From ab126c2a4e6b6835073949da4ab913d85989db09 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Aug 2023 00:48:09 +0000 Subject: [PATCH] Probe when assembling upcast candidates so they don't step on eachother's toes --- .../src/solve/trait_goals.rs | 22 ++++++++++--------- ...rr => type-checking-test-1.current.stderr} | 4 ++-- .../type-checking-test-1.next.stderr | 9 ++++++++ .../trait-upcasting/type-checking-test-1.rs | 5 ++++- 4 files changed, 27 insertions(+), 13 deletions(-) rename tests/ui/traits/trait-upcasting/{type-checking-test-1.stderr => type-checking-test-1.current.stderr} (89%) create mode 100644 tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index ee6f1686b8238..8bab20e19421d 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -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 })); } diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr similarity index 89% rename from tests/ui/traits/trait-upcasting/type-checking-test-1.stderr rename to tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr index 82b4e9bd72aec..d48d9b89d1dac 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr @@ -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 @@ -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` diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr new file mode 100644 index 0000000000000..b612005fcb051 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr @@ -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`. diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs index 6bc9f4a75d333..7c7beec0809d7 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs @@ -1,3 +1,6 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + #![feature(trait_upcasting)] trait Foo: Bar + Bar {} @@ -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) {