Skip to content

Commit

Permalink
Fail candidate assembly for erroneous types
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gurry committed Apr 13, 2024
1 parent 59c38c0 commit 2783775
Show file tree
Hide file tree
Showing 37 changed files with 640 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ 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.

// Error type cannot possibly implement `Sized` (fixes #123154)
if let ty::Error(_) = obligation.predicate.skip_binder().self_ty().kind() {
return Err(SelectionError::Unimplemented);
}

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) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 29 additions & 1 deletion tests/ui/associated-inherent-types/issue-109071.no_gate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,35 @@ LL | type Item = &[T];
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 4 previous errors
error[E0223]: ambiguous associated type
--> $DIR/issue-109071.rs:15:22
|
LL | fn T() -> Option<Self::Item> {}
| ^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: use fully-qualified syntax
|
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error[E0223]: ambiguous associated type
--> $DIR/issue-109071.rs:15:22
|
LL | fn T() -> Option<Self::Item> {}
| ^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: use fully-qualified syntax
|
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0107, E0223, E0637, E0658.
For more information about an error, try `rustc --explain E0107`.
2 changes: 2 additions & 0 deletions tests/ui/associated-inherent-types/issue-109071.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ impl<T> Windows { //~ ERROR: missing generics for struct `Windows`
impl<T> Windows<T> {
fn T() -> Option<Self::Item> {}
//~^ ERROR: ambiguous associated type
//~| ERROR: ambiguous associated type
//~| ERROR: ambiguous associated type
}

fn main() {}
30 changes: 29 additions & 1 deletion tests/ui/associated-inherent-types/issue-109071.with_gate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,35 @@ LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to 3 previous errors
error[E0223]: ambiguous associated type
--> $DIR/issue-109071.rs:15:22
|
LL | fn T() -> Option<Self::Item> {}
| ^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: use fully-qualified syntax
|
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error[E0223]: ambiguous associated type
--> $DIR/issue-109071.rs:15:22
|
LL | fn T() -> Option<Self::Item> {}
| ^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: use fully-qualified syntax
|
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0107, E0223, E0637.
For more information about an error, try `rustc --explain E0107`.
1 change: 0 additions & 1 deletion tests/ui/closures/issue-78720.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
fn server() -> impl {
//~^ ERROR at least one trait must be specified
//~| ERROR type annotations needed
().map2(|| "")
}

Expand Down
16 changes: 5 additions & 11 deletions tests/ui/closures/issue-78720.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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,
| ^
Expand All @@ -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 `()`
Expand All @@ -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
Expand All @@ -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`.
1 change: 1 addition & 0 deletions tests/ui/const-generics/const-arg-type-arg-misordered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ type Array<T, const N: usize> = [T; N];

fn foo<const N: usize>() -> Array<N, ()> {
//~^ ERROR constant provided when a type was expected
//~| ERROR constant provided when a type was expected
unimplemented!()
}

Expand Down
10 changes: 9 additions & 1 deletion tests/ui/const-generics/const-arg-type-arg-misordered.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ error[E0747]: constant provided when a type was expected
LL | fn foo<const N: usize>() -> Array<N, ()> {
| ^

error: aborting due to 1 previous error
error[E0747]: constant provided when a type was expected
--> $DIR/const-arg-type-arg-misordered.rs:3:35
|
LL | fn foo<const N: usize>() -> Array<N, ()> {
| ^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0747`.
4 changes: 4 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/issue-102768.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const _: () = {
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR `X` cannot be made into an object
};

Expand Down
66 changes: 65 additions & 1 deletion tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,71 @@ LL | type Y<'a>;
| ^ ...because it contains the generic associated type `Y`
= help: consider moving `Y` to another trait

error: aborting due to 7 previous errors
error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
--> $DIR/issue-102768.rs:9:30
|
LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/issue-102768.rs:5:10
|
LL | type Y<'a>;
| ^ --
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: add missing lifetime argument
|
LL | fn f2<'a>(arg: Box<dyn X<Y<'_, 1> = &'a ()>>) {}
| +++

error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/issue-102768.rs:9:30
|
LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
| ^--- help: remove these generics
| |
| expected 0 generic arguments
|
note: associated type defined here, with 0 generic parameters
--> $DIR/issue-102768.rs:5:10
|
LL | type Y<'a>;
| ^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
--> $DIR/issue-102768.rs:9:30
|
LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/issue-102768.rs:5:10
|
LL | type Y<'a>;
| ^ --
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: add missing lifetime argument
|
LL | fn f2<'a>(arg: Box<dyn X<Y<'_, 1> = &'a ()>>) {}
| +++

error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/issue-102768.rs:9:30
|
LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
| ^--- help: remove these generics
| |
| expected 0 generic arguments
|
note: associated type defined here, with 0 generic parameters
--> $DIR/issue-102768.rs:5:10
|
LL | type Y<'a>;
| ^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 11 previous errors

Some errors have detailed explanations: E0038, E0107.
For more information about an error, try `rustc --explain E0038`.
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
15 changes: 15 additions & 0 deletions tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ fn main() {
//~| ERROR: binding for associated type `Y` references lifetime
//~| ERROR: binding for associated type `Y` references lifetime
//~| ERROR: binding for associated type `Y` references lifetime
//~| ERROR: binding for associated type `Y` references lifetime
//~| ERROR: binding for associated type `Y` references lifetime
//~| ERROR: the trait `X` cannot be made into an object
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,23 @@ LL | type Y<'x>;
| ^ ...because it contains the generic associated type `Y`
= help: consider moving `Y` to another trait

error: aborting due to 5 previous errors
error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types
--> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:33
|
LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
| ^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types
--> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:33
|
LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
| ^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 7 previous errors

Some errors have detailed explanations: E0038, E0261, E0582.
For more information about an error, try `rustc --explain E0038`.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR at least one trait is required
//~| ERROR at least one trait is required
//~| ERROR: the trait `X` cannot be made into an object

Expand All @@ -20,6 +25,8 @@ fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR: the trait `X` cannot be made into an object

fn main() {}
Loading

0 comments on commit 2783775

Please sign in to comment.