mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 22:46:50 +00:00
Auto merge of #91030 - estebank:trait-bounds-are-tricky-2, r=oli-obk
Properly track `ImplObligations` Instead of probing for all possible `impl`s that could have caused an `ImplObligation`, keep track of its `DefId` and obligation spans for accurate error reporting. Follow to #89580. Addresses #89418.
This commit is contained in:
commit
d2df372bca
@ -31,7 +31,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
// about the original obligation only.
|
||||
let code = match cause.code() {
|
||||
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => &*parent_code,
|
||||
_ => cause.code(),
|
||||
code => code,
|
||||
};
|
||||
let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else {
|
||||
return None;
|
||||
|
@ -257,7 +257,7 @@ pub enum ObligationCauseCode<'tcx> {
|
||||
|
||||
BuiltinDerivedObligation(DerivedObligationCause<'tcx>),
|
||||
|
||||
ImplDerivedObligation(DerivedObligationCause<'tcx>),
|
||||
ImplDerivedObligation(Box<ImplDerivedObligationCause<'tcx>>),
|
||||
|
||||
DerivedObligation(DerivedObligationCause<'tcx>),
|
||||
|
||||
@ -396,16 +396,29 @@ pub enum WellFormedLoc {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
|
||||
pub struct ImplDerivedObligationCause<'tcx> {
|
||||
pub derived: DerivedObligationCause<'tcx>,
|
||||
pub impl_def_id: DefId,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl ObligationCauseCode<'_> {
|
||||
// Return the base obligation, ignoring derived obligations.
|
||||
pub fn peel_derives(&self) -> &Self {
|
||||
let mut base_cause = self;
|
||||
while let BuiltinDerivedObligation(DerivedObligationCause { parent_code, .. })
|
||||
| ImplDerivedObligation(DerivedObligationCause { parent_code, .. })
|
||||
| DerivedObligation(DerivedObligationCause { parent_code, .. })
|
||||
| FunctionArgumentObligation { parent_code, .. } = base_cause
|
||||
{
|
||||
base_cause = &parent_code;
|
||||
loop {
|
||||
match base_cause {
|
||||
BuiltinDerivedObligation(DerivedObligationCause { parent_code, .. })
|
||||
| DerivedObligation(DerivedObligationCause { parent_code, .. })
|
||||
| FunctionArgumentObligation { parent_code, .. } => {
|
||||
base_cause = &parent_code;
|
||||
}
|
||||
ImplDerivedObligation(obligation_cause) => {
|
||||
base_cause = &*obligation_cause.derived.parent_code;
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
base_cause
|
||||
}
|
||||
|
@ -507,8 +507,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
let body_id = obligation.cause.body_id;
|
||||
let span = obligation.cause.span;
|
||||
let real_trait_pred = match &*code {
|
||||
ObligationCauseCode::ImplDerivedObligation(cause)
|
||||
| ObligationCauseCode::DerivedObligation(cause)
|
||||
ObligationCauseCode::ImplDerivedObligation(cause) => cause.derived.parent_trait_pred,
|
||||
ObligationCauseCode::DerivedObligation(cause)
|
||||
| ObligationCauseCode::BuiltinDerivedObligation(cause) => cause.parent_trait_pred,
|
||||
_ => trait_pred,
|
||||
};
|
||||
@ -790,8 +790,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
return false;
|
||||
};
|
||||
|
||||
if let ObligationCauseCode::ImplDerivedObligation(obligation) = code {
|
||||
try_borrowing(obligation.parent_trait_pred, &[])
|
||||
if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code {
|
||||
try_borrowing(cause.derived.parent_trait_pred, &[])
|
||||
} else if let ObligationCauseCode::BindingObligation(_, _)
|
||||
| ObligationCauseCode::ItemObligation(_) = code
|
||||
{
|
||||
@ -1433,13 +1433,43 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
|
||||
next_code = Some(parent_code.as_ref());
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedObligation(cause) => {
|
||||
let ty = cause.derived.parent_trait_pred.skip_binder().self_ty();
|
||||
debug!(
|
||||
"maybe_note_obligation_cause_for_async_await: ImplDerived \
|
||||
parent_trait_ref={:?} self_ty.kind={:?}",
|
||||
cause.derived.parent_trait_pred,
|
||||
ty.kind()
|
||||
);
|
||||
|
||||
match *ty.kind() {
|
||||
ty::Generator(did, ..) => {
|
||||
generator = generator.or(Some(did));
|
||||
outer_generator = Some(did);
|
||||
}
|
||||
ty::GeneratorWitness(..) => {}
|
||||
ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
|
||||
// By introducing a tuple of upvar types into the chain of obligations
|
||||
// of a generator, the first non-generator item is now the tuple itself,
|
||||
// we shall ignore this.
|
||||
|
||||
seen_upvar_tys_infer_tuple = true;
|
||||
}
|
||||
_ if generator.is_none() => {
|
||||
trait_ref = Some(cause.derived.parent_trait_pred.skip_binder());
|
||||
target_ty = Some(ty);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
next_code = Some(cause.derived.parent_code.as_ref());
|
||||
}
|
||||
ObligationCauseCode::DerivedObligation(derived_obligation)
|
||||
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
|
||||
| ObligationCauseCode::ImplDerivedObligation(derived_obligation) => {
|
||||
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) => {
|
||||
let ty = derived_obligation.parent_trait_pred.skip_binder().self_ty();
|
||||
debug!(
|
||||
"maybe_note_obligation_cause_for_async_await: \
|
||||
parent_trait_ref={:?} self_ty.kind={:?}",
|
||||
parent_trait_ref={:?} self_ty.kind={:?}",
|
||||
derived_obligation.parent_trait_pred,
|
||||
ty.kind()
|
||||
);
|
||||
@ -2166,7 +2196,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedObligation(ref data) => {
|
||||
let mut parent_trait_pred = self.resolve_vars_if_possible(data.parent_trait_pred);
|
||||
let mut parent_trait_pred =
|
||||
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
|
||||
parent_trait_pred.remap_constness_diag(param_env);
|
||||
let parent_def_id = parent_trait_pred.def_id();
|
||||
let msg = format!(
|
||||
@ -2174,51 +2205,63 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
parent_trait_pred.print_modifiers_and_trait_path(),
|
||||
parent_trait_pred.skip_binder().self_ty()
|
||||
);
|
||||
let mut candidates = vec![];
|
||||
self.tcx.for_each_relevant_impl(
|
||||
parent_def_id,
|
||||
parent_trait_pred.self_ty().skip_binder(),
|
||||
|impl_def_id| match self.tcx.hir().get_if_local(impl_def_id) {
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { .. }),
|
||||
..
|
||||
})) => {
|
||||
candidates.push(impl_def_id);
|
||||
let mut is_auto_trait = false;
|
||||
match self.tcx.hir().get_if_local(data.impl_def_id) {
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Trait(is_auto, ..),
|
||||
ident,
|
||||
..
|
||||
})) => {
|
||||
// FIXME: we should do something else so that it works even on crate foreign
|
||||
// auto traits.
|
||||
is_auto_trait = matches!(is_auto, hir::IsAuto::Yes);
|
||||
err.span_note(ident.span, &msg)
|
||||
}
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
|
||||
..
|
||||
})) => {
|
||||
let mut spans = Vec::with_capacity(2);
|
||||
if let Some(trait_ref) = of_trait {
|
||||
spans.push(trait_ref.path.span);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
);
|
||||
match &candidates[..] {
|
||||
[def_id] => match self.tcx.hir().get_if_local(*def_id) {
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
|
||||
..
|
||||
})) => {
|
||||
let mut spans = Vec::with_capacity(2);
|
||||
if let Some(trait_ref) = of_trait {
|
||||
spans.push(trait_ref.path.span);
|
||||
}
|
||||
spans.push(self_ty.span);
|
||||
err.span_note(spans, &msg)
|
||||
}
|
||||
_ => err.note(&msg),
|
||||
},
|
||||
spans.push(self_ty.span);
|
||||
err.span_note(spans, &msg)
|
||||
}
|
||||
_ => err.note(&msg),
|
||||
};
|
||||
|
||||
let mut parent_predicate = parent_trait_pred.to_predicate(tcx);
|
||||
let mut data = data;
|
||||
let mut data = &data.derived;
|
||||
let mut count = 0;
|
||||
seen_requirements.insert(parent_def_id);
|
||||
if is_auto_trait {
|
||||
// We don't want to point at the ADT saying "required because it appears within
|
||||
// the type `X`", like we would otherwise do in test `supertrait-auto-trait.rs`.
|
||||
while let ObligationCauseCode::BuiltinDerivedObligation(derived) =
|
||||
&*data.parent_code
|
||||
{
|
||||
let child_trait_ref =
|
||||
self.resolve_vars_if_possible(derived.parent_trait_pred);
|
||||
let child_def_id = child_trait_ref.def_id();
|
||||
if seen_requirements.insert(child_def_id) {
|
||||
break;
|
||||
}
|
||||
data = derived;
|
||||
parent_predicate = child_trait_ref.to_predicate(tcx);
|
||||
parent_trait_pred = child_trait_ref;
|
||||
}
|
||||
}
|
||||
while let ObligationCauseCode::ImplDerivedObligation(child) = &*data.parent_code {
|
||||
// Skip redundant recursive obligation notes. See `ui/issue-20413.rs`.
|
||||
let child_trait_pred = self.resolve_vars_if_possible(child.parent_trait_pred);
|
||||
let child_trait_pred =
|
||||
self.resolve_vars_if_possible(child.derived.parent_trait_pred);
|
||||
let child_def_id = child_trait_pred.def_id();
|
||||
if seen_requirements.insert(child_def_id) {
|
||||
break;
|
||||
}
|
||||
count += 1;
|
||||
data = child;
|
||||
data = &child.derived;
|
||||
parent_predicate = child_trait_pred.to_predicate(tcx);
|
||||
parent_trait_pred = child_trait_pred;
|
||||
}
|
||||
|
@ -18,24 +18,17 @@ use rustc_span::def_id::DefId;
|
||||
|
||||
use crate::traits::project::{normalize_with_depth, normalize_with_depth_to};
|
||||
use crate::traits::select::TraitObligationExt;
|
||||
use crate::traits::util;
|
||||
use crate::traits::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
|
||||
use crate::traits::ImplSource;
|
||||
use crate::traits::Normalized;
|
||||
use crate::traits::OutputTypeParameterMismatch;
|
||||
use crate::traits::Selection;
|
||||
use crate::traits::TraitNotObjectSafe;
|
||||
use crate::traits::VtblSegment;
|
||||
use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation};
|
||||
use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for_trait_def};
|
||||
use crate::traits::{
|
||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||
ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
||||
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData,
|
||||
BuiltinDerivedObligation, DerivedObligationCause, ImplDerivedObligation,
|
||||
ImplDerivedObligationCause, ImplSource, ImplSourceAutoImplData, ImplSourceBuiltinData,
|
||||
ImplSourceClosureData, ImplSourceConstDestructData, ImplSourceDiscriminantKindData,
|
||||
ImplSourceFnPointerData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData,
|
||||
ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
|
||||
ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch,
|
||||
PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, TraitObligation,
|
||||
Unimplemented, VtblSegment,
|
||||
};
|
||||
use crate::traits::{ObjectCastObligation, PredicateObligation, TraitObligation};
|
||||
use crate::traits::{Obligation, ObligationCause};
|
||||
use crate::traits::{SelectionError, Unimplemented};
|
||||
|
||||
use super::BuiltinImplConditions;
|
||||
use super::SelectionCandidate::{self, *};
|
||||
@ -321,6 +314,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
debug!(?nested, "vtable_auto_impl");
|
||||
ensure_sufficient_stack(|| {
|
||||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||
|
||||
let trait_obligations: Vec<PredicateObligation<'_>> =
|
||||
self.infcx.commit_unconditionally(|_| {
|
||||
let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
|
||||
let trait_ref = self.infcx.replace_bound_vars_with_placeholders(poly_trait_ref);
|
||||
self.impl_or_trait_obligations(
|
||||
&cause,
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
trait_def_id,
|
||||
&trait_ref.substs,
|
||||
obligation.predicate,
|
||||
)
|
||||
});
|
||||
|
||||
let mut obligations = self.collect_predicates_for_types(
|
||||
obligation.param_env,
|
||||
cause,
|
||||
@ -329,20 +337,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
nested,
|
||||
);
|
||||
|
||||
let trait_obligations: Vec<PredicateObligation<'_>> =
|
||||
self.infcx.commit_unconditionally(|_| {
|
||||
let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
|
||||
let trait_ref = self.infcx.replace_bound_vars_with_placeholders(poly_trait_ref);
|
||||
let cause = obligation.derived_cause(ImplDerivedObligation);
|
||||
self.impl_or_trait_obligations(
|
||||
cause,
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
trait_def_id,
|
||||
&trait_ref.substs,
|
||||
)
|
||||
});
|
||||
|
||||
// Adds the predicates from the trait. Note that this contains a `Self: Trait`
|
||||
// predicate as usual. It won't have any effect since auto traits are coinductive.
|
||||
obligations.extend(trait_obligations);
|
||||
@ -365,14 +359,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
self.infcx.commit_unconditionally(|_| {
|
||||
let substs = self.rematch_impl(impl_def_id, obligation);
|
||||
debug!(?substs, "impl substs");
|
||||
let cause = obligation.derived_cause(ImplDerivedObligation);
|
||||
ensure_sufficient_stack(|| {
|
||||
self.vtable_impl(
|
||||
impl_def_id,
|
||||
substs,
|
||||
cause,
|
||||
&obligation.cause,
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
obligation.predicate,
|
||||
)
|
||||
})
|
||||
})
|
||||
@ -382,9 +376,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&mut self,
|
||||
impl_def_id: DefId,
|
||||
substs: Normalized<'tcx, SubstsRef<'tcx>>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
recursion_depth: usize,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
|
||||
) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
|
||||
debug!(?impl_def_id, ?substs, ?recursion_depth, "vtable_impl");
|
||||
|
||||
@ -394,6 +389,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
param_env,
|
||||
impl_def_id,
|
||||
&substs.value,
|
||||
parent_trait_pred,
|
||||
);
|
||||
|
||||
debug!(?impl_obligations, "vtable_impl");
|
||||
@ -566,11 +562,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let substs = trait_ref.substs;
|
||||
|
||||
let trait_obligations = self.impl_or_trait_obligations(
|
||||
obligation.cause.clone(),
|
||||
&obligation.cause,
|
||||
obligation.recursion_depth,
|
||||
obligation.param_env,
|
||||
trait_def_id,
|
||||
&substs,
|
||||
obligation.predicate,
|
||||
);
|
||||
|
||||
debug!(?trait_def_id, ?trait_obligations, "trait alias obligations");
|
||||
@ -1073,14 +1070,30 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
});
|
||||
let substs = self.rematch_impl(impl_def_id, &new_obligation);
|
||||
debug!(?substs, "impl substs");
|
||||
let cause = obligation.derived_cause(ImplDerivedObligation);
|
||||
|
||||
let derived = DerivedObligationCause {
|
||||
parent_trait_pred: obligation.predicate,
|
||||
parent_code: obligation.cause.clone_code(),
|
||||
};
|
||||
let derived_code = ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_def_id,
|
||||
span: obligation.cause.span,
|
||||
}));
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
derived_code,
|
||||
);
|
||||
ensure_sufficient_stack(|| {
|
||||
self.vtable_impl(
|
||||
impl_def_id,
|
||||
substs,
|
||||
cause,
|
||||
&cause,
|
||||
new_obligation.recursion_depth + 1,
|
||||
new_obligation.param_env,
|
||||
obligation.predicate,
|
||||
)
|
||||
})
|
||||
});
|
||||
|
@ -13,15 +13,11 @@ use super::project::ProjectionTyObligation;
|
||||
use super::util;
|
||||
use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
|
||||
use super::wf;
|
||||
use super::DerivedObligationCause;
|
||||
use super::Normalized;
|
||||
use super::Obligation;
|
||||
use super::ObligationCauseCode;
|
||||
use super::Selection;
|
||||
use super::SelectionResult;
|
||||
use super::TraitQueryMode;
|
||||
use super::{ErrorReporting, Overflow, SelectionError};
|
||||
use super::{ObligationCause, PredicateObligation, TraitObligation};
|
||||
use super::{
|
||||
DerivedObligationCause, ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause,
|
||||
Normalized, Obligation, ObligationCause, ObligationCauseCode, Overflow, PredicateObligation,
|
||||
Selection, SelectionError, SelectionResult, TraitObligation, TraitQueryMode,
|
||||
};
|
||||
|
||||
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
||||
use crate::traits::error_reporting::InferCtxtExt;
|
||||
@ -2333,11 +2329,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
#[tracing::instrument(level = "debug", skip(self, cause, param_env))]
|
||||
fn impl_or_trait_obligations(
|
||||
&mut self,
|
||||
cause: ObligationCause<'tcx>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
recursion_depth: usize,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId, // of impl or trait
|
||||
substs: SubstsRef<'tcx>, // for impl or trait
|
||||
parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
|
||||
) -> Vec<PredicateObligation<'tcx>> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
@ -2359,8 +2356,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
debug!(?predicates);
|
||||
assert_eq!(predicates.parent, None);
|
||||
let mut obligations = Vec::with_capacity(predicates.predicates.len());
|
||||
for (predicate, _) in predicates.predicates {
|
||||
debug!(?predicate);
|
||||
let parent_code = cause.clone_code();
|
||||
for (predicate, span) in predicates.predicates {
|
||||
let span = *span;
|
||||
let derived =
|
||||
DerivedObligationCause { parent_trait_pred, parent_code: parent_code.clone() };
|
||||
let code = ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_def_id: def_id,
|
||||
span,
|
||||
}));
|
||||
let cause = ObligationCause::new(cause.span, cause.body_id, code);
|
||||
let predicate = normalize_with_depth_to(
|
||||
self,
|
||||
param_env,
|
||||
@ -2369,12 +2375,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
predicate.subst(tcx, substs),
|
||||
&mut obligations,
|
||||
);
|
||||
obligations.push(Obligation {
|
||||
cause: cause.clone(),
|
||||
recursion_depth,
|
||||
param_env,
|
||||
predicate,
|
||||
});
|
||||
obligations.push(Obligation { cause, recursion_depth, param_env, predicate });
|
||||
}
|
||||
|
||||
obligations
|
||||
|
@ -227,8 +227,14 @@ fn compare_predicate_entailment<'tcx>(
|
||||
traits::normalize(&mut selcx, param_env, normalize_cause, predicate);
|
||||
|
||||
inh.register_predicates(obligations);
|
||||
let mut cause = cause.clone();
|
||||
cause.span = span;
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
impl_m_hir_id,
|
||||
ObligationCauseCode::CompareImplMethodObligation {
|
||||
impl_item_def_id: impl_m.def_id,
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
},
|
||||
);
|
||||
inh.register_predicate(traits::Obligation::new(cause, param_env, predicate));
|
||||
}
|
||||
|
||||
|
@ -1087,8 +1087,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let mut result_code = code.clone();
|
||||
loop {
|
||||
let parent = match &*code {
|
||||
ObligationCauseCode::ImplDerivedObligation(c) => {
|
||||
c.derived.parent_code.clone()
|
||||
}
|
||||
ObligationCauseCode::BuiltinDerivedObligation(c)
|
||||
| ObligationCauseCode::ImplDerivedObligation(c)
|
||||
| ObligationCauseCode::DerivedObligation(c) => c.parent_code.clone(),
|
||||
_ => break,
|
||||
};
|
||||
@ -1098,10 +1100,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
let self_: ty::subst::GenericArg<'_> = match &*unpeel_to_top(error.obligation.cause.clone_code()) {
|
||||
ObligationCauseCode::BuiltinDerivedObligation(code) |
|
||||
ObligationCauseCode::ImplDerivedObligation(code) |
|
||||
ObligationCauseCode::DerivedObligation(code) => {
|
||||
code.parent_trait_pred.self_ty().skip_binder().into()
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedObligation(code) => {
|
||||
code.derived.parent_trait_pred.self_ty().skip_binder().into()
|
||||
}
|
||||
_ if let ty::PredicateKind::Trait(predicate) =
|
||||
error.obligation.predicate.kind().skip_binder() => {
|
||||
predicate.self_ty().into()
|
||||
|
@ -1521,6 +1521,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
let selcx = &mut traits::SelectionContext::new(self);
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
|
||||
let mut parent_pred = None;
|
||||
|
||||
// If so, impls may carry other conditions (e.g., where
|
||||
// clauses) that must be considered. Make sure that those
|
||||
// match as well (or at least may match, sometimes we
|
||||
@ -1584,6 +1586,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
let predicate =
|
||||
ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx);
|
||||
parent_pred = Some(predicate);
|
||||
let obligation = traits::Obligation::new(cause, self.param_env, predicate);
|
||||
if !self.predicate_may_hold(&obligation) {
|
||||
result = ProbeResult::NoMatch;
|
||||
@ -1639,7 +1642,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
let o = self.resolve_vars_if_possible(o);
|
||||
if !self.predicate_may_hold(&o) {
|
||||
result = ProbeResult::NoMatch;
|
||||
possibly_unsatisfied_predicates.push((o.predicate, None, Some(o.cause)));
|
||||
possibly_unsatisfied_predicates.push((o.predicate, parent_pred, Some(o.cause)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,8 @@ use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
|
||||
use rustc_middle::ty::print::with_crate_prefix;
|
||||
use rustc_middle::ty::ToPolyTraitRef;
|
||||
use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::lev_distance;
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{source_map, FileName, MultiSpan, Span};
|
||||
use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, MultiSpan, Span};
|
||||
use rustc_trait_selection::traits::error_reporting::on_unimplemented::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{
|
||||
@ -723,102 +722,190 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Find all the requirements that come from a local `impl` block.
|
||||
let mut skip_list: FxHashSet<_> = Default::default();
|
||||
let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
|
||||
for (data, p, parent_p) in unsatisfied_predicates
|
||||
for (data, p, parent_p, impl_def_id, cause_span) in unsatisfied_predicates
|
||||
.iter()
|
||||
.filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
|
||||
.filter_map(|(p, parent, c)| match c.code() {
|
||||
ObligationCauseCode::ImplDerivedObligation(ref data) => {
|
||||
Some((data, p, parent))
|
||||
Some((&data.derived, p, parent, data.impl_def_id, data.span))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
{
|
||||
let parent_trait_ref = data.parent_trait_pred;
|
||||
let parent_def_id = parent_trait_ref.def_id();
|
||||
let path = parent_trait_ref.print_modifiers_and_trait_path();
|
||||
let tr_self_ty = parent_trait_ref.skip_binder().self_ty();
|
||||
let mut candidates = vec![];
|
||||
self.tcx.for_each_relevant_impl(
|
||||
parent_def_id,
|
||||
parent_trait_ref.self_ty().skip_binder(),
|
||||
|impl_def_id| match self.tcx.hir().get_if_local(impl_def_id) {
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { .. }),
|
||||
..
|
||||
})) => {
|
||||
candidates.push(impl_def_id);
|
||||
let unsatisfied_msg = "unsatisfied trait bound introduced here".to_string();
|
||||
let derive_msg =
|
||||
"unsatisfied trait bound introduced in this `derive` macro";
|
||||
match self.tcx.hir().get_if_local(impl_def_id) {
|
||||
// Unmet obligation comes from a `derive` macro, point at it once to
|
||||
// avoid multiple span labels pointing at the same place.
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Trait(..),
|
||||
ident,
|
||||
..
|
||||
})) if matches!(
|
||||
ident.span.ctxt().outer_expn_data().kind,
|
||||
ExpnKind::Macro(MacroKind::Derive, _)
|
||||
) =>
|
||||
{
|
||||
let span = ident.span.ctxt().outer_expn_data().call_site;
|
||||
let mut spans: MultiSpan = span.into();
|
||||
spans.push_span_label(span, derive_msg.to_string());
|
||||
let entry = spanned_predicates.entry(spans);
|
||||
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
|
||||
}
|
||||
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
|
||||
..
|
||||
})) if matches!(
|
||||
self_ty.span.ctxt().outer_expn_data().kind,
|
||||
ExpnKind::Macro(MacroKind::Derive, _)
|
||||
) || matches!(
|
||||
of_trait.as_ref().map(|t| t
|
||||
.path
|
||||
.span
|
||||
.ctxt()
|
||||
.outer_expn_data()
|
||||
.kind),
|
||||
Some(ExpnKind::Macro(MacroKind::Derive, _))
|
||||
) =>
|
||||
{
|
||||
let span = self_ty.span.ctxt().outer_expn_data().call_site;
|
||||
let mut spans: MultiSpan = span.into();
|
||||
spans.push_span_label(span, derive_msg.to_string());
|
||||
let entry = spanned_predicates.entry(spans.into());
|
||||
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
|
||||
}
|
||||
|
||||
// Unmet obligation coming from a `trait`.
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Trait(..),
|
||||
ident,
|
||||
span: item_span,
|
||||
..
|
||||
})) if !matches!(
|
||||
ident.span.ctxt().outer_expn_data().kind,
|
||||
ExpnKind::Macro(MacroKind::Derive, _)
|
||||
) =>
|
||||
{
|
||||
if let Some(pred) = parent_p {
|
||||
// Done to add the "doesn't satisfy" `span_label`.
|
||||
let _ = format_pred(*pred);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
);
|
||||
if let [def_id] = &candidates[..] {
|
||||
match self.tcx.hir().get_if_local(*def_id) {
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
|
||||
..
|
||||
})) => {
|
||||
if let Some(pred) = parent_p {
|
||||
// Done to add the "doesn't satisfy" `span_label`.
|
||||
let _ = format_pred(*pred);
|
||||
}
|
||||
skip_list.insert(p);
|
||||
skip_list.insert(p);
|
||||
let mut spans = if cause_span != *item_span {
|
||||
let mut spans: MultiSpan = cause_span.into();
|
||||
spans.push_span_label(cause_span, unsatisfied_msg);
|
||||
spans
|
||||
} else {
|
||||
ident.span.into()
|
||||
};
|
||||
spans.push_span_label(ident.span, "in this trait".to_string());
|
||||
let entry = spanned_predicates.entry(spans.into());
|
||||
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
|
||||
}
|
||||
|
||||
// Unmet obligation coming from an `impl`.
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
|
||||
span: item_span,
|
||||
..
|
||||
})) if !matches!(
|
||||
self_ty.span.ctxt().outer_expn_data().kind,
|
||||
ExpnKind::Macro(MacroKind::Derive, _)
|
||||
) && !matches!(
|
||||
of_trait.as_ref().map(|t| t
|
||||
.path
|
||||
.span
|
||||
.ctxt()
|
||||
.outer_expn_data()
|
||||
.kind),
|
||||
Some(ExpnKind::Macro(MacroKind::Derive, _))
|
||||
) =>
|
||||
{
|
||||
if let Some(pred) = parent_p {
|
||||
// Done to add the "doesn't satisfy" `span_label`.
|
||||
let _ = format_pred(*pred);
|
||||
}
|
||||
skip_list.insert(p);
|
||||
let mut spans = if cause_span != *item_span {
|
||||
let mut spans: MultiSpan = cause_span.into();
|
||||
spans.push_span_label(cause_span, unsatisfied_msg);
|
||||
spans
|
||||
} else {
|
||||
let mut spans = Vec::with_capacity(2);
|
||||
if let Some(trait_ref) = of_trait {
|
||||
spans.push(trait_ref.path.span);
|
||||
}
|
||||
spans.push(self_ty.span);
|
||||
let entry = spanned_predicates.entry(spans.into());
|
||||
entry
|
||||
.or_insert_with(|| (path, tr_self_ty, Vec::new()))
|
||||
.2
|
||||
.push(p);
|
||||
spans.into()
|
||||
};
|
||||
if let Some(trait_ref) = of_trait {
|
||||
spans.push_span_label(trait_ref.path.span, String::new());
|
||||
}
|
||||
_ => {}
|
||||
spans.push_span_label(self_ty.span, String::new());
|
||||
|
||||
let entry = spanned_predicates.entry(spans.into());
|
||||
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
for (span, (path, self_ty, preds)) in spanned_predicates {
|
||||
err.span_note(
|
||||
span,
|
||||
&format!(
|
||||
"the following trait bounds were not satisfied because of the \
|
||||
requirements of the implementation of `{}` for `{}`:\n{}",
|
||||
path,
|
||||
self_ty,
|
||||
preds
|
||||
.into_iter()
|
||||
// .map(|pred| format!("{:?}", pred))
|
||||
.filter_map(|pred| format_pred(*pred))
|
||||
.map(|(p, _)| format!("`{}`", p))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n"),
|
||||
),
|
||||
);
|
||||
let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect();
|
||||
spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span());
|
||||
for (span, (_path, _self_ty, preds)) in spanned_predicates {
|
||||
let mut preds: Vec<_> = preds
|
||||
.into_iter()
|
||||
.filter_map(|pred| format_pred(*pred))
|
||||
.map(|(p, _)| format!("`{}`", p))
|
||||
.collect();
|
||||
preds.sort();
|
||||
preds.dedup();
|
||||
let msg = if let [pred] = &preds[..] {
|
||||
format!("trait bound {} was not satisfied", pred)
|
||||
} else {
|
||||
format!(
|
||||
"the following trait bounds were not satisfied:\n{}",
|
||||
preds.join("\n"),
|
||||
)
|
||||
};
|
||||
err.span_note(span, &msg);
|
||||
unsatisfied_bounds = true;
|
||||
}
|
||||
|
||||
// The requirements that didn't have an `impl` span to show.
|
||||
let mut bound_list = unsatisfied_predicates
|
||||
.iter()
|
||||
.filter(|(pred, _, _parent_pred)| !skip_list.contains(&pred))
|
||||
.filter_map(|(pred, parent_pred, _cause)| {
|
||||
format_pred(*pred).map(|(p, self_ty)| {
|
||||
collect_type_param_suggestions(self_ty, *pred, &p);
|
||||
match parent_pred {
|
||||
None => format!("`{}`", &p),
|
||||
Some(parent_pred) => match format_pred(*parent_pred) {
|
||||
(
|
||||
match parent_pred {
|
||||
None => format!("`{}`", &p),
|
||||
Some((parent_p, _)) => {
|
||||
collect_type_param_suggestions(
|
||||
self_ty,
|
||||
*parent_pred,
|
||||
&p,
|
||||
);
|
||||
format!("`{}`\nwhich is required by `{}`", p, parent_p)
|
||||
}
|
||||
Some(parent_pred) => match format_pred(*parent_pred) {
|
||||
None => format!("`{}`", &p),
|
||||
Some((parent_p, _)) => {
|
||||
collect_type_param_suggestions(
|
||||
self_ty,
|
||||
*parent_pred,
|
||||
&p,
|
||||
);
|
||||
format!(
|
||||
"`{}`\nwhich is required by `{}`",
|
||||
p, parent_p
|
||||
)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
*pred,
|
||||
)
|
||||
})
|
||||
})
|
||||
.filter(|(_, pred)| !skip_list.contains(&pred))
|
||||
.map(|(t, _)| t)
|
||||
.enumerate()
|
||||
.collect::<Vec<(usize, String)>>();
|
||||
|
||||
|
@ -58,6 +58,7 @@ This API is completely unstable and subject to change.
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(hash_drain_filter)]
|
||||
|
@ -13,16 +13,17 @@ LL | struct NotClone;
|
||||
LL | Bar::<NotClone> { x: 1 }.clone();
|
||||
| ^^^^^ method cannot be called on `Bar<NotClone>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied because of the requirements of the implementation of `Clone` for `_`:
|
||||
`NotClone: Clone`
|
||||
note: trait bound `NotClone: Clone` was not satisfied
|
||||
--> $DIR/derive-assoc-type-not-impl.rs:6:10
|
||||
|
|
||||
LL | #[derive(Clone)]
|
||||
| ^^^^^
|
||||
| ^^^^^ unsatisfied trait bound introduced in this `derive` macro
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`NotClone: Clone`
|
||||
which is required by `Bar<NotClone>: Clone`
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
= note: the following trait defines an item `clone`, perhaps you need to implement it:
|
||||
candidate #1: `Clone`
|
||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `NotClone` with `#[derive(Clone)]`
|
||||
|
|
||||
LL | #[derive(Clone)]
|
||||
|
@ -12,7 +12,10 @@ trait M {
|
||||
}
|
||||
|
||||
impl<T: X<Y<i32> = i32>> M for T {}
|
||||
//~^ NOTE the following trait bounds were not satisfied
|
||||
//~^ NOTE trait bound `<S as X>::Y<i32> = i32` was not satisfied
|
||||
//~| NOTE unsatisfied trait bound introduced here
|
||||
//~| NOTE
|
||||
//~| NOTE
|
||||
|
||||
struct S;
|
||||
//~^ NOTE method `f` not found for this
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
|
||||
--> $DIR/method-unsatified-assoc-type-predicate.rs:27:7
|
||||
--> $DIR/method-unsatified-assoc-type-predicate.rs:30:7
|
||||
|
|
||||
LL | struct S;
|
||||
| ---------
|
||||
@ -11,12 +11,13 @@ LL | struct S;
|
||||
LL | a.f();
|
||||
| ^ method cannot be called on `S` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied because of the requirements of the implementation of `M` for `_`:
|
||||
`<S as X>::Y<i32> = i32`
|
||||
--> $DIR/method-unsatified-assoc-type-predicate.rs:14:26
|
||||
note: trait bound `<S as X>::Y<i32> = i32` was not satisfied
|
||||
--> $DIR/method-unsatified-assoc-type-predicate.rs:14:11
|
||||
|
|
||||
LL | impl<T: X<Y<i32> = i32>> M for T {}
|
||||
| ^ ^
|
||||
| ^^^^^^^^^^^^ - -
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -10,14 +10,14 @@ LL | pub struct Map<S, F> {
|
||||
LL | let filter = map.filterx(|x: &_| true);
|
||||
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`:
|
||||
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
|
||||
note: the following trait bounds were not satisfied:
|
||||
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
|
||||
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
|
||||
--> $DIR/issue-30786.rs:105:9
|
||||
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
|
||||
--> $DIR/issue-30786.rs:105:50
|
||||
|
|
||||
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||
| ^^^^^^^^^ ^
|
||||
| --------- - ^^^^^^ unsatisfied trait bound introduced here
|
||||
|
||||
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-30786.rs:140:24
|
||||
@ -31,14 +31,14 @@ LL | pub struct Filter<S, F> {
|
||||
LL | let count = filter.countx();
|
||||
| ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`:
|
||||
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
|
||||
note: the following trait bounds were not satisfied:
|
||||
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
|
||||
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
|
||||
--> $DIR/issue-30786.rs:105:9
|
||||
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
|
||||
--> $DIR/issue-30786.rs:105:50
|
||||
|
|
||||
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||
| ^^^^^^^^^ ^
|
||||
| --------- - ^^^^^^ unsatisfied trait bound introduced here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -10,14 +10,14 @@ LL | pub struct Map<S, F> {
|
||||
LL | let filter = map.filterx(|x: &_| true);
|
||||
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`:
|
||||
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
|
||||
note: the following trait bounds were not satisfied:
|
||||
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
|
||||
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
|
||||
--> $DIR/issue-30786.rs:105:9
|
||||
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
|
||||
--> $DIR/issue-30786.rs:105:50
|
||||
|
|
||||
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||
| ^^^^^^^^^ ^
|
||||
| --------- - ^^^^^^ unsatisfied trait bound introduced here
|
||||
|
||||
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-30786.rs:140:24
|
||||
@ -31,14 +31,14 @@ LL | pub struct Filter<S, F> {
|
||||
LL | let count = filter.countx();
|
||||
| ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`:
|
||||
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
|
||||
note: the following trait bounds were not satisfied:
|
||||
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
|
||||
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
|
||||
--> $DIR/issue-30786.rs:105:9
|
||||
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
|
||||
--> $DIR/issue-30786.rs:105:50
|
||||
|
|
||||
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||
| ^^^^^^^^^ ^
|
||||
| --------- - ^^^^^^ unsatisfied trait bound introduced here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -7,11 +7,20 @@ LL | struct Foo<T> {
|
||||
LL | self.foo();
|
||||
| ^^^ method cannot be called on `&Foo<T>` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`T: Default`
|
||||
which is required by `Foo<T>: Bar`
|
||||
`T: Bar`
|
||||
which is required by `Foo<T>: Bar`
|
||||
note: trait bound `T: Default` was not satisfied
|
||||
--> $DIR/missing-trait-bounds-for-method-call.rs:10:9
|
||||
|
|
||||
LL | impl<T: Default + Bar> Bar for Foo<T> {}
|
||||
| ^^^^^^^ --- ------
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: trait bound `T: Bar` was not satisfied
|
||||
--> $DIR/missing-trait-bounds-for-method-call.rs:10:19
|
||||
|
|
||||
LL | impl<T: Default + Bar> Bar for Foo<T> {}
|
||||
| ^^^ --- ------
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
help: consider restricting the type parameters to satisfy the trait bounds
|
||||
|
|
||||
LL | struct Foo<T> where T: Bar, T: Default {
|
||||
@ -26,9 +35,13 @@ LL | struct Fin<T> where T: Bar {
|
||||
LL | self.foo();
|
||||
| ^^^ method cannot be called on `&Fin<T>` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`T: Default`
|
||||
which is required by `Fin<T>: Bar`
|
||||
note: trait bound `T: Default` was not satisfied
|
||||
--> $DIR/missing-trait-bounds-for-method-call.rs:23:9
|
||||
|
|
||||
LL | impl<T: Default + Bar> Bar for Fin<T> {}
|
||||
| ^^^^^^^ --- ------
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
help: consider restricting the type parameter to satisfy the trait bound
|
||||
|
|
||||
LL | struct Fin<T> where T: Bar, T: Default {
|
||||
|
@ -54,6 +54,12 @@ LL | const _: () = check($exp);
|
||||
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
|
||||
|
|
||||
note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||
--> $DIR/const-drop-fail.rs:28:25
|
||||
|
|
||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const-drop-fail.rs:34:19
|
||||
|
@ -54,6 +54,12 @@ LL | const _: () = check($exp);
|
||||
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
|
||||
|
|
||||
note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||
--> $DIR/const-drop-fail.rs:28:25
|
||||
|
|
||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const-drop-fail.rs:34:19
|
||||
|
@ -20,8 +20,7 @@ LL | struct MyStruct;
|
||||
LL | println!("{}", MyStruct.foo_one());
|
||||
| ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied because of the requirements of the implementation of `Foo` for `_`:
|
||||
`MyStruct: Foo`
|
||||
note: trait bound `MyStruct: Foo` was not satisfied
|
||||
--> $DIR/specialization-trait-not-implemented.rs:14:17
|
||||
|
|
||||
LL | default impl<T> Foo for T {
|
||||
|
@ -5,6 +5,7 @@ LL | use_alias::<Rc<u32>>();
|
||||
| ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
|
||||
|
|
||||
= help: the trait `Send` is not implemented for `Rc<u32>`
|
||||
= note: required because of the requirements on the impl of `SendSync` for `Rc<u32>`
|
||||
note: required by a bound in `use_alias`
|
||||
--> $DIR/cross-crate.rs:10:17
|
||||
|
|
||||
@ -18,6 +19,7 @@ LL | use_alias::<Rc<u32>>();
|
||||
| ^^^^^^^ `Rc<u32>` cannot be shared between threads safely
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `Rc<u32>`
|
||||
= note: required because of the requirements on the impl of `SendSync` for `Rc<u32>`
|
||||
note: required by a bound in `use_alias`
|
||||
--> $DIR/cross-crate.rs:10:17
|
||||
|
|
||||
|
@ -14,7 +14,11 @@ LL | let (a, b) = copy(NoClone);
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Magic` for `NoClone`
|
||||
note: required because of the requirements on the impl of `Magic` for `NoClone`
|
||||
--> $DIR/supertrait-auto-trait.rs:8:12
|
||||
|
|
||||
LL | auto trait Magic: Copy {}
|
||||
| ^^^^^
|
||||
note: required by a bound in `copy`
|
||||
--> $DIR/supertrait-auto-trait.rs:10:12
|
||||
|
|
||||
|
@ -13,6 +13,11 @@ LL | struct CloneNoCopy;
|
||||
LL | let w = u.clone();
|
||||
| ^^^^^ method cannot be called on `U5<CloneNoCopy>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: trait bound `CloneNoCopy: Copy` was not satisfied
|
||||
--> $DIR/union-derive-clone.rs:28:10
|
||||
|
|
||||
LL | #[derive(Clone, Copy)]
|
||||
| ^^^^^ unsatisfied trait bound introduced in this `derive` macro
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`CloneNoCopy: Copy`
|
||||
which is required by `U5<CloneNoCopy>: Clone`
|
||||
|
@ -13,6 +13,11 @@ LL | struct CloneNoCopy;
|
||||
LL | let w = u.clone();
|
||||
| ^^^^^ method cannot be called on `U5<CloneNoCopy>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: trait bound `CloneNoCopy: Copy` was not satisfied
|
||||
--> $DIR/union-derive-clone.rs:28:10
|
||||
|
|
||||
LL | #[derive(Clone, Copy)]
|
||||
| ^^^^^ unsatisfied trait bound introduced in this `derive` macro
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`CloneNoCopy: Copy`
|
||||
which is required by `U5<CloneNoCopy>: Clone`
|
||||
|
@ -5,11 +5,7 @@ LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&T` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `&T`
|
||||
note: required because of the requirements on the impl of `IntoIterator` for `&T`
|
||||
--> $DIR/hir-wf-check-erase-regions.rs:6:29
|
||||
|
|
||||
LL | impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> {
|
||||
| ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
|
||||
= note: required because of the requirements on the impl of `IntoIterator` for `&T`
|
||||
note: required by a bound in `Flatten`
|
||||
--> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
|
||||
|
|
||||
@ -23,11 +19,7 @@ LL | fn into_iter(self) -> Self::IntoIter {
|
||||
| ^^^^^^^^^^^^^^ `&T` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `&T`
|
||||
note: required because of the requirements on the impl of `IntoIterator` for `&T`
|
||||
--> $DIR/hir-wf-check-erase-regions.rs:6:29
|
||||
|
|
||||
LL | impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> {
|
||||
| ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
|
||||
= note: required because of the requirements on the impl of `IntoIterator` for `&T`
|
||||
note: required by a bound in `Flatten`
|
||||
--> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user