From 4ee780ab3aa0322a3a3f395039c8847099eb6077 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Mon, 15 Apr 2024 13:22:27 +0530 Subject: [PATCH] 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 --- .../error_reporting/type_err_ctxt_ext.rs | 5 +++- .../src/traits/select/candidate_assembly.rs | 8 +++++++ compiler/rustc_ty_utils/src/ty.rs | 4 ++-- tests/ui/closures/issue-78720.rs | 1 - tests/ui/closures/issue-78720.stderr | 16 ++++--------- .../ice-type-mismatch-when-copying-112824.rs | 1 - ...e-type-mismatch-when-copying-112824.stderr | 8 +------ .../ice-unsized-struct-const-eval-123154.rs | 15 ++++++++++++ ...ce-unsized-struct-const-eval-123154.stderr | 24 +++++++++++++++++++ .../issue-68830-spurious-diagnostics.rs | 1 + .../issue-68830-spurious-diagnostics.stderr | 14 +++++++++-- 11 files changed, 72 insertions(+), 25 deletions(-) create mode 100644 tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs create mode 100644 tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 1b8b09ddda142..0174cebc576af 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -984,7 +984,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Already reported in the query. SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar)) | // Already reported. - Overflow(OverflowError::Error(guar)) => return guar, + Overflow(OverflowError::Error(guar)) => { + self.set_tainted_by_errors(guar); + return guar + }, Overflow(_) => { bug!("overflow should be handled before the `report_selection_error` path"); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 974e5ef0e166a..3ef7cc01f9021 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -87,6 +87,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if lang_items.sized_trait() == Some(def_id) { // Sized is never implementable by end-users, it is // always automatically computed. + + // FIXME: Consider moving this check to the top level as it + // may also be useful for predicates other than `Sized` + // Error type cannot possibly implement `Sized` (fixes #123154) + if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() { + return Err(SelectionError::Overflow(e.into())); + } + let sized_conditions = self.sized_conditions(obligation); self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); } else if lang_items.unsize_trait() == Some(def_id) { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index f33234122c9d3..2139b8c665bf4 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -91,8 +91,8 @@ fn adt_sized_constraint<'tcx>( let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; - if constraint_ty.references_error() { - return None; + if let Err(guar) = constraint_ty.error_reported() { + return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); } // perf hack: if there is a `constraint_ty: Sized` bound, then we know diff --git a/tests/ui/closures/issue-78720.rs b/tests/ui/closures/issue-78720.rs index 0c4f337ba57b8..81af030fe5568 100644 --- a/tests/ui/closures/issue-78720.rs +++ b/tests/ui/closures/issue-78720.rs @@ -1,6 +1,5 @@ fn server() -> impl { //~^ ERROR at least one trait must be specified - //~| ERROR type annotations needed ().map2(|| "") } diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr index 2f57c7616f121..5d65c87b0fd61 100644 --- a/tests/ui/closures/issue-78720.stderr +++ b/tests/ui/closures/issue-78720.stderr @@ -5,7 +5,7 @@ LL | fn server() -> impl { | ^^^^ error[E0412]: cannot find type `F` in this scope - --> $DIR/issue-78720.rs:14:12 + --> $DIR/issue-78720.rs:13:12 | LL | _func: F, | ^ @@ -22,14 +22,8 @@ help: you might be missing a type parameter LL | struct Map2 { | +++ -error[E0282]: type annotations needed - --> $DIR/issue-78720.rs:1:16 - | -LL | fn server() -> impl { - | ^^^^ cannot infer type - error[E0308]: mismatched types - --> $DIR/issue-78720.rs:8:39 + --> $DIR/issue-78720.rs:7:39 | LL | fn map2(self, f: F) -> Map2 {} | ^^ expected `Map2`, found `()` @@ -38,7 +32,7 @@ LL | fn map2(self, f: F) -> Map2 {} found unit type `()` error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-78720.rs:8:16 + --> $DIR/issue-78720.rs:7:16 | LL | fn map2(self, f: F) -> Map2 {} | ^^^^ 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 LL | fn map2(&self, f: F) -> Map2 {} | + -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0282, E0308, E0412. +Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs index dc9782295c136..a41a159c1fd7c 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs @@ -13,7 +13,6 @@ impl Opcode2 { pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) { move |i| match msg_type { Opcode2::OP2 => unimplemented!(), - //~^ ERROR could not evaluate constant pattern } } diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr index 9442eac0cf54a..d95a8861230e0 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr @@ -17,13 +17,7 @@ help: you might be missing a type parameter LL | pub struct Opcode2(&'a S); | +++ -error: could not evaluate constant pattern - --> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9 - | -LL | Opcode2::OP2 => unimplemented!(), - | ^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0261, E0412. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs new file mode 100644 index 0000000000000..24a2cd19b187f --- /dev/null +++ b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs @@ -0,0 +1,15 @@ +// Regression test for #123154 + +struct AA { + pub data: [&usize] + //~^ ERROR missing lifetime specifier +} + +impl AA { + const fn new() -> Self { } + //~^ ERROR mismatched types +} + +static ST: AA = AA::new(); + +fn main() {} diff --git a/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr new file mode 100644 index 0000000000000..9657e5cdda15d --- /dev/null +++ b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr @@ -0,0 +1,24 @@ +error[E0106]: missing lifetime specifier + --> $DIR/ice-unsized-struct-const-eval-123154.rs:4:16 + | +LL | pub data: [&usize] + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL ~ struct AA<'a> { +LL ~ pub data: [&'a usize] + | + +error[E0308]: mismatched types + --> $DIR/ice-unsized-struct-const-eval-123154.rs:9:23 + | +LL | const fn new() -> Self { } + | --- ^^^^ expected `AA`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0308. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs index d11ec79833217..a7487b8aecb9c 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs @@ -17,6 +17,7 @@ impl MyTrait for D { } impl MyTrait for BadStruct { +//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` fn foo() {} } diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr index 0ecec03a023eb..13f6ae0805dad 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr @@ -4,6 +4,16 @@ error[E0412]: cannot find type `MissingType` in this scope LL | err: MissingType | ^^^^^^^^^^^ not found in this scope -error: aborting due to 1 previous error +error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` + --> $DIR/issue-68830-spurious-diagnostics.rs:19:1 + | +LL | impl MyTrait for D { + | --------------------------- first implementation here +... +LL | impl MyTrait for BadStruct { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0119, E0412. +For more information about an error, try `rustc --explain E0119`.