Skip to content

Commit

Permalink
Check allow instantiating object trait binder when upcasting and in n…
Browse files Browse the repository at this point in the history
…ew solver
  • Loading branch information
compiler-errors committed Sep 27, 2024
1 parent 58420a0 commit d4ee408
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 50 deletions.
6 changes: 3 additions & 3 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ where
&& ecx
.probe(|_| ProbeKind::UpcastProjectionCompatibility)
.enter(|ecx| -> Result<(), NoSolution> {
ecx.eq(param_env, source_projection, target_projection)?;
ecx.sub(param_env, source_projection, target_projection)?;
let _ = ecx.try_evaluate_added_goals()?;
Ok(())
})
Expand All @@ -909,7 +909,7 @@ where
// Check that a's supertrait (upcast_principal) is compatible
// with the target (b_ty).
ty::ExistentialPredicate::Trait(target_principal) => {
ecx.eq(
ecx.sub(
param_env,
upcast_principal.unwrap(),
bound.rebind(target_principal),
Expand All @@ -934,7 +934,7 @@ where
Certainty::AMBIGUOUS,
);
}
ecx.eq(param_env, source_projection, target_projection)?;
ecx.sub(param_env, source_projection, target_projection)?;
}
// Check that b_ty's auto traits are present in a_ty's bounds.
ty::ExistentialPredicate::AutoTrait(def_id) => {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2582,12 +2582,12 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
nested.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.eq(
.sup(
DefineOpaqueTypes::Yes,
bound.rebind(target_principal),
upcast_principal.map_bound(|trait_ref| {
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
}),
bound.rebind(target_principal),
)
.map_err(|_| SelectionError::Unimplemented)?
.into_obligations(),
Expand Down Expand Up @@ -2620,7 +2620,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
nested.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::Yes, source_projection, target_projection)
.sup(DefineOpaqueTypes::Yes, target_projection, source_projection)
.map_err(|_| SelectionError::Unimplemented)?
.into_obligations(),
);
Expand Down
27 changes: 27 additions & 0 deletions tests/ui/coercion/sub-principals.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//@ check-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

// Verify that the unsize goal can cast a higher-ranked trait goal to
// a non-higer-ranked instantiation.

#![feature(unsize)]

use std::marker::Unsize;

fn test<T: ?Sized, U: ?Sized>()
where
T: Unsize<U>,
{
}

fn main() {
test::<dyn for<'a> Fn(&'a ()) -> &'a (), dyn Fn(&'static ()) -> &'static ()>();

trait Foo<'a, 'b> {}
test::<dyn for<'a, 'b> Foo<'a, 'b>, dyn for<'a> Foo<'a, 'a>>();

trait Bar<'a> {}
test::<dyn for<'a> Bar<'a>, dyn Bar<'_>>();
}

This file was deleted.

This file was deleted.

10 changes: 6 additions & 4 deletions tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//@ check-pass

// We should be able to instantiate a binder during trait upcasting.
// This test could be `check-pass`, but we should make sure that we
// do so in both trait solvers.

#![feature(trait_upcasting)]
#![crate_type = "rlib"]
trait Supertrait<'a, 'b> {}

trait Supertrait<'a, 'b> {}
trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}

impl<'a> Supertrait<'a, 'a> for () {}
impl<'a> Subtrait<'a, 'a> for () {}
fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
x //~ ERROR mismatched types
//[current]~^ ERROR mismatched types
x
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ error[E0308]: mismatched types
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
= note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
found existential trait ref `for<'a> Supertrait<'a, 'a>`

error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
= note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
found existential trait ref `for<'a> Supertrait<'a, 'a>`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 2 previous errors
Expand Down
26 changes: 26 additions & 0 deletions tests/ui/traits/trait-upcasting/sub.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@ check-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

// Verify that the unsize goal can cast a higher-ranked trait goal to
// a non-higer-ranked instantiation.

#![feature(unsize)]

use std::marker::Unsize;

fn test<T: ?Sized, U: ?Sized>()
where
T: Unsize<U>,
{
}

fn main() {
test::<dyn for<'a> Fn(&'a ()) -> &'a (), dyn FnOnce(&'static ()) -> &'static ()>();

trait Foo: for<'a> Bar<'a> {}
trait Bar<'a> {}
test::<dyn Foo, dyn Bar<'static>>();
test::<dyn Foo, dyn Bar<'_>>();
}

0 comments on commit d4ee408

Please sign in to comment.