Don't ICE in coerce when autoderef fails to structurally normalize non-WF type in new solver

This commit is contained in:
Michael Goulet
2024-12-25 03:10:54 +00:00
parent dee7d0e730
commit 72fa874456
3 changed files with 67 additions and 3 deletions
+11 -3
View File
@@ -461,9 +461,17 @@ fn coerce_borrowed_pointer(
// to the target type), since that should be the least
// confusing.
let Some(InferOk { value: ty, mut obligations }) = found else {
let err = first_error.expect("coerce_borrowed_pointer had no error");
debug!("coerce_borrowed_pointer: failed with err = {:?}", err);
return Err(err);
if let Some(first_error) = first_error {
debug!("coerce_borrowed_pointer: failed with err = {:?}", first_error);
return Err(first_error);
} else {
// This may happen in the new trait solver since autoderef requires
// the pointee to be structurally normalizable, or else it'll just bail.
// So when we have a type like `&<not well formed>`, then we get no
// autoderef steps (even though there should be at least one). That means
// we get no type mismatches, since the loop above just exits early.
return Err(TypeError::Mismatch);
}
};
if ty == a && mt_a.mutbl.is_not() && autoderef.step_count() == 1 {
@@ -0,0 +1,17 @@
//@ compile-flags: -Znext-solver
trait Wf {
type Assoc;
}
struct S {
f: &'static <() as Wf>::Assoc,
//~^ ERROR the trait bound `(): Wf` is not satisfied
}
fn main() {
let x: S = todo!();
let y: &() = x.f;
//~^ ERROR mismatched types
//~| ERROR the trait bound `(): Wf` is not satisfied
}
@@ -0,0 +1,39 @@
error[E0277]: the trait bound `(): Wf` is not satisfied
--> $DIR/non-wf-in-coerce-pointers.rs:8:17
|
LL | f: &'static <() as Wf>::Assoc,
| ^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
|
help: this trait has no implementations, consider adding one
--> $DIR/non-wf-in-coerce-pointers.rs:3:1
|
LL | trait Wf {
| ^^^^^^^^
error[E0308]: mismatched types
--> $DIR/non-wf-in-coerce-pointers.rs:14:18
|
LL | let y: &() = x.f;
| --- ^^^ types differ
| |
| expected due to this
|
= note: expected reference `&()`
found reference `&'static <() as Wf>::Assoc`
error[E0277]: the trait bound `(): Wf` is not satisfied
--> $DIR/non-wf-in-coerce-pointers.rs:14:18
|
LL | let y: &() = x.f;
| ^^^ the trait `Wf` is not implemented for `()`
|
help: this trait has no implementations, consider adding one
--> $DIR/non-wf-in-coerce-pointers.rs:3:1
|
LL | trait Wf {
| ^^^^^^^^
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.