mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Check allow instantiating object trait binder when upcasting and in new solver
This commit is contained in:
parent
58420a065b
commit
d4ee408afc
@ -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(())
|
||||
})
|
||||
@ -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),
|
||||
@ -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) => {
|
||||
|
@ -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(),
|
||||
@ -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(),
|
||||
);
|
||||
|
27
tests/ui/coercion/sub-principals.rs
Normal file
27
tests/ui/coercion/sub-principals.rs
Normal file
@ -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<'_>>();
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/higher-ranked-upcasting-ok.rs:17:5
|
||||
|
|
||||
LL | x
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= 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-ok.rs:17:5
|
||||
|
|
||||
LL | x
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= 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
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,14 +0,0 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/higher-ranked-upcasting-ok.rs:17:5
|
||||
|
|
||||
LL | fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
|
||||
| ------------------------------- expected `&dyn for<'a> Supertrait<'a, 'a>` because of return type
|
||||
LL | x
|
||||
| ^ expected trait `Supertrait`, found trait `Subtrait`
|
||||
|
|
||||
= note: expected reference `&dyn for<'a> Supertrait<'a, 'a>`
|
||||
found reference `&dyn for<'a, 'b> Subtrait<'a, 'b>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -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> {}
|
||||
|
||||
#![feature(trait_upcasting)]
|
||||
|
||||
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() {}
|
||||
|
@ -4,8 +4,8 @@ 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
|
||||
@ -13,8 +13,8 @@ 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>`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
26
tests/ui/traits/trait-upcasting/sub.rs
Normal file
26
tests/ui/traits/trait-upcasting/sub.rs
Normal file
@ -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<'_>>();
|
||||
}
|
Loading…
Reference in New Issue
Block a user