Probe when assembling upcast candidates so they don't step on eachother's toes
This commit is contained in:
parent
1b198b3a19
commit
ab126c2a4e
@ -552,16 +552,18 @@ fn consider_builtin_dyn_upcast_candidates(
|
|||||||
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 }));
|
||||||
}
|
}
|
||||||
|
@ -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`
|
@ -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`.
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user