Point at impl
blocks when they introduce unmet obligations
Group obligations by `impl` block that introduced them.
This commit is contained in:
parent
8f433adf75
commit
9fa165d11b
@ -12,6 +12,7 @@ pub use self::CandidateSource::*;
|
|||||||
pub use self::MethodError::*;
|
pub use self::MethodError::*;
|
||||||
|
|
||||||
use crate::check::FnCtxt;
|
use crate::check::FnCtxt;
|
||||||
|
use crate::ObligationCause;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -71,7 +72,8 @@ pub enum MethodError<'tcx> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NoMatchData<'tcx> {
|
pub struct NoMatchData<'tcx> {
|
||||||
pub static_candidates: Vec<CandidateSource>,
|
pub static_candidates: Vec<CandidateSource>,
|
||||||
pub unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>,
|
pub unsatisfied_predicates:
|
||||||
|
Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
|
||||||
pub out_of_scope_traits: Vec<DefId>,
|
pub out_of_scope_traits: Vec<DefId>,
|
||||||
pub lev_candidate: Option<ty::AssocItem>,
|
pub lev_candidate: Option<ty::AssocItem>,
|
||||||
pub mode: probe::Mode,
|
pub mode: probe::Mode,
|
||||||
@ -80,7 +82,11 @@ pub struct NoMatchData<'tcx> {
|
|||||||
impl<'tcx> NoMatchData<'tcx> {
|
impl<'tcx> NoMatchData<'tcx> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
static_candidates: Vec<CandidateSource>,
|
static_candidates: Vec<CandidateSource>,
|
||||||
unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>,
|
unsatisfied_predicates: Vec<(
|
||||||
|
ty::Predicate<'tcx>,
|
||||||
|
Option<ty::Predicate<'tcx>>,
|
||||||
|
Option<ObligationCause<'tcx>>,
|
||||||
|
)>,
|
||||||
out_of_scope_traits: Vec<DefId>,
|
out_of_scope_traits: Vec<DefId>,
|
||||||
lev_candidate: Option<ty::AssocItem>,
|
lev_candidate: Option<ty::AssocItem>,
|
||||||
mode: probe::Mode,
|
mode: probe::Mode,
|
||||||
|
@ -78,7 +78,8 @@ struct ProbeContext<'a, 'tcx> {
|
|||||||
|
|
||||||
/// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
|
/// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
|
||||||
/// for error reporting
|
/// for error reporting
|
||||||
unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>,
|
unsatisfied_predicates:
|
||||||
|
Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
|
||||||
|
|
||||||
is_suggestion: IsSuggestion,
|
is_suggestion: IsSuggestion,
|
||||||
|
|
||||||
@ -1351,6 +1352,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
possibly_unsatisfied_predicates: &mut Vec<(
|
possibly_unsatisfied_predicates: &mut Vec<(
|
||||||
ty::Predicate<'tcx>,
|
ty::Predicate<'tcx>,
|
||||||
Option<ty::Predicate<'tcx>>,
|
Option<ty::Predicate<'tcx>>,
|
||||||
|
Option<ObligationCause<'tcx>>,
|
||||||
)>,
|
)>,
|
||||||
unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
|
unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
|
||||||
) -> Option<PickResult<'tcx>>
|
) -> Option<PickResult<'tcx>>
|
||||||
@ -1497,6 +1499,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
possibly_unsatisfied_predicates: &mut Vec<(
|
possibly_unsatisfied_predicates: &mut Vec<(
|
||||||
ty::Predicate<'tcx>,
|
ty::Predicate<'tcx>,
|
||||||
Option<ty::Predicate<'tcx>>,
|
Option<ty::Predicate<'tcx>>,
|
||||||
|
Option<ObligationCause<'tcx>>,
|
||||||
)>,
|
)>,
|
||||||
) -> ProbeResult {
|
) -> ProbeResult {
|
||||||
debug!("consider_probe: self_ty={:?} probe={:?}", self_ty, probe);
|
debug!("consider_probe: self_ty={:?} probe={:?}", self_ty, probe);
|
||||||
@ -1508,8 +1511,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
.sup(probe.xform_self_ty, self_ty)
|
.sup(probe.xform_self_ty, self_ty)
|
||||||
{
|
{
|
||||||
Ok(InferOk { obligations, value: () }) => obligations,
|
Ok(InferOk { obligations, value: () }) => obligations,
|
||||||
Err(_) => {
|
Err(err) => {
|
||||||
debug!("--> cannot relate self-types");
|
debug!("--> cannot relate self-types {:?}", err);
|
||||||
return ProbeResult::NoMatch;
|
return ProbeResult::NoMatch;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1558,7 +1561,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
let o = self.resolve_vars_if_possible(o);
|
let o = self.resolve_vars_if_possible(o);
|
||||||
if !self.predicate_may_hold(&o) {
|
if !self.predicate_may_hold(&o) {
|
||||||
result = ProbeResult::NoMatch;
|
result = ProbeResult::NoMatch;
|
||||||
possibly_unsatisfied_predicates.push((o.predicate, None));
|
possibly_unsatisfied_predicates.push((
|
||||||
|
o.predicate,
|
||||||
|
None,
|
||||||
|
Some(o.cause),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1604,8 +1611,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
Some(predicate)
|
Some(predicate)
|
||||||
};
|
};
|
||||||
possibly_unsatisfied_predicates
|
possibly_unsatisfied_predicates.push((
|
||||||
.push((nested_predicate, p));
|
nested_predicate,
|
||||||
|
p,
|
||||||
|
Some(obligation.cause.clone()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1613,7 +1623,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
// Some nested subobligation of this predicate
|
// Some nested subobligation of this predicate
|
||||||
// failed.
|
// failed.
|
||||||
let predicate = self.resolve_vars_if_possible(predicate);
|
let predicate = self.resolve_vars_if_possible(predicate);
|
||||||
possibly_unsatisfied_predicates.push((predicate, None));
|
possibly_unsatisfied_predicates.push((predicate, None, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@ -1632,7 +1642,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
let o = self.resolve_vars_if_possible(o);
|
let o = self.resolve_vars_if_possible(o);
|
||||||
if !self.predicate_may_hold(&o) {
|
if !self.predicate_may_hold(&o) {
|
||||||
result = ProbeResult::NoMatch;
|
result = ProbeResult::NoMatch;
|
||||||
possibly_unsatisfied_predicates.push((o.predicate, None));
|
possibly_unsatisfied_predicates.push((o.predicate, None, Some(o.cause)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,9 @@ use rustc_span::lev_distance;
|
|||||||
use rustc_span::symbol::{kw, sym, Ident};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::{source_map, FileName, MultiSpan, Span, Symbol};
|
use rustc_span::{source_map, FileName, MultiSpan, Span, Symbol};
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::{FulfillmentError, Obligation};
|
use rustc_trait_selection::traits::{
|
||||||
|
FulfillmentError, Obligation, ObligationCause, ObligationCauseCode,
|
||||||
|
};
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
@ -791,9 +793,88 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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
|
||||||
|
.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))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let parent_trait_ref = data.parent_trait_ref;
|
||||||
|
let parent_def_id = parent_trait_ref.def_id();
|
||||||
|
let path = parent_trait_ref.print_only_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);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The requirements that didn't have an `impl` span to show.
|
||||||
let mut bound_list = unsatisfied_predicates
|
let mut bound_list = unsatisfied_predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(pred, parent_pred)| {
|
.filter(|(pred, _, _parent_pred)| !skip_list.contains(&pred))
|
||||||
|
.filter_map(|(pred, parent_pred, _cause)| {
|
||||||
format_pred(*pred).map(|(p, self_ty)| match parent_pred {
|
format_pred(*pred).map(|(p, self_ty)| match parent_pred {
|
||||||
None => format!("`{}`", &p),
|
None => format!("`{}`", &p),
|
||||||
Some(parent_pred) => match format_pred(*parent_pred) {
|
Some(parent_pred) => match format_pred(*parent_pred) {
|
||||||
@ -836,7 +917,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
for (span, msg) in bound_spans.into_iter() {
|
for (span, msg) in bound_spans.into_iter() {
|
||||||
err.span_label(span, &msg);
|
err.span_label(span, &msg);
|
||||||
}
|
}
|
||||||
if !bound_list.is_empty() {
|
if !bound_list.is_empty() || !skip_list.is_empty() {
|
||||||
let bound_list = bound_list
|
let bound_list = bound_list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, path)| path)
|
.map(|(_, path)| path)
|
||||||
@ -846,9 +927,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err.set_primary_message(&format!(
|
err.set_primary_message(&format!(
|
||||||
"the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
|
"the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
|
||||||
));
|
));
|
||||||
err.note(&format!(
|
if !bound_list.is_empty() {
|
||||||
"the following trait bounds were not satisfied:\n{bound_list}"
|
err.note(&format!(
|
||||||
));
|
"the following trait bounds were not satisfied:\n{bound_list}"
|
||||||
|
));
|
||||||
|
}
|
||||||
self.suggest_derive(&mut err, &unsatisfied_predicates);
|
self.suggest_derive(&mut err, &unsatisfied_predicates);
|
||||||
|
|
||||||
unsatisfied_bounds = true;
|
unsatisfied_bounds = true;
|
||||||
@ -1062,18 +1145,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err.span_note(spans, &msg);
|
err.span_note(spans, &msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
let preds: Vec<_> = errors.iter().map(|e| (e.obligation.predicate, None)).collect();
|
let preds: Vec<_> = errors
|
||||||
|
.iter()
|
||||||
|
.map(|e| (e.obligation.predicate, None, Some(e.obligation.cause.clone())))
|
||||||
|
.collect();
|
||||||
self.suggest_derive(err, &preds);
|
self.suggest_derive(err, &preds);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suggest_derive(
|
fn suggest_derive(
|
||||||
&self,
|
&self,
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
unsatisfied_predicates: &Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)>,
|
unsatisfied_predicates: &Vec<(
|
||||||
|
ty::Predicate<'tcx>,
|
||||||
|
Option<ty::Predicate<'tcx>>,
|
||||||
|
Option<ObligationCause<'tcx>>,
|
||||||
|
)>,
|
||||||
) {
|
) {
|
||||||
let mut derives = Vec::<(String, Span, String)>::new();
|
let mut derives = Vec::<(String, Span, String)>::new();
|
||||||
let mut traits = Vec::<Span>::new();
|
let mut traits = Vec::<Span>::new();
|
||||||
for (pred, _) in unsatisfied_predicates {
|
for (pred, _, _) in unsatisfied_predicates {
|
||||||
let trait_pred = match pred.kind().skip_binder() {
|
let trait_pred = match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Trait(trait_pred) => trait_pred,
|
ty::PredicateKind::Trait(trait_pred) => trait_pred,
|
||||||
_ => continue,
|
_ => continue,
|
||||||
@ -1264,7 +1354,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
item_name: Ident,
|
item_name: Ident,
|
||||||
source: SelfSource<'tcx>,
|
source: SelfSource<'tcx>,
|
||||||
valid_out_of_scope_traits: Vec<DefId>,
|
valid_out_of_scope_traits: Vec<DefId>,
|
||||||
unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)],
|
unsatisfied_predicates: &[(
|
||||||
|
ty::Predicate<'tcx>,
|
||||||
|
Option<ty::Predicate<'tcx>>,
|
||||||
|
Option<ObligationCause<'tcx>>,
|
||||||
|
)],
|
||||||
unsatisfied_bounds: bool,
|
unsatisfied_bounds: bool,
|
||||||
) {
|
) {
|
||||||
let mut alt_rcvr_sugg = false;
|
let mut alt_rcvr_sugg = false;
|
||||||
@ -1380,7 +1474,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// this isn't perfect (that is, there are cases when
|
// this isn't perfect (that is, there are cases when
|
||||||
// implementing a trait would be legal but is rejected
|
// implementing a trait would be legal but is rejected
|
||||||
// here).
|
// here).
|
||||||
unsatisfied_predicates.iter().all(|(p, _)| {
|
unsatisfied_predicates.iter().all(|(p, _, _)| {
|
||||||
match p.kind().skip_binder() {
|
match p.kind().skip_binder() {
|
||||||
// Hide traits if they are present in predicates as they can be fixed without
|
// Hide traits if they are present in predicates as they can be fixed without
|
||||||
// having to implement them.
|
// having to implement them.
|
||||||
|
@ -13,12 +13,16 @@ LL | struct NotClone;
|
|||||||
LL | Bar::<NotClone> { x: 1 }.clone();
|
LL | Bar::<NotClone> { x: 1 }.clone();
|
||||||
| ^^^^^ method cannot be called on `Bar<NotClone>` due to unsatisfied trait bounds
|
| ^^^^^ method cannot be called on `Bar<NotClone>` due to unsatisfied trait bounds
|
||||||
|
|
|
|
||||||
= note: the following trait bounds were not satisfied:
|
note: the following trait bounds were not satisfied because of the requirements of the implementation of `Clone` for `_`:
|
||||||
`NotClone: Clone`
|
`NotClone: Clone`
|
||||||
which is required by `Bar<NotClone>: Clone`
|
--> $DIR/derive-assoc-type-not-impl.rs:6:10
|
||||||
|
|
|
||||||
|
LL | #[derive(Clone)]
|
||||||
|
| ^^^^^
|
||||||
= help: items from traits can only be used if the trait is implemented and in scope
|
= 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:
|
= note: the following trait defines an item `clone`, perhaps you need to implement it:
|
||||||
candidate #1: `Clone`
|
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)]`
|
help: consider annotating `NotClone` with `#[derive(Clone)]`
|
||||||
|
|
|
|
||||||
LL | #[derive(Clone)]
|
LL | #[derive(Clone)]
|
||||||
|
@ -12,6 +12,7 @@ trait M {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: X<Y<i32> = i32>> M for T {}
|
impl<T: X<Y<i32> = i32>> M for T {}
|
||||||
|
//~^ NOTE the following trait bounds were not satisfied
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
//~^ NOTE method `f` not found for this
|
//~^ NOTE method `f` not found for this
|
||||||
@ -26,7 +27,6 @@ fn f(a: S) {
|
|||||||
a.f();
|
a.f();
|
||||||
//~^ ERROR the method `f` exists for struct `S`, but its trait bounds were not satisfied
|
//~^ ERROR the method `f` exists for struct `S`, but its trait bounds were not satisfied
|
||||||
//~| NOTE method cannot be called on `S` due to unsatisfied trait bounds
|
//~| NOTE method cannot be called on `S` due to unsatisfied trait bounds
|
||||||
//~| NOTE the following trait bounds were not satisfied:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
|
error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
|
||||||
--> $DIR/method-unsatified-assoc-type-predicate.rs:26:7
|
--> $DIR/method-unsatified-assoc-type-predicate.rs:27:7
|
||||||
|
|
|
|
||||||
LL | struct S;
|
LL | struct S;
|
||||||
| ---------
|
| ---------
|
||||||
@ -11,9 +11,12 @@ LL | struct S;
|
|||||||
LL | a.f();
|
LL | a.f();
|
||||||
| ^ method cannot be called on `S` due to unsatisfied trait bounds
|
| ^ method cannot be called on `S` due to unsatisfied trait bounds
|
||||||
|
|
|
|
||||||
= note: the following trait bounds were not satisfied:
|
note: the following trait bounds were not satisfied because of the requirements of the implementation of `M` for `_`:
|
||||||
`<S as X>::Y<i32> = i32`
|
`<S as X>::Y<i32> = i32`
|
||||||
which is required by `S: M`
|
--> $DIR/method-unsatified-assoc-type-predicate.rs:14:26
|
||||||
|
|
|
||||||
|
LL | impl<T: X<Y<i32> = i32>> M for T {}
|
||||||
|
| ^ ^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -10,13 +10,14 @@ LL | pub struct Map<S, F> {
|
|||||||
LL | let filter = map.filterx(|x: &_| true);
|
LL | let filter = map.filterx(|x: &_| true);
|
||||||
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` due to unsatisfied trait bounds
|
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` due to unsatisfied trait bounds
|
||||||
|
|
|
|
||||||
= note: the following trait bounds were not satisfied:
|
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:127:27: 127:36]>: Stream`
|
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
||||||
which is required by `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
|
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
||||||
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
||||||
which is required by `&Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
|
--> $DIR/issue-30786.rs:106:9
|
||||||
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
|
|
||||||
which is required by `&mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||||
|
| ^^^^^^^^^ ^
|
||||||
|
|
||||||
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:140:30: 140:42]>`, but its trait bounds were not satisfied
|
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:140:30: 140:42]>`, but its trait bounds were not satisfied
|
||||||
--> $DIR/issue-30786.rs:141:24
|
--> $DIR/issue-30786.rs:141:24
|
||||||
@ -30,13 +31,14 @@ LL | pub struct Filter<S, F> {
|
|||||||
LL | let count = filter.countx();
|
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:140:30: 140:42]>` due to unsatisfied trait bounds
|
| ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` due to unsatisfied trait bounds
|
||||||
|
|
|
|
||||||
= note: the following trait bounds were not satisfied:
|
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:140:30: 140:42]>: Stream`
|
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
||||||
which is required by `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
|
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
||||||
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
||||||
which is required by `&Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
|
--> $DIR/issue-30786.rs:106:9
|
||||||
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
|
|
||||||
which is required by `&mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||||
|
| ^^^^^^^^^ ^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -10,13 +10,14 @@ LL | pub struct Map<S, F> {
|
|||||||
LL | let filter = map.filterx(|x: &_| true);
|
LL | let filter = map.filterx(|x: &_| true);
|
||||||
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` due to unsatisfied trait bounds
|
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` due to unsatisfied trait bounds
|
||||||
|
|
|
|
||||||
= note: the following trait bounds were not satisfied:
|
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:127:27: 127:36]>: Stream`
|
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
||||||
which is required by `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
|
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
||||||
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
||||||
which is required by `&Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
|
--> $DIR/issue-30786.rs:106:9
|
||||||
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
|
|
|
||||||
which is required by `&mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||||
|
| ^^^^^^^^^ ^
|
||||||
|
|
||||||
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:140:30: 140:42]>`, but its trait bounds were not satisfied
|
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:140:30: 140:42]>`, but its trait bounds were not satisfied
|
||||||
--> $DIR/issue-30786.rs:141:24
|
--> $DIR/issue-30786.rs:141:24
|
||||||
@ -30,13 +31,14 @@ LL | pub struct Filter<S, F> {
|
|||||||
LL | let count = filter.countx();
|
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:140:30: 140:42]>` due to unsatisfied trait bounds
|
| ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` due to unsatisfied trait bounds
|
||||||
|
|
|
|
||||||
= note: the following trait bounds were not satisfied:
|
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:140:30: 140:42]>: Stream`
|
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
||||||
which is required by `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
|
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
||||||
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
||||||
which is required by `&Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
|
--> $DIR/issue-30786.rs:106:9
|
||||||
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
|
|
|
||||||
which is required by `&mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||||
|
| ^^^^^^^^^ ^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -20,8 +20,12 @@ LL | struct MyStruct;
|
|||||||
LL | println!("{}", MyStruct.foo_one());
|
LL | println!("{}", MyStruct.foo_one());
|
||||||
| ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds
|
| ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds
|
||||||
|
|
|
|
||||||
= note: the following trait bounds were not satisfied:
|
note: the following trait bounds were not satisfied because of the requirements of the implementation of `Foo` for `_`:
|
||||||
`MyStruct: Foo`
|
`MyStruct: Foo`
|
||||||
|
--> $DIR/specialization-trait-not-implemented.rs:14:17
|
||||||
|
|
|
||||||
|
LL | default impl<T> Foo for T {
|
||||||
|
| ^^^ ^
|
||||||
note: the following trait must be implemented
|
note: the following trait must be implemented
|
||||||
--> $DIR/specialization-trait-not-implemented.rs:7:1
|
--> $DIR/specialization-trait-not-implemented.rs:7:1
|
||||||
|
|
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user