Skip to content

Commit

Permalink
Rollup merge of rust-lang#134746 - compiler-errors:autoderef-norm-non…
Browse files Browse the repository at this point in the history
…-wf-coerce-ice, r=lcnr

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

r? lcnr
  • Loading branch information
matthiaskrgr authored Jan 22, 2025
2 parents b76da20 + 72fa874 commit b09d73a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
14 changes: 11 additions & 3 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// 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 {
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/traits/next-solver/non-wf-in-coerce-pointers.rs
Original file line number Diff line number Diff line change
@@ -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
}
39 changes: 39 additions & 0 deletions tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit b09d73a

Please sign in to comment.