For a rigid projection, recursively look at the self type's item bounds
This commit is contained in:
parent
98aa3624be
commit
22d582a38d
23 changed files with 273 additions and 431 deletions
|
@ -542,7 +542,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
goal: Goal<'tcx, G>,
|
goal: Goal<'tcx, G>,
|
||||||
candidates: &mut Vec<Candidate<'tcx>>,
|
candidates: &mut Vec<Candidate<'tcx>>,
|
||||||
) {
|
) {
|
||||||
let alias_ty = match goal.predicate.self_ty().kind() {
|
let _ = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
|
||||||
|
let mut self_ty = goal.predicate.self_ty();
|
||||||
|
|
||||||
|
// For some deeply nested `<T>::A::B::C::D` rigid associated type,
|
||||||
|
// we should explore the item bounds for all levels, since the
|
||||||
|
// `associated_type_bounds` feature means that a parent associated
|
||||||
|
// type may carry bounds for a nested associated type.
|
||||||
|
loop {
|
||||||
|
let (kind, alias_ty) = match *self_ty.kind() {
|
||||||
ty::Bool
|
ty::Bool
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Int(_)
|
| ty::Int(_)
|
||||||
|
@ -567,25 +575,64 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
| ty::Param(_)
|
| ty::Param(_)
|
||||||
| ty::Placeholder(..)
|
| ty::Placeholder(..)
|
||||||
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||||
| ty::Alias(ty::Inherent, _)
|
| ty::Error(_) => break,
|
||||||
| ty::Alias(ty::Weak, _)
|
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
|
||||||
| ty::Error(_) => return,
|
|
||||||
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
|
|
||||||
| ty::Bound(..) => bug!("unexpected self type for `{goal:?}`"),
|
| ty::Bound(..) => bug!("unexpected self type for `{goal:?}`"),
|
||||||
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
|
|
||||||
ty::Alias(ty::Projection | ty::Opaque, alias_ty) => alias_ty,
|
// If we hit infer when normalizing the self type of an alias,
|
||||||
|
// then bail with ambiguity.
|
||||||
|
ty::Infer(ty::TyVar(_)) => {
|
||||||
|
if let Ok(result) = ecx
|
||||||
|
.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||||
|
{
|
||||||
|
candidates
|
||||||
|
.push(Candidate { source: CandidateSource::AliasBound, result });
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
|
||||||
|
ty::Alias(ty::Inherent | ty::Weak, _) => {
|
||||||
|
unreachable!("Weak and Inherent aliases should have been normalized away")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for assumption in
|
for assumption in
|
||||||
self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
|
ecx.tcx().item_bounds(alias_ty.def_id).instantiate(ecx.tcx(), alias_ty.args)
|
||||||
{
|
{
|
||||||
match G::consider_alias_bound_candidate(self, goal, assumption) {
|
match G::consider_alias_bound_candidate(ecx, goal, assumption) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
|
candidates
|
||||||
|
.push(Candidate { source: CandidateSource::AliasBound, result });
|
||||||
}
|
}
|
||||||
Err(NoSolution) => (),
|
Err(NoSolution) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have a projection, check that its self type is a rigid projection.
|
||||||
|
// If so, continue searching.
|
||||||
|
if kind == ty::Projection {
|
||||||
|
match ecx.try_normalize_ty(goal.param_env, alias_ty.self_ty()) {
|
||||||
|
Some(next_self_ty) => self_ty = next_self_ty,
|
||||||
|
None => {
|
||||||
|
if let Ok(result) = ecx
|
||||||
|
.evaluate_added_goals_and_make_canonical_response(
|
||||||
|
Certainty::OVERFLOW,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
candidates.push(Candidate {
|
||||||
|
source: CandidateSource::AliasBound,
|
||||||
|
result,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that we are allowed to use an alias bound originating from the self
|
/// Check that we are allowed to use an alias bound originating from the self
|
||||||
|
|
|
@ -40,6 +40,7 @@ use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
pub use rustc_middle::traits::Reveal;
|
pub use rustc_middle::traits::Reveal;
|
||||||
|
|
||||||
|
@ -1614,32 +1615,46 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
|
||||||
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
||||||
) {
|
) {
|
||||||
debug!("assemble_candidates_from_trait_def(..)");
|
debug!("assemble_candidates_from_trait_def(..)");
|
||||||
|
let mut ambiguous = false;
|
||||||
let tcx = selcx.tcx();
|
selcx.for_each_item_bound(
|
||||||
// Check whether the self-type is itself a projection.
|
obligation.predicate.self_ty(),
|
||||||
// If so, extract what we know from the trait and try to come up with a good answer.
|
|selcx, clause, _| {
|
||||||
let bounds = match *obligation.predicate.self_ty().kind() {
|
let Some(clause) = clause.as_projection_clause() else {
|
||||||
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
|
return ControlFlow::Continue(());
|
||||||
ty::Alias(ty::Projection | ty::Opaque, ref data) => {
|
|
||||||
tcx.item_bounds(data.def_id).instantiate(tcx, data.args)
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
candidate_set.mark_ambiguous();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ => return,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assemble_candidates_from_predicates(
|
let is_match =
|
||||||
selcx,
|
selcx.infcx.probe(|_| selcx.match_projection_projections(obligation, clause, true));
|
||||||
obligation,
|
|
||||||
candidate_set,
|
match is_match {
|
||||||
ProjectionCandidate::TraitDef,
|
ProjectionMatchesProjection::Yes => {
|
||||||
bounds.iter(),
|
candidate_set.push_candidate(ProjectionCandidate::TraitDef(clause));
|
||||||
true,
|
|
||||||
|
if !obligation.predicate.has_non_region_infer() {
|
||||||
|
// HACK: Pick the first trait def candidate for a fully
|
||||||
|
// inferred predicate. This is to allow duplicates that
|
||||||
|
// differ only in normalization.
|
||||||
|
return ControlFlow::Break(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProjectionMatchesProjection::Ambiguous => {
|
||||||
|
candidate_set.mark_ambiguous();
|
||||||
|
}
|
||||||
|
ProjectionMatchesProjection::No => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
},
|
||||||
|
|| {
|
||||||
|
// `ProjectionCandidateSet` is borrowed in the above closure,
|
||||||
|
// so just mark ambiguous outside of the closure.
|
||||||
|
ambiguous = true;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ambiguous {
|
||||||
|
candidate_set.mark_ambiguous();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In the case of a trait object like
|
/// In the case of a trait object like
|
||||||
|
|
|
@ -6,13 +6,16 @@
|
||||||
//!
|
//!
|
||||||
//! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
|
//! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
|
||||||
|
|
||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use hir::LangItem;
|
use hir::LangItem;
|
||||||
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
|
use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
|
||||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt};
|
||||||
|
|
||||||
use crate::traits;
|
use crate::traits;
|
||||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
|
@ -158,11 +161,52 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
_ => return,
|
_ => return,
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = self
|
self.infcx.probe(|_| {
|
||||||
.infcx
|
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
|
||||||
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
|
let placeholder_trait_predicate =
|
||||||
|
self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
|
||||||
|
debug!(?placeholder_trait_predicate);
|
||||||
|
|
||||||
candidates.vec.extend(result.into_iter().map(|idx| ProjectionCandidate(idx)));
|
// The bounds returned by `item_bounds` may contain duplicates after
|
||||||
|
// normalization, so try to deduplicate when possible to avoid
|
||||||
|
// unnecessary ambiguity.
|
||||||
|
let mut distinct_normalized_bounds = FxHashSet::default();
|
||||||
|
self.for_each_item_bound::<!>(
|
||||||
|
placeholder_trait_predicate.self_ty(),
|
||||||
|
|selcx, bound, idx| {
|
||||||
|
let Some(bound) = bound.as_trait_clause() else {
|
||||||
|
return ControlFlow::Continue(());
|
||||||
|
};
|
||||||
|
if bound.polarity() != placeholder_trait_predicate.polarity {
|
||||||
|
return ControlFlow::Continue(());
|
||||||
|
}
|
||||||
|
|
||||||
|
selcx.infcx.probe(|_| {
|
||||||
|
match selcx.match_normalize_trait_ref(
|
||||||
|
obligation,
|
||||||
|
bound.to_poly_trait_ref(),
|
||||||
|
placeholder_trait_predicate.trait_ref,
|
||||||
|
) {
|
||||||
|
Ok(None) => {
|
||||||
|
candidates.vec.push(ProjectionCandidate(idx));
|
||||||
|
}
|
||||||
|
Ok(Some(normalized_trait))
|
||||||
|
if distinct_normalized_bounds.insert(normalized_trait) =>
|
||||||
|
{
|
||||||
|
candidates.vec.push(ProjectionCandidate(idx));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
},
|
||||||
|
|| {
|
||||||
|
// On ambiguity.
|
||||||
|
candidates.ambiguous = true;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
|
/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
|
||||||
|
|
|
@ -162,20 +162,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref;
|
self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref;
|
||||||
let placeholder_self_ty = placeholder_trait_predicate.self_ty();
|
let placeholder_self_ty = placeholder_trait_predicate.self_ty();
|
||||||
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
|
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
|
||||||
let (def_id, args) = match *placeholder_self_ty.kind() {
|
|
||||||
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
|
|
||||||
ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
|
|
||||||
(def_id, args)
|
|
||||||
}
|
|
||||||
_ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
|
|
||||||
};
|
|
||||||
|
|
||||||
let candidate_predicate =
|
let candidate_predicate = self
|
||||||
tcx.item_bounds(def_id).map_bound(|i| i[idx]).instantiate(tcx, args);
|
.for_each_item_bound(
|
||||||
|
placeholder_self_ty,
|
||||||
|
|_, clause, clause_idx| {
|
||||||
|
if clause_idx == idx {
|
||||||
|
ControlFlow::Break(clause)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|| unreachable!(),
|
||||||
|
)
|
||||||
|
.break_value()
|
||||||
|
.expect("expected to index into clause that exists");
|
||||||
let candidate = candidate_predicate
|
let candidate = candidate_predicate
|
||||||
.as_trait_clause()
|
.as_trait_clause()
|
||||||
.expect("projection candidate is not a trait predicate")
|
.expect("projection candidate is not a trait predicate")
|
||||||
.map_bound(|t| t.trait_ref);
|
.map_bound(|t| t.trait_ref);
|
||||||
|
|
||||||
let mut obligations = Vec::new();
|
let mut obligations = Vec::new();
|
||||||
let candidate = normalize_with_depth_to(
|
let candidate = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
|
@ -194,8 +200,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
.map_err(|_| Unimplemented)
|
.map_err(|_| Unimplemented)
|
||||||
})?);
|
})?);
|
||||||
|
|
||||||
if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() {
|
// FIXME(compiler-errors): I don't think this is needed.
|
||||||
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args);
|
if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
|
||||||
|
let predicates = tcx.predicates_of(alias_ty.def_id).instantiate_own(tcx, alias_ty.args);
|
||||||
for (predicate, _) in predicates {
|
for (predicate, _) in predicates {
|
||||||
let normalized = normalize_with_depth_to(
|
let normalized = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -52,6 +52,7 @@ use std::cell::{Cell, RefCell};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
pub use rustc_middle::traits::select::*;
|
pub use rustc_middle::traits::select::*;
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
|
@ -1592,71 +1593,41 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
|
self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Matches a predicate against the bounds of its self type.
|
/// Looks at the item bounds of the projection or opaque type.
|
||||||
///
|
/// If this is a nested rigid projection, such as
|
||||||
/// Given an obligation like `<T as Foo>::Bar: Baz` where the self type is
|
/// `<<T as Tr1>::Assoc as Tr2>::Assoc`, consider the item bounds
|
||||||
/// a projection, look at the bounds of `T::Bar`, see if we can find a
|
/// on both `Tr1::Assoc` and `Tr2::Assoc`, since we may encounter
|
||||||
/// `Baz` bound. We return indexes into the list returned by
|
/// relative bounds on both via the `associated_type_bounds` feature.
|
||||||
/// `tcx.item_bounds` for any applicable bounds.
|
pub(super) fn for_each_item_bound<T>(
|
||||||
#[instrument(level = "debug", skip(self), ret)]
|
|
||||||
fn match_projection_obligation_against_definition_bounds(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &PolyTraitObligation<'tcx>,
|
mut self_ty: Ty<'tcx>,
|
||||||
) -> smallvec::SmallVec<[usize; 2]> {
|
mut for_each: impl FnMut(&mut Self, ty::Clause<'tcx>, usize) -> ControlFlow<T, ()>,
|
||||||
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
|
on_ambiguity: impl FnOnce(),
|
||||||
let placeholder_trait_predicate =
|
) -> ControlFlow<T, ()> {
|
||||||
self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
|
let mut idx = 0;
|
||||||
debug!(?placeholder_trait_predicate);
|
loop {
|
||||||
|
let (kind, alias_ty) = match *self_ty.kind() {
|
||||||
let tcx = self.infcx.tcx;
|
ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
|
||||||
let (def_id, args) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
|
ty::Infer(ty::TyVar(_)) => {
|
||||||
ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
|
on_ambiguity();
|
||||||
(def_id, args)
|
return ControlFlow::Continue(());
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
span_bug!(
|
|
||||||
obligation.cause.span,
|
|
||||||
"match_projection_obligation_against_definition_bounds() called \
|
|
||||||
but self-ty is not a projection: {:?}",
|
|
||||||
placeholder_trait_predicate.trait_ref.self_ty()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
_ => return ControlFlow::Continue(()),
|
||||||
};
|
};
|
||||||
let bounds = tcx.item_bounds(def_id).instantiate(tcx, args);
|
|
||||||
|
|
||||||
// The bounds returned by `item_bounds` may contain duplicates after
|
for bound in
|
||||||
// normalization, so try to deduplicate when possible to avoid
|
self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
|
||||||
// unnecessary ambiguity.
|
|
||||||
let mut distinct_normalized_bounds = FxHashSet::default();
|
|
||||||
|
|
||||||
bounds
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter_map(|(idx, bound)| {
|
|
||||||
let bound_predicate = bound.kind();
|
|
||||||
if let ty::ClauseKind::Trait(pred) = bound_predicate.skip_binder() {
|
|
||||||
let bound = bound_predicate.rebind(pred.trait_ref);
|
|
||||||
if self.infcx.probe(|_| {
|
|
||||||
match self.match_normalize_trait_ref(
|
|
||||||
obligation,
|
|
||||||
bound,
|
|
||||||
placeholder_trait_predicate.trait_ref,
|
|
||||||
) {
|
|
||||||
Ok(None) => true,
|
|
||||||
Ok(Some(normalized_trait))
|
|
||||||
if distinct_normalized_bounds.insert(normalized_trait) =>
|
|
||||||
{
|
{
|
||||||
true
|
for_each(self, bound, idx)?;
|
||||||
|
idx += 1;
|
||||||
}
|
}
|
||||||
_ => false,
|
|
||||||
}
|
if kind == ty::Projection {
|
||||||
}) {
|
self_ty = alias_ty.self_ty();
|
||||||
return Some(idx);
|
} else {
|
||||||
|
return ControlFlow::Continue(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Equates the trait in `obligation` with trait bound. If the two traits
|
/// Equates the trait in `obligation` with trait bound. If the two traits
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// NOTE: rustc cannot currently handle bounds of the form `for<'a> <Foo as Bar<'a>>::Assoc: Baz`.
|
// check-pass
|
||||||
// This should hopefully be fixed with Chalk.
|
|
||||||
|
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
|
|
||||||
|
@ -24,9 +23,6 @@ impl<'a, 'b> Lam<&'a &'b u8> for L2 {
|
||||||
|
|
||||||
trait Case1 {
|
trait Case1 {
|
||||||
type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
|
type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
|
||||||
//~^ ERROR `<<Self as Case1>::C as Iterator>::Item` is not an iterator
|
|
||||||
//~| ERROR `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
|
|
||||||
//~| ERROR `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct S1;
|
pub struct S1;
|
||||||
|
@ -35,33 +31,17 @@ impl Case1 for S1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assume_case1<T: Case1>() {
|
fn assume_case1<T: Case1>() {
|
||||||
fn assert_a<_0, A>()
|
fn assert_c<_1, _2, C>()
|
||||||
where
|
|
||||||
A: Iterator<Item = _0>,
|
|
||||||
_0: Debug,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
assert_a::<_, T::A>();
|
|
||||||
|
|
||||||
fn assert_b<_0, B>()
|
|
||||||
where
|
|
||||||
B: Iterator<Item = _0>,
|
|
||||||
_0: 'static,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
assert_b::<_, T::B>();
|
|
||||||
|
|
||||||
fn assert_c<_0, _1, _2, C>()
|
|
||||||
where
|
where
|
||||||
C: Clone + Iterator<Item = _2>,
|
C: Clone + Iterator<Item = _2>,
|
||||||
_2: Send + Iterator<Item = _1>,
|
_2: Send + Iterator<Item = _1>,
|
||||||
_1: for<'a> Lam<&'a u8, App = _0>,
|
_1: for<'a> Lam<&'a u8>,
|
||||||
_0: Debug,
|
for<'a> <_1 as Lam<&'a u8>>::App: Debug,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
assert_c::<_, _, _, T::C>();
|
assert_c::<_, _, T::C>();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assume_case1(S1);
|
assume_case1::<S1>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
|
|
||||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:26:36
|
|
||||||
|
|
|
||||||
LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
|
|
||||||
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
|
|
||||||
|
|
|
||||||
= help: the trait `Send` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Send {
|
|
||||||
| ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` is not an iterator
|
|
||||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:26:43
|
|
||||||
|
|
|
||||||
LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<<Self as Case1>::C as Iterator>::Item` is not an iterator
|
|
||||||
|
|
|
||||||
= help: the trait `Iterator` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Iterator {
|
|
||||||
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
|
|
||||||
--> $DIR/bad-bounds-on-assoc-in-trait.rs:26:93
|
|
||||||
|
|
|
||||||
LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
|
|
||||||
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
|
|
||||||
|
|
|
||||||
= help: the trait `Sync` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Sync {
|
|
||||||
| ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -16,8 +18,6 @@ impl<'a, 'b> Lam<&'a &'b u8> for L2 { type App = u8; }
|
||||||
|
|
||||||
trait Case1 {
|
trait Case1 {
|
||||||
type A: Iterator<Item: Debug>;
|
type A: Iterator<Item: Debug>;
|
||||||
//~^ ERROR `<<Self as Case1>::A as Iterator>::Item` doesn't implement `Debug`
|
|
||||||
|
|
||||||
type B: Iterator<Item: 'static>;
|
type B: Iterator<Item: 'static>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ impl Case1 for S1 {
|
||||||
// bounds of `Out`, but trait selection can't find the bound since it applies
|
// bounds of `Out`, but trait selection can't find the bound since it applies
|
||||||
// to a type other than `Self::Out`.
|
// to a type other than `Self::Out`.
|
||||||
pub trait Foo { type Out: Baz<Assoc: Default>; }
|
pub trait Foo { type Out: Baz<Assoc: Default>; }
|
||||||
//~^ ERROR trait bound `<<Self as Foo>::Out as Baz>::Assoc: Default` is not satisfied
|
|
||||||
pub trait Baz { type Assoc; }
|
pub trait Baz { type Assoc; }
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
error[E0277]: `<<Self as Case1>::A as Iterator>::Item` doesn't implement `Debug`
|
|
||||||
--> $DIR/bounds-on-assoc-in-trait.rs:18:28
|
|
||||||
|
|
|
||||||
LL | type A: Iterator<Item: Debug>;
|
|
||||||
| ^^^^^ `<<Self as Case1>::A as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
|
||||||
|
|
|
||||||
= help: the trait `Debug` is not implemented for `<<Self as Case1>::A as Iterator>::Item`
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | trait Case1 where <<Self as Case1>::A as Iterator>::Item: Debug {
|
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `<<Self as Foo>::Out as Baz>::Assoc: Default` is not satisfied
|
|
||||||
--> $DIR/bounds-on-assoc-in-trait.rs:35:38
|
|
||||||
|
|
|
||||||
LL | pub trait Foo { type Out: Baz<Assoc: Default>; }
|
|
||||||
| ^^^^^^^ the trait `Default` is not implemented for `<<Self as Foo>::Out as Baz>::Assoc`
|
|
||||||
|
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | pub trait Foo where <<Self as Foo>::Out as Baz>::Assoc: Default { type Out: Baz<Assoc: Default>; }
|
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -251,13 +251,10 @@ where
|
||||||
trait TRA1 {
|
trait TRA1 {
|
||||||
type A: Iterator<Item: Copy, Item: Send>;
|
type A: Iterator<Item: Copy, Item: Send>;
|
||||||
//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
|
//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
|
||||||
//~| ERROR `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
|
|
||||||
//~| ERROR the trait bound `<<Self as TRA1>::A as Iterator>::Item: Copy` is not satisfied
|
|
||||||
}
|
}
|
||||||
trait TRA2 {
|
trait TRA2 {
|
||||||
type A: Iterator<Item: Copy, Item: Copy>;
|
type A: Iterator<Item: Copy, Item: Copy>;
|
||||||
//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
|
//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
|
||||||
//~| ERROR the trait bound `<<Self as TRA2>::A as Iterator>::Item: Copy` is not satisfied
|
|
||||||
}
|
}
|
||||||
trait TRA3 {
|
trait TRA3 {
|
||||||
type A: Iterator<Item: 'static, Item: 'static>;
|
type A: Iterator<Item: 'static, Item: 'static>;
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> {
|
||||||
| `Item` bound here first
|
| `Item` bound here first
|
||||||
|
|
||||||
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
||||||
--> $DIR/duplicate.rs:267:40
|
--> $DIR/duplicate.rs:264:40
|
||||||
|
|
|
|
||||||
LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
|
LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
|
||||||
| ---------- ^^^^^^^^^^ re-bound here
|
| ---------- ^^^^^^^^^^ re-bound here
|
||||||
|
@ -15,7 +15,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
|
||||||
| `Item` bound here first
|
| `Item` bound here first
|
||||||
|
|
||||||
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
||||||
--> $DIR/duplicate.rs:269:44
|
--> $DIR/duplicate.rs:266:44
|
||||||
|
|
|
|
||||||
LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
|
LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
|
||||||
| ---------- ^^^^^^^^^^ re-bound here
|
| ---------- ^^^^^^^^^^ re-bound here
|
||||||
|
@ -23,7 +23,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
|
||||||
| `Item` bound here first
|
| `Item` bound here first
|
||||||
|
|
||||||
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
||||||
--> $DIR/duplicate.rs:271:43
|
--> $DIR/duplicate.rs:268:43
|
||||||
|
|
|
|
||||||
LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
|
LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
|
||||||
| ------------- ^^^^^^^^^^^^^ re-bound here
|
| ------------- ^^^^^^^^^^^^^ re-bound here
|
||||||
|
@ -523,7 +523,7 @@ LL | type A: Iterator<Item: Copy, Item: Send>;
|
||||||
| `Item` bound here first
|
| `Item` bound here first
|
||||||
|
|
||||||
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
||||||
--> $DIR/duplicate.rs:258:34
|
--> $DIR/duplicate.rs:256:34
|
||||||
|
|
|
|
||||||
LL | type A: Iterator<Item: Copy, Item: Copy>;
|
LL | type A: Iterator<Item: Copy, Item: Copy>;
|
||||||
| ---------- ^^^^^^^^^^ re-bound here
|
| ---------- ^^^^^^^^^^ re-bound here
|
||||||
|
@ -531,7 +531,7 @@ LL | type A: Iterator<Item: Copy, Item: Copy>;
|
||||||
| `Item` bound here first
|
| `Item` bound here first
|
||||||
|
|
||||||
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
|
||||||
--> $DIR/duplicate.rs:263:37
|
--> $DIR/duplicate.rs:260:37
|
||||||
|
|
|
|
||||||
LL | type A: Iterator<Item: 'static, Item: 'static>;
|
LL | type A: Iterator<Item: 'static, Item: 'static>;
|
||||||
| ------------- ^^^^^^^^^^^^^ re-bound here
|
| ------------- ^^^^^^^^^^^^^ re-bound here
|
||||||
|
@ -631,41 +631,7 @@ LL | Self: Iterator<Item: 'static, Item: 'static>,
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0277]: the trait bound `<<Self as TRA1>::A as Iterator>::Item: Copy` is not satisfied
|
error: aborting due to 75 previous errors
|
||||||
--> $DIR/duplicate.rs:252:28
|
|
||||||
|
|
|
||||||
LL | type A: Iterator<Item: Copy, Item: Send>;
|
|
||||||
| ^^^^ the trait `Copy` is not implemented for `<<Self as TRA1>::A as Iterator>::Item`
|
|
||||||
|
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | trait TRA1 where <<Self as TRA1>::A as Iterator>::Item: Copy {
|
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
|
Some errors have detailed explanations: E0282, E0719.
|
||||||
--> $DIR/duplicate.rs:252:40
|
For more information about an error, try `rustc --explain E0282`.
|
||||||
|
|
|
||||||
LL | type A: Iterator<Item: Copy, Item: Send>;
|
|
||||||
| ^^^^ `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
|
|
||||||
|
|
|
||||||
= help: the trait `Send` is not implemented for `<<Self as TRA1>::A as Iterator>::Item`
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | trait TRA1 where <<Self as TRA1>::A as Iterator>::Item: Send {
|
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `<<Self as TRA2>::A as Iterator>::Item: Copy` is not satisfied
|
|
||||||
--> $DIR/duplicate.rs:258:28
|
|
||||||
|
|
|
||||||
LL | type A: Iterator<Item: Copy, Item: Copy>;
|
|
||||||
| ^^^^ the trait `Copy` is not implemented for `<<Self as TRA2>::A as Iterator>::Item`
|
|
||||||
|
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | trait TRA2 where <<Self as TRA2>::A as Iterator>::Item: Copy {
|
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 78 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0282, E0719.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -12,6 +12,10 @@ LL | trait X<'a>
|
||||||
LL | where
|
LL | where
|
||||||
LL | for<'b> <Self as X<'b>>::U: Clone,
|
LL | for<'b> <Self as X<'b>>::U: Clone,
|
||||||
| ^^^^^ required by this bound in `X`
|
| ^^^^^ required by this bound in `X`
|
||||||
|
help: consider further restricting the associated type
|
||||||
|
|
|
||||||
|
LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone {
|
||||||
|
| ++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
--> $DIR/normalizing-self-auto-trait-issue-109924.rs:7:12
|
--> $DIR/normalizing-self-auto-trait-issue-109924.rs:6:12
|
||||||
|
|
|
|
||||||
LL | #![feature(return_type_notation)]
|
LL | #![feature(return_type_notation)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -7,29 +7,5 @@ LL | #![feature(return_type_notation)]
|
||||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error[E0277]: `impl Future<Output = ()> { <_ as Foo>::bar() }` cannot be sent between threads safely
|
warning: 1 warning emitted
|
||||||
--> $DIR/normalizing-self-auto-trait-issue-109924.rs:22:11
|
|
||||||
|
|
|
||||||
LL | build(Bar);
|
|
||||||
| ----- ^^^ `impl Future<Output = ()> { <_ as Foo>::bar() }` cannot be sent between threads safely
|
|
||||||
| |
|
|
||||||
| required by a bound introduced by this call
|
|
||||||
|
|
|
||||||
= help: the trait `for<'a> Send` is not implemented for `impl Future<Output = ()> { <_ as Foo>::bar() }`
|
|
||||||
note: this is a known limitation of the trait solver that will be lifted in the future
|
|
||||||
--> $DIR/normalizing-self-auto-trait-issue-109924.rs:22:11
|
|
||||||
|
|
|
||||||
LL | build(Bar);
|
|
||||||
| ------^^^-
|
|
||||||
| | |
|
|
||||||
| | the trait solver is unable to infer the generic types that should be inferred from this argument
|
|
||||||
| add turbofish arguments to this call to specify the types manually, even if it's redundant
|
|
||||||
note: required by a bound in `build`
|
|
||||||
--> $DIR/normalizing-self-auto-trait-issue-109924.rs:19:39
|
|
||||||
|
|
|
||||||
LL | fn build<T>(_: T) where T: Foo<bar(): Send> {}
|
|
||||||
| ^^^^ required by this bound in `build`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
--> $DIR/normalizing-self-auto-trait-issue-109924.rs:7:12
|
--> $DIR/normalizing-self-auto-trait-issue-109924.rs:6:12
|
||||||
|
|
|
|
||||||
LL | #![feature(return_type_notation)]
|
LL | #![feature(return_type_notation)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
// check-pass
|
||||||
// revisions: current next
|
// revisions: current next
|
||||||
//[current] known-bug: #109924
|
|
||||||
//[next] check-pass
|
|
||||||
//[next] compile-flags: -Znext-solver
|
//[next] compile-flags: -Znext-solver
|
||||||
// edition:2021
|
// edition:2021
|
||||||
|
|
||||||
#![feature(return_type_notation)]
|
#![feature(return_type_notation)]
|
||||||
//[next]~^ WARN the feature `return_type_notation` is incomplete
|
//~^ WARN the feature `return_type_notation` is incomplete
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
||||||
async fn bar(&self);
|
async fn bar(&self);
|
||||||
|
|
|
@ -11,7 +11,6 @@ impl Tr1 for S1 { type As1 = S2; }
|
||||||
trait _Tr3 {
|
trait _Tr3 {
|
||||||
type A: Iterator<Item: Copy>;
|
type A: Iterator<Item: Copy>;
|
||||||
//~^ ERROR associated type bounds are unstable
|
//~^ ERROR associated type bounds are unstable
|
||||||
//~| ERROR the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
|
|
||||||
|
|
||||||
type B: Iterator<Item: 'static>;
|
type B: Iterator<Item: 'static>;
|
||||||
//~^ ERROR associated type bounds are unstable
|
//~^ ERROR associated type bounds are unstable
|
||||||
|
|
|
@ -9,7 +9,7 @@ LL | type A: Iterator<Item: Copy>;
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:16:22
|
--> $DIR/feature-gate-associated_type_bounds.rs:15:22
|
||||||
|
|
|
|
||||||
LL | type B: Iterator<Item: 'static>;
|
LL | type B: Iterator<Item: 'static>;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -19,7 +19,7 @@ LL | type B: Iterator<Item: 'static>;
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:20:20
|
--> $DIR/feature-gate-associated_type_bounds.rs:19:20
|
||||||
|
|
|
|
||||||
LL | struct _St1<T: Tr1<As1: Tr2>> {
|
LL | struct _St1<T: Tr1<As1: Tr2>> {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -29,7 +29,7 @@ LL | struct _St1<T: Tr1<As1: Tr2>> {
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:27:18
|
--> $DIR/feature-gate-associated_type_bounds.rs:26:18
|
||||||
|
|
|
|
||||||
LL | enum _En1<T: Tr1<As1: Tr2>> {
|
LL | enum _En1<T: Tr1<As1: Tr2>> {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -39,7 +39,7 @@ LL | enum _En1<T: Tr1<As1: Tr2>> {
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:34:19
|
--> $DIR/feature-gate-associated_type_bounds.rs:33:19
|
||||||
|
|
|
|
||||||
LL | union _Un1<T: Tr1<As1: Tr2>> {
|
LL | union _Un1<T: Tr1<As1: Tr2>> {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -49,7 +49,7 @@ LL | union _Un1<T: Tr1<As1: Tr2>> {
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:41:37
|
--> $DIR/feature-gate-associated_type_bounds.rs:40:37
|
||||||
|
|
|
|
||||||
LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
|
LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -59,7 +59,7 @@ LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:44:22
|
--> $DIR/feature-gate-associated_type_bounds.rs:43:22
|
||||||
|
|
|
|
||||||
LL | fn _apit(_: impl Tr1<As1: Copy>) {}
|
LL | fn _apit(_: impl Tr1<As1: Copy>) {}
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -69,7 +69,7 @@ LL | fn _apit(_: impl Tr1<As1: Copy>) {}
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:46:26
|
--> $DIR/feature-gate-associated_type_bounds.rs:45:26
|
||||||
|
|
|
|
||||||
LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
|
LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -79,7 +79,7 @@ LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:49:24
|
--> $DIR/feature-gate-associated_type_bounds.rs:48:24
|
||||||
|
|
|
|
||||||
LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
|
LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -89,7 +89,7 @@ LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:52:31
|
--> $DIR/feature-gate-associated_type_bounds.rs:51:31
|
||||||
|
|
|
|
||||||
LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
|
LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -99,7 +99,7 @@ LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:55:23
|
--> $DIR/feature-gate-associated_type_bounds.rs:54:23
|
||||||
|
|
|
|
||||||
LL | const _cdef: impl Tr1<As1: Copy> = S1;
|
LL | const _cdef: impl Tr1<As1: Copy> = S1;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -109,7 +109,7 @@ LL | const _cdef: impl Tr1<As1: Copy> = S1;
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:61:24
|
--> $DIR/feature-gate-associated_type_bounds.rs:60:24
|
||||||
|
|
|
|
||||||
LL | static _sdef: impl Tr1<As1: Copy> = S1;
|
LL | static _sdef: impl Tr1<As1: Copy> = S1;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -119,7 +119,7 @@ LL | static _sdef: impl Tr1<As1: Copy> = S1;
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:68:21
|
--> $DIR/feature-gate-associated_type_bounds.rs:67:21
|
||||||
|
|
|
|
||||||
LL | let _: impl Tr1<As1: Copy> = S1;
|
LL | let _: impl Tr1<As1: Copy> = S1;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -129,7 +129,7 @@ LL | let _: impl Tr1<As1: Copy> = S1;
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0562]: `impl Trait` is not allowed in const types
|
error[E0562]: `impl Trait` is not allowed in const types
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:55:14
|
--> $DIR/feature-gate-associated_type_bounds.rs:54:14
|
||||||
|
|
|
|
||||||
LL | const _cdef: impl Tr1<As1: Copy> = S1;
|
LL | const _cdef: impl Tr1<As1: Copy> = S1;
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -137,7 +137,7 @@ LL | const _cdef: impl Tr1<As1: Copy> = S1;
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0562]: `impl Trait` is not allowed in static types
|
error[E0562]: `impl Trait` is not allowed in static types
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:61:15
|
--> $DIR/feature-gate-associated_type_bounds.rs:60:15
|
||||||
|
|
|
|
||||||
LL | static _sdef: impl Tr1<As1: Copy> = S1;
|
LL | static _sdef: impl Tr1<As1: Copy> = S1;
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -145,25 +145,14 @@ LL | static _sdef: impl Tr1<As1: Copy> = S1;
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
|
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:68:12
|
--> $DIR/feature-gate-associated_type_bounds.rs:67:12
|
||||||
|
|
|
|
||||||
LL | let _: impl Tr1<As1: Copy> = S1;
|
LL | let _: impl Tr1<As1: Copy> = S1;
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0277]: the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
|
error: aborting due to 16 previous errors
|
||||||
--> $DIR/feature-gate-associated_type_bounds.rs:12:28
|
|
||||||
|
|
|
||||||
LL | type A: Iterator<Item: Copy>;
|
|
||||||
| ^^^^ the trait `Copy` is not implemented for `<<Self as _Tr3>::A as Iterator>::Item`
|
|
||||||
|
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | trait _Tr3 where <<Self as _Tr3>::A as Iterator>::Item: Copy {
|
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 17 previous errors
|
Some errors have detailed explanations: E0562, E0658.
|
||||||
|
For more information about an error, try `rustc --explain E0562`.
|
||||||
Some errors have detailed explanations: E0277, E0562, E0658.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
// check-fail
|
// check-pass
|
||||||
// known-bug: #88460
|
|
||||||
|
|
||||||
// This should pass, but has a missed normalization due to HRTB.
|
|
||||||
|
|
||||||
pub trait Marker {}
|
pub trait Marker {}
|
||||||
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
|
|
||||||
--> $DIR/issue-88460.rs:28:10
|
|
||||||
|
|
|
||||||
LL | test(Foo);
|
|
||||||
| ---- ^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
|
|
||||||
| |
|
|
||||||
| required by a bound introduced by this call
|
|
||||||
|
|
|
||||||
= help: the trait `Marker` is implemented for `()`
|
|
||||||
note: this is a known limitation of the trait solver that will be lifted in the future
|
|
||||||
--> $DIR/issue-88460.rs:28:10
|
|
||||||
|
|
|
||||||
LL | test(Foo);
|
|
||||||
| -----^^^-
|
|
||||||
| | |
|
|
||||||
| | the trait solver is unable to infer the generic types that should be inferred from this argument
|
|
||||||
| add turbofish arguments to this call to specify the types manually, even if it's redundant
|
|
||||||
note: required by a bound in `test`
|
|
||||||
--> $DIR/issue-88460.rs:15:27
|
|
||||||
|
|
|
||||||
LL | fn test<T>(value: T)
|
|
||||||
| ---- required by a bound in this function
|
|
||||||
...
|
|
||||||
LL | for<'a> T::Assoc<'a>: Marker,
|
|
||||||
| ^^^^^^ required by this bound in `test`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,5 +1,4 @@
|
||||||
// check-fail
|
// check-pass
|
||||||
// known-bug: #90950
|
|
||||||
|
|
||||||
trait Yokeable<'a>: 'static {
|
trait Yokeable<'a>: 'static {
|
||||||
type Output: 'a;
|
type Output: 'a;
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
error[E0277]: the trait bound `for<'a> <_ as Yokeable<'a>>::Output: IsCovariant<'a>` is not satisfied
|
|
||||||
--> $DIR/issue-90950.rs:50:12
|
|
||||||
|
|
|
||||||
LL | upcast(y)
|
|
||||||
| ------ ^ the trait `for<'a> IsCovariant<'a>` is not implemented for `<_ as Yokeable<'a>>::Output`
|
|
||||||
| |
|
|
||||||
| required by a bound introduced by this call
|
|
||||||
|
|
|
||||||
= help: the trait `IsCovariant<'a>` is implemented for `std::borrow::Cow<'a, T>`
|
|
||||||
note: this is a known limitation of the trait solver that will be lifted in the future
|
|
||||||
--> $DIR/issue-90950.rs:50:12
|
|
||||||
|
|
|
||||||
LL | upcast(y)
|
|
||||||
| -------^-
|
|
||||||
| | |
|
|
||||||
| | the trait solver is unable to infer the generic types that should be inferred from this argument
|
|
||||||
| add turbofish arguments to this call to specify the types manually, even if it's redundant
|
|
||||||
note: required by a bound in `upcast`
|
|
||||||
--> $DIR/issue-90950.rs:27:42
|
|
||||||
|
|
|
||||||
LL | fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where
|
|
||||||
| ------ required by a bound in this function
|
|
||||||
LL | Y: for<'a> Yokeable<'a>,
|
|
||||||
LL | for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a>
|
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `upcast`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,5 +1,4 @@
|
||||||
// check-fail
|
// check-pass
|
||||||
// known-bug: #89196
|
|
||||||
|
|
||||||
// Should pass, but we normalize and check bounds before we resolve the generics
|
// Should pass, but we normalize and check bounds before we resolve the generics
|
||||||
// of the function (which we know because of the return type).
|
// of the function (which we know because of the return type).
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satisfied
|
|
||||||
--> $DIR/norm-before-method-resolution.rs:22:17
|
|
||||||
|
|
|
||||||
LL | let _: () = weird_bound();
|
|
||||||
| ^^^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out`
|
|
||||||
|
|
|
||||||
note: this is a known limitation of the trait solver that will be lifted in the future
|
|
||||||
--> $DIR/norm-before-method-resolution.rs:22:17
|
|
||||||
|
|
|
||||||
LL | let _: () = weird_bound();
|
|
||||||
| ^^^^^^^^^^^^^ try adding turbofish arguments to this expression to specify the types manually, even if it's redundant
|
|
||||||
note: required by a bound in `weird_bound`
|
|
||||||
--> $DIR/norm-before-method-resolution.rs:18:40
|
|
||||||
|
|
|
||||||
LL | fn weird_bound<X>() -> X
|
|
||||||
| ----------- required by a bound in this function
|
|
||||||
...
|
|
||||||
LL | for<'a> <X as Trait<'a>>::Out: Copy
|
|
||||||
| ^^^^ required by this bound in `weird_bound`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
Loading…
Add table
Add a link
Reference in a new issue