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
This commit is contained in:
parent
63f70b3d10
commit
c30e15aded
@ -984,7 +984,10 @@ fn report_selection_error(
|
||||
// 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");
|
||||
|
@ -87,6 +87,14 @@ pub(super) fn assemble_candidates<'o>(
|
||||
} 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) {
|
||||
|
@ -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
|
||||
|
@ -1,12 +0,0 @@
|
||||
//@ known-bug: #123154
|
||||
struct AA {
|
||||
pub data: [&usize]
|
||||
}
|
||||
|
||||
impl AA {
|
||||
const fn new() -> Self { }
|
||||
}
|
||||
|
||||
static AA = AA::new();
|
||||
|
||||
fn main() { }
|
@ -1,6 +1,5 @@
|
||||
fn server() -> impl {
|
||||
//~^ ERROR at least one trait must be specified
|
||||
//~| ERROR type annotations needed
|
||||
().map2(|| "")
|
||||
}
|
||||
|
||||
|
@ -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<Segment2, F> {
|
||||
| +++
|
||||
|
||||
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<F>(self, f: F) -> Map2<F> {}
|
||||
| ^^ expected `Map2<F>`, found `()`
|
||||
@ -38,7 +32,7 @@ LL | fn map2<F>(self, f: F) -> Map2<F> {}
|
||||
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<F>(self, f: F) -> Map2<F> {}
|
||||
| ^^^^ 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<F>(&self, f: F) -> Map2<F> {}
|
||||
| +
|
||||
|
||||
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`.
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,7 @@ help: you might be missing a type parameter
|
||||
LL | pub struct Opcode2<S>(&'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`.
|
||||
|
@ -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() {}
|
@ -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`.
|
@ -17,6 +17,7 @@ impl<T, D> MyTrait<T> for D {
|
||||
}
|
||||
|
||||
impl<T> MyTrait<T> for BadStruct {
|
||||
//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
|
||||
fn foo() {}
|
||||
}
|
||||
|
||||
|
@ -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<T, D> MyTrait<T> for D {
|
||||
| --------------------------- first implementation here
|
||||
...
|
||||
LL | impl<T> MyTrait<T> for BadStruct {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct`
|
||||
|
||||
For more information about this error, try `rustc --explain E0412`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0119, E0412.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
|
Loading…
Reference in New Issue
Block a user