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

compiler/rustc_middle/src/ty/diagnostics.rs

Lines changed: 54 additions & 10 deletions
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

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

Lines changed: 1 addition & 0 deletions
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

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

Lines changed: 4 additions & 2 deletions
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

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

Lines changed: 1 addition & 3 deletions
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 `(_, _)`

src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr

Lines changed: 2 additions & 6 deletions
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 `(_,)`

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

Lines changed: 0 additions & 2 deletions
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
|

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

Lines changed: 0 additions & 2 deletions
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
|

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

Lines changed: 0 additions & 6 deletions
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
| |

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

Lines changed: 0 additions & 2 deletions
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
|

src/test/ui/issues/issue-11844.stderr

Lines changed: 0 additions & 2 deletions
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
|

0 commit comments

Comments
 (0)