mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-21 04:03:11 +00:00
Do not use ImplDerivedObligationCause for inherent impl method error reporting
This commit is contained in:
parent
39bf7777aa
commit
b369c8ecbd
@ -1522,23 +1522,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
|
||||
// Convert the bounds into obligations.
|
||||
let impl_obligations = traits::predicates_for_generics(
|
||||
|_idx, span| {
|
||||
let misc = traits::ObligationCause::misc(span, self.body_id);
|
||||
let parent_trait_pred = ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::from_method(self.tcx, impl_def_id, substs),
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
});
|
||||
misc.derived_cause(parent_trait_pred, |derived| {
|
||||
traits::ImplDerivedObligation(Box::new(
|
||||
traits::ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_or_alias_def_id: impl_def_id,
|
||||
impl_def_predicate_index: None,
|
||||
span,
|
||||
},
|
||||
))
|
||||
})
|
||||
|idx, span| {
|
||||
let code = if span.is_dummy() {
|
||||
traits::ExprItemObligation(impl_def_id, self.scope_expr_id, idx)
|
||||
} else {
|
||||
traits::ExprBindingObligation(
|
||||
impl_def_id,
|
||||
span,
|
||||
self.scope_expr_id,
|
||||
idx,
|
||||
)
|
||||
};
|
||||
ObligationCause::new(self.span, self.body_id, code)
|
||||
},
|
||||
self.param_env,
|
||||
impl_bounds,
|
||||
|
@ -661,19 +661,26 @@ 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::default();
|
||||
for (p, parent_p, impl_def_id, cause) 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(data)
|
||||
if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) =>
|
||||
{
|
||||
Some((p, parent, data.impl_or_alias_def_id, data))
|
||||
for (p, parent_p, cause) in unsatisfied_predicates {
|
||||
// Extract the predicate span and parent def id of the cause,
|
||||
// if we have one.
|
||||
let (item_def_id, cause_span) = match cause.as_ref().map(|cause| cause.code()) {
|
||||
Some(ObligationCauseCode::ImplDerivedObligation(data)) => {
|
||||
(data.impl_or_alias_def_id, data.span)
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
{
|
||||
match self.tcx.hir().get_if_local(impl_def_id) {
|
||||
Some(
|
||||
ObligationCauseCode::ExprBindingObligation(def_id, span, _, _)
|
||||
| ObligationCauseCode::BindingObligation(def_id, span),
|
||||
) => (*def_id, *span),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
// Don't point out the span of `WellFormed` predicates.
|
||||
if !matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) {
|
||||
continue;
|
||||
};
|
||||
|
||||
match self.tcx.hir().get_if_local(item_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 {
|
||||
@ -718,7 +725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
});
|
||||
for param in generics.params {
|
||||
if param.span == cause.span && sized_pred {
|
||||
if param.span == cause_span && sized_pred {
|
||||
let (sp, sugg) = match param.colon_span {
|
||||
Some(sp) => (sp.shrink_to_hi(), " ?Sized +"),
|
||||
None => (param.span.shrink_to_hi(), ": ?Sized"),
|
||||
@ -741,9 +748,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
(FxHashSet::default(), FxHashSet::default(), Vec::new())
|
||||
});
|
||||
entry.2.push(p);
|
||||
if cause.span != *item_span {
|
||||
entry.0.insert(cause.span);
|
||||
entry.1.insert((cause.span, "unsatisfied trait bound introduced here"));
|
||||
if cause_span != *item_span {
|
||||
entry.0.insert(cause_span);
|
||||
entry.1.insert((cause_span, "unsatisfied trait bound introduced here"));
|
||||
} else {
|
||||
if let Some(trait_ref) = of_trait {
|
||||
entry.0.insert(trait_ref.path.span);
|
||||
@ -775,9 +782,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let entry = entry.or_insert_with(|| {
|
||||
(FxHashSet::default(), FxHashSet::default(), Vec::new())
|
||||
});
|
||||
entry.0.insert(cause.span);
|
||||
entry.0.insert(cause_span);
|
||||
entry.1.insert((ident.span, ""));
|
||||
entry.1.insert((cause.span, "unsatisfied trait bound introduced here"));
|
||||
entry.1.insert((cause_span, "unsatisfied trait bound introduced here"));
|
||||
entry.2.push(p);
|
||||
}
|
||||
Some(node) => unreachable!("encountered `{node:?}`"),
|
||||
|
49
tests/ui/methods/inherent-bound-in-probe.rs
Normal file
49
tests/ui/methods/inherent-bound-in-probe.rs
Normal file
@ -0,0 +1,49 @@
|
||||
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
|
||||
|
||||
// Fixes #110131
|
||||
//
|
||||
// The issue is that we were constructing an `ImplDerived` cause code for the
|
||||
// `&'a T: IntoIterator<Item = &'a u8>` obligation for `Helper::new`, which is
|
||||
// incorrect because derived obligations are only expected to come from *traits*.
|
||||
|
||||
struct SeqBuffer<'a, T>
|
||||
where
|
||||
&'a T: IntoIterator<Item = &'a u8>,
|
||||
{
|
||||
iter: <&'a T as IntoIterator>::IntoIter,
|
||||
}
|
||||
|
||||
struct Helper<'a, T>
|
||||
where
|
||||
&'a T: IntoIterator<Item = &'a u8>,
|
||||
{
|
||||
buf: SeqBuffer<'a, T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Helper<'a, T>
|
||||
where
|
||||
&'a T: IntoIterator<Item = &'a u8>,
|
||||
{
|
||||
fn new(sq: &'a T) -> Self {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
struct BitReaderWrapper<T>(T);
|
||||
|
||||
impl<'a, T> IntoIterator for &'a BitReaderWrapper<T>
|
||||
where
|
||||
&'a T: IntoIterator<Item = &'a u8>,
|
||||
{
|
||||
type Item = u32;
|
||||
|
||||
type IntoIter = Helper<'a, T>;
|
||||
//~^ ERROR `Helper<'a, T>` is not an iterator
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
Helper::new(&self.0)
|
||||
//~^ ERROR overflow evaluating the requirement `&_: IntoIterator`
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
38
tests/ui/methods/inherent-bound-in-probe.stderr
Normal file
38
tests/ui/methods/inherent-bound-in-probe.stderr
Normal file
@ -0,0 +1,38 @@
|
||||
error[E0277]: `Helper<'a, T>` is not an iterator
|
||||
--> $DIR/inherent-bound-in-probe.rs:40:21
|
||||
|
|
||||
LL | type IntoIter = Helper<'a, T>;
|
||||
| ^^^^^^^^^^^^^ `Helper<'a, T>` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `Helper<'a, T>`
|
||||
note: required by a bound in `std::iter::IntoIterator::IntoIter`
|
||||
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `&_: IntoIterator`
|
||||
--> $DIR/inherent-bound-in-probe.rs:44:17
|
||||
|
|
||||
LL | Helper::new(&self.0)
|
||||
| ^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_bound_in_probe`)
|
||||
note: required for `&BitReaderWrapper<_>` to implement `IntoIterator`
|
||||
--> $DIR/inherent-bound-in-probe.rs:34:13
|
||||
|
|
||||
LL | impl<'a, T> IntoIterator for &'a BitReaderWrapper<T>
|
||||
| ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | where
|
||||
LL | &'a T: IntoIterator<Item = &'a u8>,
|
||||
| ------------- unsatisfied trait bound introduced here
|
||||
= note: 126 redundant requirements hidden
|
||||
= note: required for `&BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<...>>>>>` to implement `IntoIterator`
|
||||
= note: the full type name has been written to '$TEST_BUILD_DIR/methods/inherent-bound-in-probe/inherent-bound-in-probe.long-type-hash.txt'
|
||||
note: required by a bound in `Helper<'a, T>`
|
||||
--> $DIR/inherent-bound-in-probe.rs:25:25
|
||||
|
|
||||
LL | &'a T: IntoIterator<Item = &'a u8>,
|
||||
| ^^^^^^^^^^^^^ required by this bound in `Helper<'a, T>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0275, E0277.
|
||||
For more information about an error, try `rustc --explain E0275`.
|
Loading…
Reference in New Issue
Block a user