Avoid an ICE reachable through const eval shenanigans
This commit is contained in:
parent
7b21c18fe4
commit
61963fabdf
4 changed files with 81 additions and 4 deletions
|
@ -510,9 +510,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
.report_mismatched_types(&cause, method_self_ty, self_ty, terr)
|
.report_mismatched_types(&cause, method_self_ty, self_ty, terr)
|
||||||
.emit();
|
.emit();
|
||||||
} else {
|
} else {
|
||||||
error!("{self_ty} was a subtype of {method_self_ty} but now is not?");
|
// This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions
|
||||||
// This must already have errored elsewhere.
|
// may run before wfcheck if the function is used in const eval.
|
||||||
self.dcx().has_errors().unwrap();
|
self.dcx().span_delayed_bug(
|
||||||
|
cause.span(),
|
||||||
|
format!("{self_ty} was a subtype of {method_self_ty} but now is not?"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
29
tests/ui/self/arbitrary-self-from-method-substs-ice.rs
Normal file
29
tests/ui/self/arbitrary-self-from-method-substs-ice.rs
Normal 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() {}
|
46
tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
Normal file
46
tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
Normal 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`.
|
|
@ -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
|
= 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`)
|
= 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
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue