Comments, another test
This commit is contained in:
parent
2540c2b761
commit
ed30efff3b
@ -235,6 +235,40 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Assemble a list of predicates that would be present on a theoretical
|
||||
/// user impl for an object type. These predicates must be checked any time
|
||||
/// we assemble a built-in object candidate for an object type, since they
|
||||
/// are not implied by the well-formedness of the type.
|
||||
///
|
||||
/// For example, given the following traits:
|
||||
///
|
||||
/// ```rust,ignore (theoretical code)
|
||||
/// trait Foo: Baz {
|
||||
/// type Bar: Copy;
|
||||
/// }
|
||||
///
|
||||
/// trait Baz {}
|
||||
/// ```
|
||||
///
|
||||
/// For the dyn type `dyn Foo<Item = Ty>`, we can imagine there being a
|
||||
/// pair of theoretical impls:
|
||||
///
|
||||
/// ```rust,ignore (theoretical code)
|
||||
/// impl Foo for dyn Foo<Item = Ty>
|
||||
/// where
|
||||
/// Self: Baz,
|
||||
/// <Self as Foo>::Bar: Copy,
|
||||
/// {
|
||||
/// type Bar = Ty;
|
||||
/// }
|
||||
///
|
||||
/// impl Baz for dyn Foo<Item = Ty> {}
|
||||
/// ```
|
||||
///
|
||||
/// However, in order to make such impls well-formed, we need to do an
|
||||
/// additional step of eagerly folding the associated types in the where
|
||||
/// clauses of the impl. In this example, that means replacing
|
||||
/// `<Self as Foo>::Bar` with `Ty` in the first impl.
|
||||
pub(crate) fn predicates_for_object_candidate<'tcx>(
|
||||
ecx: &EvalCtxt<'_, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
@ -247,6 +281,8 @@ pub(crate) fn predicates_for_object_candidate<'tcx>(
|
||||
tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.substs).predicates,
|
||||
);
|
||||
for item in tcx.associated_items(trait_ref.def_id).in_definition_order() {
|
||||
// FIXME(associated_const_equality): Also add associated consts to
|
||||
// the requirements here.
|
||||
if item.kind == ty::AssocKind::Type {
|
||||
requirements.extend(tcx.item_bounds(item.def_id).subst(tcx, trait_ref.substs));
|
||||
}
|
||||
@ -290,13 +326,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
|
||||
if let ty::Alias(ty::Projection, alias_ty) = *ty.kind()
|
||||
&& let Some(replacement) = self.mapping.get(&alias_ty.def_id)
|
||||
{
|
||||
// We may have a case where our object type's projection bound is higher-ranked,
|
||||
// but the where clauses we instantiated are not. We can solve this by instantiating
|
||||
// the binder at the usage site.
|
||||
let proj = self.ecx.instantiate_binder_with_infer(*replacement);
|
||||
// Technically this folder could be fallible?
|
||||
// FIXME: Technically this folder could be fallible?
|
||||
let nested = self
|
||||
.ecx
|
||||
.eq(self.param_env, alias_ty, proj.projection_ty)
|
||||
.expect("expected to be able to unify goal projection with dyn's projection");
|
||||
// Technically we could register these too..
|
||||
// FIXME: Technically we could register these too..
|
||||
assert!(nested.is_empty(), "did not expect unification to have any nested goals");
|
||||
proj.term.ty().unwrap()
|
||||
} else {
|
||||
|
27
tests/ui/traits/new-solver/more-object-bound.rs
Normal file
27
tests/ui/traits/new-solver/more-object-bound.rs
Normal file
@ -0,0 +1,27 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
// From #80800
|
||||
|
||||
trait SuperTrait {
|
||||
type A;
|
||||
type B;
|
||||
}
|
||||
|
||||
trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
|
||||
|
||||
fn transmute<A, B>(x: A) -> B {
|
||||
foo::<A, B, dyn Trait<A = A, B = B>>(x)
|
||||
//~^ ERROR type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
|
||||
}
|
||||
|
||||
fn foo<A, B, T: ?Sized>(x: T::A) -> B
|
||||
where
|
||||
T: Trait<B = B>,
|
||||
{
|
||||
x
|
||||
}
|
||||
|
||||
static X: u8 = 0;
|
||||
fn main() {
|
||||
let x = transmute::<&u8, &[u8; 1_000_000]>(&X);
|
||||
println!("{:?}", x[100_000]);
|
||||
}
|
19
tests/ui/traits/new-solver/more-object-bound.stderr
Normal file
19
tests/ui/traits/new-solver/more-object-bound.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error[E0283]: type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
|
||||
--> $DIR/more-object-bound.rs:12:5
|
||||
|
|
||||
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/more-object-bound.rs:18:8
|
||||
|
|
||||
LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B
|
||||
| --- required by a bound in this function
|
||||
LL | where
|
||||
LL | T: Trait<B = B>,
|
||||
| ^^^^^^^^^^^^ required by this bound in `foo`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0283`.
|
Loading…
x
Reference in New Issue
Block a user