Skip to content

Commit

Permalink
Probe when assembling upcast candidates so they don't step on eachoth…
Browse files Browse the repository at this point in the history
…er's toes
  • Loading branch information
compiler-errors committed Aug 15, 2023
1 parent 1b198b3 commit ab126c2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
22 changes: 12 additions & 10 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,16 +552,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
self.walk_vtable(
a_principal.with_self_ty(tcx, a_ty),
|ecx, new_a_principal, _, vtable_vptr_slot| {
if let Ok(resp) = ecx.consider_builtin_upcast_to_principal(
goal,
a_data,
a_region,
b_data,
b_region,
Some(new_a_principal.map_bound(|trait_ref| {
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
})),
) {
if let Ok(resp) = ecx.probe_candidate("dyn upcast").enter(|ecx| {
ecx.consider_builtin_upcast_to_principal(
goal,
a_data,
a_region,
b_data,
b_region,
Some(new_a_principal.map_bound(|trait_ref| {
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
})),
)
}) {
responses
.push((resp, BuiltinImplSource::TraitUpcasting { vtable_vptr_slot }));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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
| ^^^^^^^^^^^^^^^^ invalid cast
Expand All @@ -10,7 +10,7 @@ LL | let _ = &x as &dyn Bar<_>; // Ambiguous
| +

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
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
Expand Down
Original file line number Diff line number Diff line change
@@ -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`.
5 changes: 4 additions & 1 deletion tests/ui/traits/trait-upcasting/type-checking-test-1.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next

#![feature(trait_upcasting)]

trait Foo: Bar<i32> + Bar<u32> {}
Expand All @@ -15,7 +18,7 @@ fn test_specific(x: &dyn Foo) {
fn test_unknown_version(x: &dyn Foo) {
let _ = x as &dyn Bar<_>; // Ambiguous
//~^ 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) {
Expand Down

0 comments on commit ab126c2

Please sign in to comment.