Consider fewer predicates for projection candidates
We now require that projection candidates are applicable with the idenitity substs of the trait, rather than allowing predicates that are only applicable for certain substs.
This commit is contained in:
parent
29272fc514
commit
04e589ced8
26 changed files with 666 additions and 38 deletions
|
|
@ -133,6 +133,13 @@ rustc_queries! {
|
|||
cache_on_disk_if { key.is_local() }
|
||||
}
|
||||
|
||||
/// Returns the list of predicates that can be used for
|
||||
/// `SelectionCandidate::ProjectionCandidate` and
|
||||
/// `ProjectionTyCandidate::TraitDef`.
|
||||
query projection_predicates(key: DefId) -> &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||
desc { |tcx| "finding projection predicates for `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLib>> {
|
||||
desc { "looking up the native libraries of a linked crate" }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -333,6 +333,17 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
|
|||
/// in a different item, with `target_substs` as the base for
|
||||
/// the target impl/trait, with the source child-specific
|
||||
/// parameters (e.g., method parameters) on top of that base.
|
||||
///
|
||||
/// For example given:
|
||||
///
|
||||
/// trait X<S> { fn f<T>(); }
|
||||
/// impl<U> X<U> for U { fn f<V>() {} }
|
||||
///
|
||||
/// * If `self` is `[Self, S, T]`: the identity substs of `f` in the trait.
|
||||
/// * If `source_ancestor` is the def_id of the trait.
|
||||
/// * If `target_substs` is `[U]`, the substs for the impl.
|
||||
/// * Then we will return `[U, T]`, the subst for `f` in the impl that
|
||||
/// are needed for it to match the trait.
|
||||
pub fn rebase_onto(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
|
|||
|
|
@ -896,9 +896,12 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
|
|||
|
||||
let tcx = selcx.tcx();
|
||||
// Check whether the self-type is itself a projection.
|
||||
let (def_id, substs) = match obligation_trait_ref.self_ty().kind {
|
||||
ty::Projection(ref data) => (data.trait_ref(tcx).def_id, data.substs),
|
||||
ty::Opaque(def_id, substs) => (def_id, substs),
|
||||
// If so, extract what we know from the trait and try to come up with a good answer.
|
||||
let bounds = match obligation_trait_ref.self_ty().kind {
|
||||
ty::Projection(ref data) => {
|
||||
tcx.projection_predicates(data.item_def_id).subst(tcx, data.substs)
|
||||
}
|
||||
ty::Opaque(def_id, substs) => tcx.projection_predicates(def_id).subst(tcx, substs),
|
||||
ty::Infer(ty::TyVar(_)) => {
|
||||
// If the self-type is an inference variable, then it MAY wind up
|
||||
// being a projected type, so induce an ambiguity.
|
||||
|
|
@ -908,17 +911,13 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
|
|||
_ => return,
|
||||
};
|
||||
|
||||
// If so, extract what we know from the trait and try to come up with a good answer.
|
||||
let trait_predicates = tcx.predicates_of(def_id);
|
||||
let bounds = trait_predicates.instantiate(tcx, substs);
|
||||
let bounds = elaborate_predicates(tcx, bounds.predicates.into_iter()).map(|o| o.predicate);
|
||||
assemble_candidates_from_predicates(
|
||||
selcx,
|
||||
obligation,
|
||||
obligation_trait_ref,
|
||||
candidate_set,
|
||||
ProjectionTyCandidate::TraitDef,
|
||||
bounds,
|
||||
bounds.iter(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1484,6 +1483,12 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
|||
);
|
||||
return Progress { ty: tcx.ty_error(), obligations: nested };
|
||||
}
|
||||
// If we're trying to normalize `<Vec<u32> as X>::A<S>` using
|
||||
//`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
|
||||
//
|
||||
// * `obligation.predicate.substs` is `[Vec<u32>, S]`
|
||||
// * `substs` is `[u32]`
|
||||
// * `substs` ends up as `[u32, S]`
|
||||
let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs);
|
||||
let substs =
|
||||
translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node);
|
||||
|
|
|
|||
|
|
@ -1273,9 +1273,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
placeholder_trait_predicate,
|
||||
);
|
||||
|
||||
let (def_id, substs) = match placeholder_trait_predicate.trait_ref.self_ty().kind {
|
||||
ty::Projection(ref data) => (data.trait_ref(self.tcx()).def_id, data.substs),
|
||||
ty::Opaque(def_id, substs) => (def_id, substs),
|
||||
let tcx = self.infcx.tcx;
|
||||
let predicates = match placeholder_trait_predicate.trait_ref.self_ty().kind {
|
||||
ty::Projection(ref data) => {
|
||||
tcx.projection_predicates(data.item_def_id).subst(tcx, data.substs)
|
||||
}
|
||||
ty::Opaque(def_id, substs) => tcx.projection_predicates(def_id).subst(tcx, substs),
|
||||
_ => {
|
||||
span_bug!(
|
||||
obligation.cause.span,
|
||||
|
|
@ -1285,32 +1288,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
);
|
||||
}
|
||||
};
|
||||
debug!(
|
||||
"match_projection_obligation_against_definition_bounds: \
|
||||
def_id={:?}, substs={:?}",
|
||||
def_id, substs
|
||||
);
|
||||
|
||||
let predicates_of = self.tcx().predicates_of(def_id);
|
||||
let bounds = predicates_of.instantiate(self.tcx(), substs);
|
||||
debug!(
|
||||
"match_projection_obligation_against_definition_bounds: \
|
||||
bounds={:?}",
|
||||
bounds
|
||||
);
|
||||
|
||||
let elaborated_predicates =
|
||||
util::elaborate_predicates(self.tcx(), bounds.predicates.into_iter());
|
||||
let matching_bound = elaborated_predicates.filter_to_traits().find(|bound| {
|
||||
self.infcx.probe(|_| {
|
||||
self.match_projection(
|
||||
obligation,
|
||||
*bound,
|
||||
placeholder_trait_predicate.trait_ref,
|
||||
&placeholder_map,
|
||||
snapshot,
|
||||
)
|
||||
})
|
||||
let matching_bound = predicates.iter().find_map(|bound| {
|
||||
if let ty::PredicateKind::Trait(bound, _) = bound.kind() {
|
||||
let bound = bound.to_poly_trait_ref();
|
||||
if self.infcx.probe(|_| {
|
||||
self.match_projection(
|
||||
obligation,
|
||||
bound,
|
||||
placeholder_trait_predicate.trait_ref,
|
||||
&placeholder_map,
|
||||
snapshot,
|
||||
)
|
||||
}) {
|
||||
return Some(bound);
|
||||
}
|
||||
}
|
||||
None
|
||||
});
|
||||
|
||||
debug!(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::hir::map as hir_map;
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
|
||||
use rustc_session::CrateDisambiguator;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
|
@ -365,6 +367,106 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
|
|||
fn_like.asyncness()
|
||||
}
|
||||
|
||||
/// For associated types we allow bounds written on the associated type
|
||||
/// (`type X: Trait`) to be used as candidates. We also allow the same bounds
|
||||
/// when desugared as bounds on the trait `where Self::X: Trait`.
|
||||
///
|
||||
/// Note that this filtering is done with the trait's identity substs to
|
||||
/// simplify checking that these bounds are met in impls. This means that
|
||||
/// a bound such as `for<'b> <Self as X<'b>>::U: Clone` can't be used, as in
|
||||
/// `hr-associated-type-bound-1.rs`.
|
||||
fn associated_type_projection_predicates(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> &'_ ty::List<ty::Predicate<'_>> {
|
||||
let trait_id = tcx.associated_item(def_id).container.id();
|
||||
let trait_substs = InternalSubsts::identity_for_item(tcx, trait_id);
|
||||
|
||||
let generic_trait_bounds = tcx.predicates_of(trait_id);
|
||||
let trait_bounds = generic_trait_bounds.instantiate_identity(tcx);
|
||||
let trait_predicates = util::elaborate_predicates(tcx, trait_bounds.predicates.into_iter());
|
||||
|
||||
let predicates = trait_predicates.filter_map(|obligation| {
|
||||
let pred = obligation.predicate;
|
||||
match pred.kind() {
|
||||
ty::PredicateKind::Trait(tr, _) => {
|
||||
if let ty::Projection(p) = tr.skip_binder().self_ty().kind {
|
||||
if p.item_def_id == def_id && p.substs.starts_with(trait_substs) {
|
||||
return Some(pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::Projection(proj) => {
|
||||
if let ty::Projection(p) = proj.skip_binder().projection_ty.self_ty().kind {
|
||||
if p.item_def_id == def_id && p.substs.starts_with(trait_substs) {
|
||||
return Some(pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
None
|
||||
});
|
||||
|
||||
let result = tcx.mk_predicates(predicates);
|
||||
debug!("associated_type_projection_predicates({}) = {:?}", tcx.def_path_str(def_id), result);
|
||||
result
|
||||
}
|
||||
|
||||
/// Opaque types don't have the same issues as associated types: the only
|
||||
/// predicates on an opaque type (excluding those it inherits from its parent
|
||||
/// item) should be of the form we're expecting.
|
||||
fn opaque_type_projection_predicates(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> &'_ ty::List<ty::Predicate<'_>> {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
|
||||
let generics_bounds = tcx.predicates_of(def_id);
|
||||
let bounds = generics_bounds.instantiate_identity(tcx);
|
||||
let predicates = util::elaborate_predicates(tcx, bounds.predicates.into_iter());
|
||||
|
||||
let filtered_predicates = predicates.filter_map(|obligation| {
|
||||
let pred = obligation.predicate;
|
||||
match pred.kind() {
|
||||
ty::PredicateKind::Trait(tr, _) => {
|
||||
if let ty::Opaque(opaque_def_id, opaque_substs) = tr.skip_binder().self_ty().kind {
|
||||
if opaque_def_id == def_id && opaque_substs == substs {
|
||||
return Some(pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::Projection(proj) => {
|
||||
if let ty::Opaque(opaque_def_id, opaque_substs) =
|
||||
proj.skip_binder().projection_ty.self_ty().kind
|
||||
{
|
||||
if opaque_def_id == def_id && opaque_substs == substs {
|
||||
return Some(pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
tcx.sess.delay_span_bug(
|
||||
obligation.cause.span(tcx),
|
||||
&format!("unexpected predicate {:?} on opaque type", pred),
|
||||
);
|
||||
None
|
||||
});
|
||||
|
||||
let result = tcx.mk_predicates(filtered_predicates);
|
||||
debug!("opaque_type_projection_predicates({}) = {:?}", tcx.def_path_str(def_id), result);
|
||||
result
|
||||
}
|
||||
|
||||
fn projection_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> &'_ ty::List<ty::Predicate<'_>> {
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::AssocTy => associated_type_projection_predicates(tcx, def_id),
|
||||
DefKind::OpaqueTy => opaque_type_projection_predicates(tcx, def_id),
|
||||
k => bug!("projection_predicates called on {}", k.descr(def_id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers<'_>) {
|
||||
*providers = ty::query::Providers {
|
||||
asyncness,
|
||||
|
|
@ -381,6 +483,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
|
|||
instance_def_size_estimate,
|
||||
issue33140_self_ty,
|
||||
impl_defaultness,
|
||||
projection_predicates,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2281,7 +2281,7 @@ fn check_impl_items_against_trait<'tcx>(
|
|||
&ty_trait_item,
|
||||
impl_trait_ref,
|
||||
opt_trait_span,
|
||||
)
|
||||
);
|
||||
} else {
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
|
|
|
|||
18
src/test/ui/associated-types/hr-associated-type-bound-1.rs
Normal file
18
src/test/ui/associated-types/hr-associated-type-bound-1.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
trait X<'a>
|
||||
where
|
||||
for<'b> <Self as X<'b>>::U: Clone,
|
||||
{
|
||||
type U: ?Sized;
|
||||
fn f(&self, x: &Self::U) {
|
||||
<Self::U>::clone(x);
|
||||
}
|
||||
}
|
||||
|
||||
impl X<'_> for i32 {
|
||||
type U = str;
|
||||
//~^ ERROR the trait bound `for<'b> <i32 as X<'b>>::U: std::clone::Clone`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
1i32.f("abc");
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
error[E0277]: the trait bound `for<'b> <i32 as X<'b>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-1.rs:12:14
|
||||
|
|
||||
LL | trait X<'a>
|
||||
| - required by a bound in this
|
||||
LL | where
|
||||
LL | for<'b> <Self as X<'b>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<i32 as X<'b>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
21
src/test/ui/associated-types/hr-associated-type-bound-2.rs
Normal file
21
src/test/ui/associated-types/hr-associated-type-bound-2.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
trait X<'a>
|
||||
where
|
||||
for<'b> <Self as X<'b>>::U: Clone,
|
||||
{
|
||||
type U: ?Sized;
|
||||
fn f(&self, x: &Self::U) {
|
||||
<Self::U>::clone(x);
|
||||
}
|
||||
}
|
||||
|
||||
impl X<'_> for u32
|
||||
where
|
||||
for<'b> <Self as X<'b>>::U: Clone,
|
||||
{
|
||||
type U = str;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
1u32.f("abc");
|
||||
//~^ ERROR no method named `f` found for type `u32` in the current scope
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
error[E0599]: no method named `f` found for type `u32` in the current scope
|
||||
--> $DIR/hr-associated-type-bound-2.rs:19:10
|
||||
|
|
||||
LL | 1u32.f("abc");
|
||||
| ^ method not found in `u32`
|
||||
|
|
||||
= note: the method `f` exists but the following trait bounds were not satisfied:
|
||||
`<u32 as X<'b>>::U: std::clone::Clone`
|
||||
which is required by `u32: X`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
trait X<'a>
|
||||
where
|
||||
for<'b> <Self as X<'b>>::U: Clone,
|
||||
{
|
||||
type U: ?Sized;
|
||||
}
|
||||
fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) {
|
||||
//~^ ERROR the trait bound `for<'b> <T as X<'b>>::U: std::clone::Clone` is not satisfied
|
||||
<<T as X<'_>>::U>::clone(x);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
f::<dyn X<'_, U = str>>("abc");
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
error[E0277]: the trait bound `for<'b> <T as X<'b>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-object.rs:7:13
|
||||
|
|
||||
LL | trait X<'a>
|
||||
| - required by a bound in this
|
||||
LL | where
|
||||
LL | for<'b> <Self as X<'b>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) {
|
||||
| ^^^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<T as X<'b>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
trait Y<'a, T: ?Sized>
|
||||
where
|
||||
T: Y<'a, Self>,
|
||||
for<'b> <Self as Y<'b, T>>::V: Clone,
|
||||
for<'b> <T as Y<'b, Self>>::V: Clone,
|
||||
{
|
||||
type V: ?Sized;
|
||||
fn g(&self, x: &Self::V) {
|
||||
<Self::V>::clone(x);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Y<'a, u8> for u8 {
|
||||
type V = str;
|
||||
//~^ ERROR the trait bound `for<'b> <u8 as Y<'b, u8>>::V: std::clone::Clone` is not satisfied
|
||||
}
|
||||
|
||||
fn main() {
|
||||
1u8.g("abc");
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
error[E0277]: the trait bound `for<'b> <u8 as Y<'b, u8>>::V: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-1.rs:14:14
|
||||
|
|
||||
LL | trait Y<'a, T: ?Sized>
|
||||
| - required by a bound in this
|
||||
...
|
||||
LL | for<'b> <Self as Y<'b, T>>::V: Clone,
|
||||
| ----- required by this bound in `Y`
|
||||
...
|
||||
LL | type V = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<u8 as Y<'b, u8>>::V`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
trait Z<'a, T: ?Sized>
|
||||
where
|
||||
T: Z<'a, u16>,
|
||||
//~^ the trait bound `for<'b> <u16 as Z<'b, u16>>::W: std::clone::Clone` is not satisfied
|
||||
//~| the trait bound `for<'b> <u16 as Z<'b, u16>>::W: std::clone::Clone` is not satisfied
|
||||
for<'b> <T as Z<'b, u16>>::W: Clone,
|
||||
{
|
||||
type W: ?Sized;
|
||||
fn h(&self, x: &T::W) {
|
||||
<T::W>::clone(x);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Z<'a, u16> for u16 {
|
||||
type W = str;
|
||||
//~^ ERROR the trait bound `for<'b> <u16 as Z<'b, u16>>::W: std::clone::Clone
|
||||
}
|
||||
|
||||
fn main() {
|
||||
1u16.h("abc");
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
error[E0277]: the trait bound `for<'b> <u16 as Z<'b, u16>>::W: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:3:8
|
||||
|
|
||||
LL | trait Z<'a, T: ?Sized>
|
||||
| - required by a bound in this
|
||||
LL | where
|
||||
LL | T: Z<'a, u16>,
|
||||
| ^^^^^^^^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<u16 as Z<'b, u16>>::W`
|
||||
...
|
||||
LL | for<'b> <T as Z<'b, u16>>::W: Clone,
|
||||
| ----- required by this bound in `Z`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error[E0277]: the trait bound `for<'b> <u16 as Z<'b, u16>>::W: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:15:14
|
||||
|
|
||||
LL | trait Z<'a, T: ?Sized>
|
||||
| - required by a bound in this
|
||||
...
|
||||
LL | for<'b> <T as Z<'b, u16>>::W: Clone,
|
||||
| ----- required by this bound in `Z`
|
||||
...
|
||||
LL | type W = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<u16 as Z<'b, u16>>::W`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error[E0277]: the trait bound `for<'b> <u16 as Z<'b, u16>>::W: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-2.rs:3:8
|
||||
|
|
||||
LL | trait Z<'a, T: ?Sized>
|
||||
| - required by a bound in this
|
||||
LL | where
|
||||
LL | T: Z<'a, u16>,
|
||||
| ^^^^^^^^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<u16 as Z<'b, u16>>::W`
|
||||
...
|
||||
LL | for<'b> <T as Z<'b, u16>>::W: Clone,
|
||||
| ----- required by this bound in `Z`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// ignore-tidy-linelength
|
||||
|
||||
trait X<'a, T>
|
||||
where
|
||||
for<'b> T: X<'b, T>,
|
||||
for<'b> <T as X<'b, T>>::U: Clone,
|
||||
{
|
||||
type U: ?Sized;
|
||||
fn f(x: &<T as X<'_, T>>::U) {
|
||||
<<T as X<'_, T>>::U>::clone(x);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> X<'_, (T,)> for (S,) {
|
||||
type U = str;
|
||||
//~^ ERROR the trait bound `for<'b> <(T,) as X<'b, (T,)>>::U: std::clone::Clone` is not satisfied
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
<(i32,) as X<(i32,)>>::f("abc");
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
error[E0277]: the trait bound `for<'b> <(T,) as X<'b, (T,)>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-3.rs:15:14
|
||||
|
|
||||
LL | trait X<'a, T>
|
||||
| - required by a bound in this
|
||||
...
|
||||
LL | for<'b> <T as X<'b, T>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<(T,) as X<'b, (T,)>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
trait X<'a, T>
|
||||
where
|
||||
for<'b> (T,): X<'b, T>,
|
||||
for<'b> <(T,) as X<'b, T>>::U: Clone,
|
||||
{
|
||||
type U: ?Sized;
|
||||
fn f(x: &<(T,) as X<'_, T>>::U) {
|
||||
<<(T,) as X<'_, T>>::U>::clone(x);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> X<'_, T> for (S,) {
|
||||
type U = str;
|
||||
//~^ ERROR the trait bound `for<'b> <(T,) as X<'b, T>>::U: std::clone::Clone` is not satisfied
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
<(i32,) as X<i32>>::f("abc");
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
error[E0277]: the trait bound `for<'b> <(T,) as X<'b, T>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-4.rs:13:14
|
||||
|
|
||||
LL | trait X<'a, T>
|
||||
| - required by a bound in this
|
||||
...
|
||||
LL | for<'b> <(T,) as X<'b, T>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<(T,) as X<'b, T>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// ignore-tidy-linelength
|
||||
|
||||
trait Cycle: Sized {
|
||||
type Next: Cycle<Next = Self>;
|
||||
}
|
||||
|
||||
impl<T> Cycle for Box<T> {
|
||||
type Next = Vec<T>;
|
||||
}
|
||||
|
||||
impl<T> Cycle for Vec<T> {
|
||||
type Next = Box<T>;
|
||||
}
|
||||
|
||||
trait X<'a, T: Cycle + for<'b> X<'b, T>>
|
||||
where
|
||||
for<'b> <T as X<'b, T>>::U: Clone,
|
||||
for<'b> T::Next: X<'b, T::Next>,
|
||||
for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
|
||||
{
|
||||
type U: ?Sized;
|
||||
fn f(x: &<T as X<'_, T>>::U) {
|
||||
<<T as X<'_, T>>::U>::clone(x);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> X<'_, Vec<T>> for S {
|
||||
type U = str;
|
||||
//~^ ERROR the trait bound `for<'b> <std::boxed::Box<T> as X<'b, std::boxed::Box<T>>>::U: std::clone::Clone` is not satisfied
|
||||
//~| ERROR the trait bound `for<'b> <std::vec::Vec<T> as X<'b, std::vec::Vec<T>>>::U: std::clone::Clone` is not satisfied
|
||||
}
|
||||
|
||||
impl<S, T> X<'_, Box<T>> for S {
|
||||
type U = str;
|
||||
//~^ ERROR the trait bound `for<'b> <std::boxed::Box<T> as X<'b, std::boxed::Box<T>>>::U: std::clone::Clone` is not satisfied
|
||||
//~| ERROR the trait bound `for<'b> <std::vec::Vec<T> as X<'b, std::vec::Vec<T>>>::U: std::clone::Clone` is not satisfied
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
<i32 as X<Box<i32>>>::f("abc");
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
error[E0277]: the trait bound `for<'b> <std::boxed::Box<T> as X<'b, std::boxed::Box<T>>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:28:14
|
||||
|
|
||||
LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
|
||||
| - required by a bound in this
|
||||
...
|
||||
LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<std::boxed::Box<T> as X<'b, std::boxed::Box<T>>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error[E0277]: the trait bound `for<'b> <std::vec::Vec<T> as X<'b, std::vec::Vec<T>>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:28:14
|
||||
|
|
||||
LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
|
||||
| - required by a bound in this
|
||||
LL | where
|
||||
LL | for<'b> <T as X<'b, T>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<std::vec::Vec<T> as X<'b, std::vec::Vec<T>>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error[E0277]: the trait bound `for<'b> <std::vec::Vec<T> as X<'b, std::vec::Vec<T>>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:34:14
|
||||
|
|
||||
LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
|
||||
| - required by a bound in this
|
||||
...
|
||||
LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<std::vec::Vec<T> as X<'b, std::vec::Vec<T>>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error[E0277]: the trait bound `for<'b> <std::boxed::Box<T> as X<'b, std::boxed::Box<T>>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-5.rs:34:14
|
||||
|
|
||||
LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
|
||||
| - required by a bound in this
|
||||
LL | where
|
||||
LL | for<'b> <T as X<'b, T>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<std::boxed::Box<T> as X<'b, std::boxed::Box<T>>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
trait X<'a, T>
|
||||
where
|
||||
for<'b> T: X<'b, T>,
|
||||
for<'b> <T as X<'b, T>>::U: Clone,
|
||||
{
|
||||
type U: ?Sized;
|
||||
fn f(x: &<T as X<'_, T>>::U) {
|
||||
<<T as X<'_, T>>::U>::clone(x);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> X<'_, T> for (S,) {
|
||||
//~^ ERROR the trait bound `for<'b> T: X<'b, T>` is not satisfied
|
||||
type U = str;
|
||||
//~^ ERROR the trait bound `for<'b> <T as X<'b, T>>::U: std::clone::Clone` is not satisfied
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
<(i32,) as X<i32>>::f("abc");
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
error[E0277]: the trait bound `for<'b> <T as X<'b, T>>::U: std::clone::Clone` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-6.rs:14:14
|
||||
|
|
||||
LL | trait X<'a, T>
|
||||
| - required by a bound in this
|
||||
...
|
||||
LL | for<'b> <T as X<'b, T>>::U: Clone,
|
||||
| ----- required by this bound in `X`
|
||||
...
|
||||
LL | type U = str;
|
||||
| ^^^ the trait `for<'b> std::clone::Clone` is not implemented for `<T as X<'b, T>>::U`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::clone::Clone>
|
||||
<&mut T as std::clone::Clone>
|
||||
|
||||
error[E0277]: the trait bound `for<'b> T: X<'b, T>` is not satisfied
|
||||
--> $DIR/hr-associated-type-bound-param-6.rs:12:12
|
||||
|
|
||||
LL | trait X<'a, T>
|
||||
| - required by a bound in this
|
||||
LL | where
|
||||
LL | for<'b> T: X<'b, T>,
|
||||
| -------- required by this bound in `X`
|
||||
...
|
||||
LL | impl<S, T> X<'_, T> for (S,) {
|
||||
| ^^^^^^^^ the trait `for<'b> X<'b, T>` is not implemented for `T`
|
||||
|
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | impl<S, T: for<'b> X<'b, T>> X<'_, T> for (S,) {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
trait UnsafeCopy<'a, T: Copy>
|
||||
where
|
||||
for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>,
|
||||
{
|
||||
type Item;
|
||||
|
||||
fn bug(item: &Self::Item) -> () {
|
||||
let x: T = **item;
|
||||
&x as *const _;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
|
||||
//~^ ERROR the trait bound `<T as UnsafeCopy<'b, T>>::Item: std::ops::Deref` is not satisfied
|
||||
type Item = T;
|
||||
//~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: std::ops::Deref
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
<&'static str>::bug(&"");
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
error[E0277]: the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: std::ops::Deref` is not satisfied
|
||||
--> $DIR/hr-associated-type-projection-1.rs:15:17
|
||||
|
|
||||
LL | trait UnsafeCopy<'a, T: Copy>
|
||||
| ---------- required by a bound in this
|
||||
LL | where
|
||||
LL | for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>,
|
||||
| --------------------------- required by this bound in `UnsafeCopy`
|
||||
...
|
||||
LL | type Item = T;
|
||||
| ^ the trait `for<'b> std::ops::Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<&T as std::ops::Deref>
|
||||
<&mut T as std::ops::Deref>
|
||||
|
||||
error[E0277]: the trait bound `<T as UnsafeCopy<'b, T>>::Item: std::ops::Deref` is not satisfied
|
||||
--> $DIR/hr-associated-type-projection-1.rs:13:33
|
||||
|
|
||||
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
|
||||
|
|
||||
help: consider further restricting the associated type
|
||||
|
|
||||
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where <T as UnsafeCopy<'b, T>>::Item: std::ops::Deref {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue