Skip to content

Commit 4ee780a

Browse files
committed
Fail candidate assembly for erroneous types
Trait predicates for types which have errors may still evaluate to OK leading to downstream ICEs. Now we return a selection error for such types in candidate assembly and thereby prevent such issues
1 parent 59c38c0 commit 4ee780a

11 files changed

+72
-25
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
984984
// Already reported in the query.
985985
SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar)) |
986986
// Already reported.
987-
Overflow(OverflowError::Error(guar)) => return guar,
987+
Overflow(OverflowError::Error(guar)) => {
988+
self.set_tainted_by_errors(guar);
989+
return guar
990+
},
988991

989992
Overflow(_) => {
990993
bug!("overflow should be handled before the `report_selection_error` path");

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+8
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
8787
} else if lang_items.sized_trait() == Some(def_id) {
8888
// Sized is never implementable by end-users, it is
8989
// always automatically computed.
90+
91+
// FIXME: Consider moving this check to the top level as it
92+
// may also be useful for predicates other than `Sized`
93+
// Error type cannot possibly implement `Sized` (fixes #123154)
94+
if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() {
95+
return Err(SelectionError::Overflow(e.into()));
96+
}
97+
9098
let sized_conditions = self.sized_conditions(obligation);
9199
self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
92100
} else if lang_items.unsize_trait() == Some(def_id) {

compiler/rustc_ty_utils/src/ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ fn adt_sized_constraint<'tcx>(
9191
let tail_ty = tcx.type_of(tail_def.did).instantiate_identity();
9292

9393
let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?;
94-
if constraint_ty.references_error() {
95-
return None;
94+
if let Err(guar) = constraint_ty.error_reported() {
95+
return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar)));
9696
}
9797

9898
// perf hack: if there is a `constraint_ty: Sized` bound, then we know

tests/ui/closures/issue-78720.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
fn server() -> impl {
22
//~^ ERROR at least one trait must be specified
3-
//~| ERROR type annotations needed
43
().map2(|| "")
54
}
65

tests/ui/closures/issue-78720.stderr

+5-11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | fn server() -> impl {
55
| ^^^^
66

77
error[E0412]: cannot find type `F` in this scope
8-
--> $DIR/issue-78720.rs:14:12
8+
--> $DIR/issue-78720.rs:13:12
99
|
1010
LL | _func: F,
1111
| ^
@@ -22,14 +22,8 @@ help: you might be missing a type parameter
2222
LL | struct Map2<Segment2, F> {
2323
| +++
2424

25-
error[E0282]: type annotations needed
26-
--> $DIR/issue-78720.rs:1:16
27-
|
28-
LL | fn server() -> impl {
29-
| ^^^^ cannot infer type
30-
3125
error[E0308]: mismatched types
32-
--> $DIR/issue-78720.rs:8:39
26+
--> $DIR/issue-78720.rs:7:39
3327
|
3428
LL | fn map2<F>(self, f: F) -> Map2<F> {}
3529
| ^^ expected `Map2<F>`, found `()`
@@ -38,7 +32,7 @@ LL | fn map2<F>(self, f: F) -> Map2<F> {}
3832
found unit type `()`
3933

4034
error[E0277]: the size for values of type `Self` cannot be known at compilation time
41-
--> $DIR/issue-78720.rs:8:16
35+
--> $DIR/issue-78720.rs:7:16
4236
|
4337
LL | fn map2<F>(self, f: F) -> Map2<F> {}
4438
| ^^^^ doesn't have a size known at compile-time
@@ -53,7 +47,7 @@ help: function arguments must have a statically known size, borrowed types alway
5347
LL | fn map2<F>(&self, f: F) -> Map2<F> {}
5448
| +
5549

56-
error: aborting due to 5 previous errors
50+
error: aborting due to 4 previous errors
5751

58-
Some errors have detailed explanations: E0277, E0282, E0308, E0412.
52+
Some errors have detailed explanations: E0277, E0308, E0412.
5953
For more information about an error, try `rustc --explain E0277`.

tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ impl Opcode2 {
1313
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
1414
move |i| match msg_type {
1515
Opcode2::OP2 => unimplemented!(),
16-
//~^ ERROR could not evaluate constant pattern
1716
}
1817
}
1918

tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr

+1-7
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,7 @@ help: you might be missing a type parameter
1717
LL | pub struct Opcode2<S>(&'a S);
1818
| +++
1919

20-
error: could not evaluate constant pattern
21-
--> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9
22-
|
23-
LL | Opcode2::OP2 => unimplemented!(),
24-
| ^^^^^^^^^^^^
25-
26-
error: aborting due to 3 previous errors
20+
error: aborting due to 2 previous errors
2721

2822
Some errors have detailed explanations: E0261, E0412.
2923
For more information about an error, try `rustc --explain E0261`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Regression test for #123154
2+
3+
struct AA {
4+
pub data: [&usize]
5+
//~^ ERROR missing lifetime specifier
6+
}
7+
8+
impl AA {
9+
const fn new() -> Self { }
10+
//~^ ERROR mismatched types
11+
}
12+
13+
static ST: AA = AA::new();
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/ice-unsized-struct-const-eval-123154.rs:4:16
3+
|
4+
LL | pub data: [&usize]
5+
| ^ expected named lifetime parameter
6+
|
7+
help: consider introducing a named lifetime parameter
8+
|
9+
LL ~ struct AA<'a> {
10+
LL ~ pub data: [&'a usize]
11+
|
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/ice-unsized-struct-const-eval-123154.rs:9:23
15+
|
16+
LL | const fn new() -> Self { }
17+
| --- ^^^^ expected `AA`, found `()`
18+
| |
19+
| implicitly returns `()` as its body has no tail or `return` expression
20+
21+
error: aborting due to 2 previous errors
22+
23+
Some errors have detailed explanations: E0106, E0308.
24+
For more information about an error, try `rustc --explain E0106`.

tests/ui/specialization/issue-68830-spurious-diagnostics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ impl<T, D> MyTrait<T> for D {
1717
}
1818

1919
impl<T> MyTrait<T> for BadStruct {
20+
//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
2021
fn foo() {}
2122
}
2223

tests/ui/specialization/issue-68830-spurious-diagnostics.stderr

+12-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ error[E0412]: cannot find type `MissingType` in this scope
44
LL | err: MissingType
55
| ^^^^^^^^^^^ not found in this scope
66

7-
error: aborting due to 1 previous error
7+
error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
8+
--> $DIR/issue-68830-spurious-diagnostics.rs:19:1
9+
|
10+
LL | impl<T, D> MyTrait<T> for D {
11+
| --------------------------- first implementation here
12+
...
13+
LL | impl<T> MyTrait<T> for BadStruct {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct`
15+
16+
error: aborting due to 2 previous errors
817

9-
For more information about this error, try `rustc --explain E0412`.
18+
Some errors have detailed explanations: E0119, E0412.
19+
For more information about an error, try `rustc --explain E0119`.

0 commit comments

Comments
 (0)