Skip to content

Commit 61963fa

Browse files
committed
Avoid an ICE reachable through const eval shenanigans
1 parent 7b21c18 commit 61963fa

File tree

4 files changed

+81
-4
lines changed

4 files changed

+81
-4
lines changed

compiler/rustc_hir_typeck/src/method/confirm.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,9 +510,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
510510
.report_mismatched_types(&cause, method_self_ty, self_ty, terr)
511511
.emit();
512512
} else {
513-
error!("{self_ty} was a subtype of {method_self_ty} but now is not?");
514-
// This must already have errored elsewhere.
515-
self.dcx().has_errors().unwrap();
513+
// This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions
514+
// may run before wfcheck if the function is used in const eval.
515+
self.dcx().span_delayed_bug(
516+
cause.span(),
517+
format!("{self_ty} was a subtype of {method_self_ty} but now is not?"),
518+
);
516519
}
517520
}
518521
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//! The same as the non-ICE test, but const eval will run typeck of
2+
//! `get` before running wfcheck (as that may in itself trigger const
3+
//! eval again, and thus cause bogus cycles). This used to ICE because
4+
//! we asserted that an error had already been emitted.
5+
6+
use std::ops::Deref;
7+
8+
struct Foo(u32);
9+
impl Foo {
10+
const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
11+
//~^ ERROR: `R` cannot be used as the type of `self`
12+
//~| ERROR destructor of `R` cannot be evaluated at compile-time
13+
self.0
14+
//~^ ERROR cannot borrow here, since the borrowed element may contain interior mutability
15+
//~| ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
16+
}
17+
}
18+
19+
const FOO: () = {
20+
let foo = Foo(1);
21+
foo.get::<&Foo>();
22+
};
23+
24+
const BAR: [(); {
25+
FOO;
26+
0
27+
}] = [];
28+
29+
fn main() {}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
2+
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
3+
|
4+
LL | self.0
5+
| ^^^^
6+
|
7+
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
8+
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error[E0015]: cannot call non-const fn `<R as Deref>::deref` in constant functions
12+
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
13+
|
14+
LL | self.0
15+
| ^^^^^^
16+
|
17+
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
18+
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
19+
|
20+
LL + #![feature(const_trait_impl)]
21+
|
22+
23+
error[E0493]: destructor of `R` cannot be evaluated at compile-time
24+
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43
25+
|
26+
LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
27+
| ^^^^ the destructor for this type cannot be evaluated in constant functions
28+
...
29+
LL | }
30+
| - value is dropped here
31+
32+
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
33+
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:49
34+
|
35+
LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
36+
| ^
37+
|
38+
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
39+
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
40+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
41+
= 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`)
42+
43+
error: aborting due to 4 previous errors
44+
45+
Some errors have detailed explanations: E0015, E0493, E0658.
46+
For more information about an error, try `rustc --explain E0015`.

tests/ui/self/arbitrary-self-from-method-substs.default.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ LL | fn get<R: Deref<Target = Self>>(self: R) -> u32 {
99
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010
= 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`)
1111

12-
ERROR rustc_hir_typeck::method::confirm Foo was a subtype of &Foo but now is not?
1312
error: aborting due to 1 previous error
1413

1514
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)