Skip to content

Commit b507174

Browse files
authored
Rollup merge of #91898 - compiler-errors:dont_suggest_closure_return_type, r=lcnr
Make `TyS::is_suggestable` check for non-suggestable types structually Not sure if I went overboard checking substs in dyn types, etc. Let me know if I should simplify this function. Fixes #91832
2 parents 700670f + f29fb47 commit b507174

30 files changed

+112
-99
lines changed

Diff for: compiler/rustc_middle/src/ty/diagnostics.rs

+54-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
//! Diagnostics related methods for `TyS`.
22
3+
use crate::ty::subst::{GenericArg, GenericArgKind};
34
use crate::ty::TyKind::*;
4-
use crate::ty::{InferTy, TyCtxt, TyS};
5+
use crate::ty::{
6+
ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy,
7+
ProjectionTy, TyCtxt, TyS, TypeAndMut,
8+
};
9+
510
use rustc_errors::{Applicability, DiagnosticBuilder};
611
use rustc_hir as hir;
712
use rustc_hir::def_id::DefId;
@@ -63,16 +68,55 @@ impl<'tcx> TyS<'tcx> {
6368

6469
/// Whether the type can be safely suggested during error recovery.
6570
pub fn is_suggestable(&self) -> bool {
66-
!matches!(
67-
self.kind(),
71+
fn generic_arg_is_suggestible(arg: GenericArg<'_>) -> bool {
72+
match arg.unpack() {
73+
GenericArgKind::Type(ty) => ty.is_suggestable(),
74+
GenericArgKind::Const(c) => const_is_suggestable(c.val),
75+
_ => true,
76+
}
77+
}
78+
79+
fn const_is_suggestable(kind: ConstKind<'_>) -> bool {
80+
match kind {
81+
ConstKind::Infer(..)
82+
| ConstKind::Bound(..)
83+
| ConstKind::Placeholder(..)
84+
| ConstKind::Error(..) => false,
85+
_ => true,
86+
}
87+
}
88+
89+
// FIXME(compiler-errors): Some types are still not good to suggest,
90+
// specifically references with lifetimes within the function. Not
91+
//sure we have enough information to resolve whether a region is
92+
// temporary, so I'll leave this as a fixme.
93+
94+
match self.kind() {
6895
Opaque(..)
69-
| FnDef(..)
70-
| FnPtr(..)
71-
| Dynamic(..)
72-
| Closure(..)
73-
| Infer(..)
74-
| Projection(..)
75-
)
96+
| FnDef(..)
97+
| Closure(..)
98+
| Infer(..)
99+
| Generator(..)
100+
| GeneratorWitness(..)
101+
| Bound(_, _)
102+
| Placeholder(_)
103+
| Error(_) => false,
104+
Dynamic(dty, _) => dty.iter().all(|pred| match pred.skip_binder() {
105+
ExistentialPredicate::Trait(ExistentialTraitRef { substs, .. }) => {
106+
substs.iter().all(generic_arg_is_suggestible)
107+
}
108+
ExistentialPredicate::Projection(ExistentialProjection { substs, ty, .. }) => {
109+
ty.is_suggestable() && substs.iter().all(generic_arg_is_suggestible)
110+
}
111+
_ => true,
112+
}),
113+
Projection(ProjectionTy { substs: args, .. }) | Adt(_, args) | Tuple(args) => {
114+
args.iter().all(generic_arg_is_suggestible)
115+
}
116+
Slice(ty) | RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => ty.is_suggestable(),
117+
Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val),
118+
_ => true,
119+
}
76120
}
77121
}
78122

Diff for: src/test/ui/associated-types/defaults-in-other-trait-items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ trait Tr {
1010
//~^ ERROR mismatched types
1111
//~| NOTE expected associated type, found `()`
1212
//~| NOTE expected associated type `<Self as Tr>::A`
13+
//~| NOTE this expression has type `<Self as Tr>::A`
1314
}
1415
}
1516

Diff for: src/test/ui/associated-types/defaults-in-other-trait-items.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ LL | type A = ();
55
| ------------ associated type defaults can't be assumed inside the trait defining them
66
...
77
LL | let () = p;
8-
| ^^ expected associated type, found `()`
8+
| ^^ - this expression has type `<Self as Tr>::A`
9+
| |
10+
| expected associated type, found `()`
911
|
1012
= note: expected associated type `<Self as Tr>::A`
1113
found unit type `()`
1214

1315
error[E0308]: mismatched types
14-
--> $DIR/defaults-in-other-trait-items.rs:35:25
16+
--> $DIR/defaults-in-other-trait-items.rs:36:25
1517
|
1618
LL | type Ty = u8;
1719
| ------------- associated type defaults can't be assumed inside the trait defining them

Diff for: src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error[E0308]: mismatched types
22
--> $DIR/default-match-bindings-forbidden.rs:6:5
33
|
44
LL | (x, y) = &(1, 2);
5-
| ^^^^^^ ------- this expression has type `&({integer}, {integer})`
6-
| |
7-
| expected reference, found tuple
5+
| ^^^^^^ expected reference, found tuple
86
|
97
= note: expected type `&({integer}, {integer})`
108
found tuple `(_, _)`

Diff for: src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr

+2-6
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ error[E0308]: mismatched types
1010
--> $DIR/tuple_destructure_fail.rs:8:5
1111
|
1212
LL | (a, a, b) = (1, 2);
13-
| ^^^^^^^^^ ------ this expression has type `({integer}, {integer})`
14-
| |
15-
| expected a tuple with 2 elements, found one with 3 elements
13+
| ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
1614
|
1715
= note: expected type `({integer}, {integer})`
1816
found tuple `(_, _, _)`
@@ -29,9 +27,7 @@ error[E0308]: mismatched types
2927
--> $DIR/tuple_destructure_fail.rs:10:5
3028
|
3129
LL | (_,) = (1, 2);
32-
| ^^^^ ------ this expression has type `({integer}, {integer})`
33-
| |
34-
| expected a tuple with 2 elements, found one with 1 element
30+
| ^^^^ expected a tuple with 2 elements, found one with 1 element
3531
|
3632
= note: expected type `({integer}, {integer})`
3733
found tuple `(_,)`

Diff for: src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: mismatched types
22
--> $DIR/exclusive_range_pattern_syntax_collision.rs:6:13
33
|
4-
LL | match [5..4, 99..105, 43..44] {
5-
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
64
LL | [_, 99.., _] => {},
75
| ^^ expected struct `std::ops::Range`, found integer
86
|

Diff for: src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ LL | [_, 99..] => {},
77
error[E0308]: mismatched types
88
--> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:13
99
|
10-
LL | match [5..4, 99..105, 43..44] {
11-
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
1210
LL | [_, 99..] => {},
1311
| ^^ expected struct `std::ops::Range`, found integer
1412
|

Diff for: src/test/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr

-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: mismatched types
22
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:12
33
|
4-
LL | match [5..4, 99..105, 43..44] {
5-
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
64
LL | [..9, 99..100, _] => {},
75
| ^ expected struct `std::ops::Range`, found integer
86
|
@@ -12,8 +10,6 @@ LL | [..9, 99..100, _] => {},
1210
error[E0308]: mismatched types
1311
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:15
1412
|
15-
LL | match [5..4, 99..105, 43..44] {
16-
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
1713
LL | [..9, 99..100, _] => {},
1814
| ^^ --- this is of type `{integer}`
1915
| |
@@ -25,8 +21,6 @@ LL | [..9, 99..100, _] => {},
2521
error[E0308]: mismatched types
2622
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:19
2723
|
28-
LL | match [5..4, 99..105, 43..44] {
29-
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
3024
LL | [..9, 99..100, _] => {},
3125
| -- ^^^ expected struct `std::ops::Range`, found integer
3226
| |

Diff for: src/test/ui/half-open-range-patterns/pat-tuple-5.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: mismatched types
22
--> $DIR/pat-tuple-5.rs:8:10
33
|
4-
LL | match (0, 1) {
5-
| ------ this expression has type `({integer}, {integer})`
64
LL | (PAT ..) => {}
75
| ^^^ expected tuple, found `u8`
86
|

Diff for: src/test/ui/issues/issue-11844.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: mismatched types
22
--> $DIR/issue-11844.rs:6:9
33
|
4-
LL | match a {
5-
| - this expression has type `Option<Box<{integer}>>`
64
LL | Ok(a) =>
75
| ^^^^^ expected enum `Option`, found enum `Result`
86
|

Diff for: src/test/ui/issues/issue-12552.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: mismatched types
22
--> $DIR/issue-12552.rs:6:5
33
|
4-
LL | match t {
5-
| - this expression has type `Result<_, {integer}>`
64
LL | Some(k) => match k {
75
| ^^^^^^^ expected enum `Result`, found enum `Option`
86
|
@@ -12,9 +10,6 @@ LL | Some(k) => match k {
1210
error[E0308]: mismatched types
1311
--> $DIR/issue-12552.rs:9:5
1412
|
15-
LL | match t {
16-
| - this expression has type `Result<_, {integer}>`
17-
...
1813
LL | None => ()
1914
| ^^^^ expected enum `Result`, found enum `Option`
2015
|

Diff for: src/test/ui/issues/issue-13466.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: mismatched types
22
--> $DIR/issue-13466.rs:8:9
33
|
4-
LL | let _x: usize = match Some(1) {
5-
| ------- this expression has type `Option<{integer}>`
64
LL | Ok(u) => u,
75
| ^^^^^ expected enum `Option`, found enum `Result`
86
|
@@ -12,9 +10,6 @@ LL | Ok(u) => u,
1210
error[E0308]: mismatched types
1311
--> $DIR/issue-13466.rs:14:9
1412
|
15-
LL | let _x: usize = match Some(1) {
16-
| ------- this expression has type `Option<{integer}>`
17-
...
1813
LL | Err(e) => panic!(e)
1914
| ^^^^^^ expected enum `Option`, found enum `Result`
2015
|

Diff for: src/test/ui/issues/issue-3680.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: mismatched types
22
--> $DIR/issue-3680.rs:3:9
33
|
4-
LL | match None {
5-
| ---- this expression has type `Option<_>`
64
LL | Err(_) => ()
75
| ^^^^^^ expected enum `Option`, found enum `Result`
86
|

Diff for: src/test/ui/issues/issue-66706.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,23 @@ error[E0308]: mismatched types
3636
--> $DIR/issue-66706.rs:2:5
3737
|
3838
LL | fn a() {
39-
| - help: try adding a return type: `-> [{integer}; _]`
39+
| - possibly return type missing here?
4040
LL | [0; [|_: _ &_| ()].len()]
4141
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
4242

4343
error[E0308]: mismatched types
4444
--> $DIR/issue-66706.rs:14:5
4545
|
4646
LL | fn c() {
47-
| - help: try adding a return type: `-> [{integer}; _]`
47+
| - possibly return type missing here?
4848
LL | [0; [|&_: _ &_| {}; 0 ].len()]
4949
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
5050

5151
error[E0308]: mismatched types
5252
--> $DIR/issue-66706.rs:20:5
5353
|
5454
LL | fn d() {
55-
| - help: try adding a return type: `-> [{integer}; _]`
55+
| - possibly return type missing here?
5656
LL | [0; match [|f @ &ref _| () ] {} ]
5757
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
5858

Diff for: src/test/ui/issues/issue-72574-1.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ LL | (_a, _x @ ..) => {}
2121
error[E0308]: mismatched types
2222
--> $DIR/issue-72574-1.rs:4:9
2323
|
24-
LL | match x {
25-
| - this expression has type `({integer}, {integer}, {integer})`
2624
LL | (_a, _x @ ..) => {}
2725
| ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
2826
|

Diff for: src/test/ui/mismatched_types/E0409.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ LL | (0, ref y) | (y, 0) => {}
99
error[E0308]: mismatched types
1010
--> $DIR/E0409.rs:5:23
1111
|
12-
LL | match x {
13-
| - this expression has type `({integer}, {integer})`
1412
LL | (0, ref y) | (y, 0) => {}
1513
| ----- ^ expected `&{integer}`, found integer
1614
| |

Diff for: src/test/ui/mut/mut-pattern-mismatched.stderr

-6
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ error[E0308]: mismatched types
33
|
44
LL | let &_
55
| ^^ types differ in mutability
6-
...
7-
LL | = foo;
8-
| --- this expression has type `&mut {integer}`
96
|
107
= note: expected mutable reference `&mut {integer}`
118
found reference `&_`
@@ -15,9 +12,6 @@ error[E0308]: mismatched types
1512
|
1613
LL | let &mut _
1714
| ^^^^^^ types differ in mutability
18-
...
19-
LL | = bar;
20-
| --- this expression has type `&{integer}`
2115
|
2216
= note: expected reference `&{integer}`
2317
found mutable reference `&mut _`

Diff for: src/test/ui/never_type/diverging-tuple-parts-39485.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
error[E0308]: mismatched types
22
--> $DIR/diverging-tuple-parts-39485.rs:8:5
33
|
4+
LL | fn g() {
5+
| - possibly return type missing here?
46
LL | &panic!()
57
| ^^^^^^^^^ expected `()`, found reference
68
|
79
= note: expected unit type `()`
810
found reference `&_`
9-
help: try adding a return type
10-
|
11-
LL | fn g() -> &_ {
12-
| +++++
1311
help: consider removing the borrow
1412
|
1513
LL - &panic!()

Diff for: src/test/ui/or-patterns/already-bound-name.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,8 @@ error[E0308]: mismatched types
8686
--> $DIR/already-bound-name.rs:30:32
8787
|
8888
LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
89-
| - ^ ------- this expression has type `E<E<{integer}>>`
90-
| | |
91-
| | expected integer, found enum `E`
89+
| - ^ expected integer, found enum `E`
90+
| |
9291
| first introduced with type `{integer}` here
9392
|
9493
= note: expected type `{integer}`

Diff for: src/test/ui/or-patterns/inconsistent-modes.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ error[E0308]: mismatched types
6565
--> $DIR/inconsistent-modes.rs:13:32
6666
|
6767
LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
68-
| ----- ^^^^^^^^^ ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>`
69-
| | |
70-
| | types differ in mutability
68+
| ----- ^^^^^^^^^ types differ in mutability
69+
| |
7170
| first introduced with type `&{integer}` here
7271
|
7372
= note: expected type `&{integer}`

Diff for: src/test/ui/pattern/issue-74702.stderr

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ error[E0308]: mismatched types
2222
--> $DIR/issue-74702.rs:2:9
2323
|
2424
LL | let (foo @ ..,) = (0, 0);
25-
| ^^^^^^^^^^^ ------ this expression has type `({integer}, {integer})`
26-
| |
27-
| expected a tuple with 2 elements, found one with 1 element
25+
| ^^^^^^^^^^^ expected a tuple with 2 elements, found one with 1 element
2826
|
2927
= note: expected tuple `({integer}, {integer})`
3028
found tuple `(_,)`

Diff for: src/test/ui/pattern/pat-tuple-overfield.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ LL | E1::Z0 => {}
150150
error[E0308]: mismatched types
151151
--> $DIR/pat-tuple-overfield.rs:19:9
152152
|
153-
LL | match (1, 2, 3) {
154-
| --------- this expression has type `({integer}, {integer}, {integer})`
155153
LL | (1, 2, 3, 4) => {}
156154
| ^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements
157155
|
@@ -161,9 +159,6 @@ LL | (1, 2, 3, 4) => {}
161159
error[E0308]: mismatched types
162160
--> $DIR/pat-tuple-overfield.rs:20:9
163161
|
164-
LL | match (1, 2, 3) {
165-
| --------- this expression has type `({integer}, {integer}, {integer})`
166-
LL | (1, 2, 3, 4) => {}
167162
LL | (1, 2, .., 3, 4) => {}
168163
| ^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 4 elements
169164
|

0 commit comments

Comments
 (0)