Avoid an ICE reachable through const eval shenanigans

This commit is contained in:
Oli Scherer 2024-07-01 10:14:42 +00:00
parent 7b21c18fe4
commit 61963fabdf
4 changed files with 81 additions and 4 deletions

View File

@ -510,9 +510,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
.report_mismatched_types(&cause, method_self_ty, self_ty, terr)
.emit();
} else {
error!("{self_ty} was a subtype of {method_self_ty} but now is not?");
// This must already have errored elsewhere.
self.dcx().has_errors().unwrap();
// This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions
// may run before wfcheck if the function is used in const eval.
self.dcx().span_delayed_bug(
cause.span(),
format!("{self_ty} was a subtype of {method_self_ty} but now is not?"),
);
}
}
}

View File

@ -0,0 +1,29 @@
//! The same as the non-ICE test, but const eval will run typeck of
//! `get` before running wfcheck (as that may in itself trigger const
//! eval again, and thus cause bogus cycles). This used to ICE because
//! we asserted that an error had already been emitted.
use std::ops::Deref;
struct Foo(u32);
impl Foo {
const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
//~^ ERROR: `R` cannot be used as the type of `self`
//~| ERROR destructor of `R` cannot be evaluated at compile-time
self.0
//~^ ERROR cannot borrow here, since the borrowed element may contain interior mutability
//~| ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
}
}
const FOO: () = {
let foo = Foo(1);
foo.get::<&Foo>();
};
const BAR: [(); {
FOO;
0
}] = [];
fn main() {}

View File

@ -0,0 +1,46 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
|
LL | self.0
| ^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` 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[E0015]: cannot call non-const fn `<R as Deref>::deref` in constant functions
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
|
LL | self.0
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|
error[E0493]: destructor of `R` cannot be evaluated at compile-time
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43
|
LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
| ^^^^ the destructor for this type cannot be evaluated in constant functions
...
LL | }
| - value is dropped here
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:49
|
LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
| ^
|
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
= help: add `#![feature(arbitrary_self_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
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0015, E0493, E0658.
For more information about an error, try `rustc --explain E0015`.

View File

@ -9,7 +9,6 @@ LL | fn get<R: Deref<Target = Self>>(self: R) -> u32 {
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
ERROR rustc_hir_typeck::method::confirm Foo was a subtype of &Foo but now is not?
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.