Skip to content
/ rust Public
forked from rust-lang/rust

Commit 72fa874

Browse files
Don't ICE in coerce when autoderef fails to structurally normalize non-WF type in new solver
1 parent dee7d0e commit 72fa874

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
461461
// to the target type), since that should be the least
462462
// confusing.
463463
let Some(InferOk { value: ty, mut obligations }) = found else {
464-
let err = first_error.expect("coerce_borrowed_pointer had no error");
465-
debug!("coerce_borrowed_pointer: failed with err = {:?}", err);
466-
return Err(err);
464+
if let Some(first_error) = first_error {
465+
debug!("coerce_borrowed_pointer: failed with err = {:?}", first_error);
466+
return Err(first_error);
467+
} else {
468+
// This may happen in the new trait solver since autoderef requires
469+
// the pointee to be structurally normalizable, or else it'll just bail.
470+
// So when we have a type like `&<not well formed>`, then we get no
471+
// autoderef steps (even though there should be at least one). That means
472+
// we get no type mismatches, since the loop above just exits early.
473+
return Err(TypeError::Mismatch);
474+
}
467475
};
468476

469477
if ty == a && mt_a.mutbl.is_not() && autoderef.step_count() == 1 {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ compile-flags: -Znext-solver
2+
3+
trait Wf {
4+
type Assoc;
5+
}
6+
7+
struct S {
8+
f: &'static <() as Wf>::Assoc,
9+
//~^ ERROR the trait bound `(): Wf` is not satisfied
10+
}
11+
12+
fn main() {
13+
let x: S = todo!();
14+
let y: &() = x.f;
15+
//~^ ERROR mismatched types
16+
//~| ERROR the trait bound `(): Wf` is not satisfied
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0277]: the trait bound `(): Wf` is not satisfied
2+
--> $DIR/non-wf-in-coerce-pointers.rs:8:17
3+
|
4+
LL | f: &'static <() as Wf>::Assoc,
5+
| ^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
6+
|
7+
help: this trait has no implementations, consider adding one
8+
--> $DIR/non-wf-in-coerce-pointers.rs:3:1
9+
|
10+
LL | trait Wf {
11+
| ^^^^^^^^
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/non-wf-in-coerce-pointers.rs:14:18
15+
|
16+
LL | let y: &() = x.f;
17+
| --- ^^^ types differ
18+
| |
19+
| expected due to this
20+
|
21+
= note: expected reference `&()`
22+
found reference `&'static <() as Wf>::Assoc`
23+
24+
error[E0277]: the trait bound `(): Wf` is not satisfied
25+
--> $DIR/non-wf-in-coerce-pointers.rs:14:18
26+
|
27+
LL | let y: &() = x.f;
28+
| ^^^ the trait `Wf` is not implemented for `()`
29+
|
30+
help: this trait has no implementations, consider adding one
31+
--> $DIR/non-wf-in-coerce-pointers.rs:3:1
32+
|
33+
LL | trait Wf {
34+
| ^^^^^^^^
35+
36+
error: aborting due to 3 previous errors
37+
38+
Some errors have detailed explanations: E0277, E0308.
39+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)