Probe when assembling upcast candidates so they don't step on eachother's toes

This commit is contained in:
Michael Goulet 2023-08-15 00:48:09 +00:00
parent 1b198b3a19
commit ab126c2a4e
4 changed files with 27 additions and 13 deletions

View File

@ -552,16 +552,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
self.walk_vtable( self.walk_vtable(
a_principal.with_self_ty(tcx, a_ty), a_principal.with_self_ty(tcx, a_ty),
|ecx, new_a_principal, _, vtable_vptr_slot| { |ecx, new_a_principal, _, vtable_vptr_slot| {
if let Ok(resp) = ecx.consider_builtin_upcast_to_principal( if let Ok(resp) = ecx.probe_candidate("dyn upcast").enter(|ecx| {
goal, ecx.consider_builtin_upcast_to_principal(
a_data, goal,
a_region, a_data,
b_data, a_region,
b_region, b_data,
Some(new_a_principal.map_bound(|trait_ref| { b_region,
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) Some(new_a_principal.map_bound(|trait_ref| {
})), ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
) { })),
)
}) {
responses responses
.push((resp, BuiltinImplSource::TraitUpcasting { vtable_vptr_slot })); .push((resp, BuiltinImplSource::TraitUpcasting { vtable_vptr_slot }));
} }

View File

@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
--> $DIR/type-checking-test-1.rs:16:13 --> $DIR/type-checking-test-1.rs:19:13
| |
LL | let _ = x as &dyn Bar<_>; // Ambiguous LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ invalid cast | ^^^^^^^^^^^^^^^^ invalid cast
@ -10,7 +10,7 @@ LL | let _ = &x as &dyn Bar<_>; // Ambiguous
| + | +
error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
--> $DIR/type-checking-test-1.rs:16:13 --> $DIR/type-checking-test-1.rs:19:13
| |
LL | let _ = x as &dyn Bar<_>; // Ambiguous LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo` | ^ the trait `Bar<_>` is not implemented for `&dyn Foo`

View File

@ -0,0 +1,9 @@
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
--> $DIR/type-checking-test-1.rs:19:13
|
LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
error: aborting due to previous error
For more information about this error, try `rustc --explain E0605`.

View File

@ -1,3 +1,6 @@
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
#![feature(trait_upcasting)] #![feature(trait_upcasting)]
trait Foo: Bar<i32> + Bar<u32> {} trait Foo: Bar<i32> + Bar<u32> {}
@ -15,7 +18,7 @@ fn test_specific(x: &dyn Foo) {
fn test_unknown_version(x: &dyn Foo) { fn test_unknown_version(x: &dyn Foo) {
let _ = x as &dyn Bar<_>; // Ambiguous let _ = x as &dyn Bar<_>; // Ambiguous
//~^ ERROR non-primitive cast //~^ ERROR non-primitive cast
//~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied //[current]~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied
} }
fn test_infer_version(x: &dyn Foo) { fn test_infer_version(x: &dyn Foo) {