summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_typeck/src/method
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_hir_typeck/src/method
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_hir_typeck/src/method')
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs102
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs132
3 files changed, 158 insertions, 90 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 169f128e0..9155a3d8d 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -8,7 +8,7 @@ use rustc_hir_analysis::astconv::generics::{
check_generic_arg_count_for_call, create_substs_for_generic_args,
};
use rustc_hir_analysis::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall};
-use rustc_infer::infer::{self, InferOk};
+use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
@@ -478,7 +478,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
substs,
})),
);
- match self.at(&cause, self.param_env).sup(method_self_ty, self_ty) {
+ match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::No, method_self_ty, self_ty) {
Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations);
}
@@ -574,19 +574,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
) -> Option<Span> {
let sized_def_id = self.tcx.lang_items().sized_trait()?;
- traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied())
+ traits::elaborate(self.tcx, predicates.predicates.iter().copied())
// We don't care about regions here.
- .filter_map(|obligation| match obligation.predicate.kind().skip_binder() {
+ .filter_map(|pred| match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred))
if trait_pred.def_id() == sized_def_id =>
{
let span = predicates
.iter()
- .find_map(
- |(p, span)| {
- if p == obligation.predicate { Some(span) } else { None }
- },
- )
+ .find_map(|(p, span)| if p == pred { Some(span) } else { None })
.unwrap_or(rustc_span::DUMMY_SP);
Some((trait_pred, span))
}
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 3bef5cfcd..4fd778910 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -13,6 +13,7 @@ use rustc_hir_analysis::astconv::InferCtxtExt as _;
use rustc_hir_analysis::autoderef::{self, Autoderef};
use rustc_infer::infer::canonical::OriginalQueryValues;
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
+use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
use rustc_middle::middle::stability;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
@@ -699,7 +700,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
- let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) else {
+ let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) else {
bug!("unexpected incoherent type: {:?}", self_ty)
};
for &impl_def_id in self.tcx.incoherent_impls(simp) {
@@ -792,6 +793,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// a `&self` method will wind up with an argument type like `&dyn Trait`.
let trait_ref = principal.with_self_ty(self.tcx, self_ty);
self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
+ if new_trait_ref.has_non_region_late_bound() {
+ this.tcx.sess.delay_span_bug(
+ this.span,
+ "tried to select method from HRTB with non-lifetime bound vars",
+ );
+ return;
+ }
+
let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);
let (xform_self_ty, xform_ret_ty) =
@@ -836,24 +845,21 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::Ambiguous
- | ty::PredicateKind::AliasEq(..)
+ | ty::PredicateKind::AliasRelate(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
}
});
self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
- let trait_ref = this.erase_late_bound_regions(poly_trait_ref);
+ let trait_ref = this.instantiate_binder_with_fresh_vars(
+ this.span,
+ infer::LateBoundRegionConversionTime::FnCall,
+ poly_trait_ref,
+ );
let (xform_self_ty, xform_ret_ty) =
this.xform_self_ty(item, trait_ref.self_ty(), trait_ref.substs);
- // Because this trait derives from a where-clause, it
- // should not contain any inference variables or other
- // artifacts. This means it is safe to put into the
- // `WhereClauseCandidate` and (eventually) into the
- // `WhereClausePick`.
- assert!(!trait_ref.substs.needs_infer());
-
this.push_candidate(
Candidate {
xform_self_ty,
@@ -929,7 +935,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
if let Some(self_ty) = self_ty {
if self
.at(&ObligationCause::dummy(), self.param_env)
- .sup(fty.inputs()[0], self_ty)
+ .sup(DefineOpaqueTypes::No, fty.inputs()[0], self_ty)
.is_err()
{
return false;
@@ -963,7 +969,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
bound_trait_ref.def_id(),
));
} else {
- let new_trait_ref = self.erase_late_bound_regions(bound_trait_ref);
+ let new_trait_ref = self.instantiate_binder_with_fresh_vars(
+ self.span,
+ infer::LateBoundRegionConversionTime::FnCall,
+ bound_trait_ref,
+ );
let (xform_self_ty, xform_ret_ty) =
self.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.substs);
@@ -1026,12 +1036,21 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
true
}
})
+ // ensure that we don't suggest unstable methods
+ .filter(|candidate| {
+ // note that `DUMMY_SP` is ok here because it is only used for
+ // suggestions and macro stuff which isn't applicable here.
+ !matches!(
+ self.tcx.eval_stability(candidate.item.def_id, None, DUMMY_SP, None),
+ stability::EvalResult::Deny { .. }
+ )
+ })
.map(|candidate| candidate.item.ident(self.tcx))
.filter(|&name| set.insert(name))
.collect();
// Sort them by the name so we have a stable result.
- names.sort_by(|a, b| a.as_str().partial_cmp(b.as_str()).unwrap());
+ names.sort_by(|a, b| a.as_str().cmp(b.as_str()));
names
}
@@ -1338,6 +1357,7 @@ impl<'tcx> Pick<'tcx> {
container: _,
trait_item_def_id: _,
fn_has_self_parameter: _,
+ opt_rpitit_info: _,
},
kind: _,
import_ids: _,
@@ -1434,9 +1454,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
CandidateSource::Trait(candidate.item.container_id(self.tcx))
}
TraitCandidate(trait_ref) => self.probe(|_| {
- let _ = self
- .at(&ObligationCause::dummy(), self.param_env)
- .sup(candidate.xform_self_ty, self_ty);
+ let _ = self.at(&ObligationCause::dummy(), self.param_env).sup(
+ DefineOpaqueTypes::No,
+ candidate.xform_self_ty,
+ self_ty,
+ );
match self.select_trait_candidate(trait_ref) {
Ok(Some(traits::ImplSource::UserDefined(ref impl_data))) => {
// If only a single impl matches, make the error message point
@@ -1463,10 +1485,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.probe(|_| {
// First check that the self type can be related.
- let sub_obligations = match self
- .at(&ObligationCause::dummy(), self.param_env)
- .sup(probe.xform_self_ty, self_ty)
- {
+ let sub_obligations = match self.at(&ObligationCause::dummy(), self.param_env).sup(
+ DefineOpaqueTypes::No,
+ probe.xform_self_ty,
+ self_ty,
+ ) {
Ok(InferOk { obligations, value: () }) => obligations,
Err(err) => {
debug!("--> cannot relate self-types {:?}", err);
@@ -1508,23 +1531,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,
@@ -1541,8 +1559,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
if !self.predicate_may_hold(&o) {
result = ProbeResult::NoMatch;
let parent_o = o.clone();
- let implied_obligations =
- traits::elaborate_obligations(self.tcx, vec![o]);
+ let implied_obligations = traits::elaborate(self.tcx, vec![o]);
for o in implied_obligations {
let parent = if o == parent_o {
None
@@ -1681,7 +1698,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
if let ProbeResult::Match = result
&& self
.at(&ObligationCause::dummy(), self.param_env)
- .sup(return_ty, xform_ret_ty)
+ .sup(DefineOpaqueTypes::No, return_ty, xform_ret_ty)
.is_err()
{
result = ProbeResult::BadReturnType;
@@ -1742,7 +1759,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
fn probe_for_similar_candidate(&mut self) -> Result<Option<ty::AssocItem>, MethodError<'tcx>> {
debug!("probing for method names similar to {:?}", self.method_name);
- let steps = self.steps.clone();
self.probe(|_| {
let mut pcx = ProbeContext::new(
self.fcx,
@@ -1750,8 +1766,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.mode,
self.method_name,
self.return_type,
- &self.orig_steps_var_values,
- steps,
+ self.orig_steps_var_values,
+ self.steps,
self.scope_expr_id,
);
pcx.allow_similar_names = true;
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 60d56263d..900a6fa0d 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -27,7 +27,7 @@ use rustc_middle::traits::util::supertraits;
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
-use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Symbol;
@@ -42,7 +42,7 @@ use rustc_trait_selection::traits::{
use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
use super::{CandidateSource, MethodError, NoMatchData};
use rustc_hir::intravisit::Visitor;
-use std::cmp::Ordering;
+use std::cmp::{self, Ordering};
use std::iter;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -245,6 +245,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
}
+ fn suggest_missing_writer(
+ &self,
+ rcvr_ty: Ty<'tcx>,
+ args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]),
+ ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
+ let mut err =
+ struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str);
+ err.span_note(
+ args.0.span,
+ "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
+ );
+ if let ExprKind::Lit(_) = args.0.kind {
+ err.span_help(
+ args.0.span.shrink_to_lo(),
+ "a writer is needed before this format string",
+ );
+ };
+
+ err
+ }
+
pub fn report_no_match_method_error(
&self,
mut span: Span,
@@ -278,7 +300,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
// We could pass the file for long types into these two, but it isn't strictly necessary
- // given how targetted they are.
+ // given how targeted they are.
if self.suggest_wrapping_range_with_parens(
tcx,
rcvr_ty,
@@ -323,16 +345,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- let mut err = struct_span_err!(
- tcx.sess,
- span,
- E0599,
- "no {} named `{}` found for {} `{}` in the current scope",
- item_kind,
- item_name,
- rcvr_ty.prefix_string(self.tcx),
- ty_str_reported,
- );
+ let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.map_or(false, |def_id| {
+ tcx.is_diagnostic_item(sym::write_macro, def_id)
+ || tcx.is_diagnostic_item(sym::writeln_macro, def_id)
+ }) && item_name.name == Symbol::intern("write_fmt");
+ let mut err = if is_write
+ && let Some(args) = args
+ {
+ self.suggest_missing_writer(rcvr_ty, args)
+ } else {
+ struct_span_err!(
+ tcx.sess,
+ span,
+ E0599,
+ "no {} named `{}` found for {} `{}` in the current scope",
+ item_kind,
+ item_name,
+ rcvr_ty.prefix_string(self.tcx),
+ ty_str_reported,
+ )
+ };
if tcx.sess.source_map().is_multiline(sugg_span) {
err.span_label(sugg_span.with_hi(span.lo()), "");
}
@@ -348,6 +380,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.downgrade_to_delayed_bug();
}
+ if tcx.ty_is_opaque_future(rcvr_ty) && item_name.name == sym::poll {
+ err.help(&format!(
+ "method `poll` found on `Pin<&mut {ty_str}>`, \
+ see documentation for `std::pin::Pin`"
+ ));
+ err.help("self type must be pinned to call `Future::poll`, \
+ see https://rust-lang.github.io/async-book/04_pinning/01_chapter.html#pinning-in-practice"
+ );
+ }
+
if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source {
self.suggest_await_before_method(
&mut err, item_name, rcvr_ty, cal, span, expected.only_has_type(self),
@@ -405,6 +447,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
probe.is_ok()
});
+
+ self.note_internal_mutation_in_method(
+ &mut err,
+ rcvr_expr,
+ expected.to_option(&self),
+ rcvr_ty,
+ );
}
let mut custom_span_label = false;
@@ -612,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 {
@@ -669,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"),
@@ -692,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);
@@ -726,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:?}`"),
@@ -1164,7 +1220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.inputs()
.skip_binder()
.get(0)
- .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr())
+ .filter(|ty| ty.is_ref() && !rcvr_ty.is_ref())
.copied()
.unwrap_or(rcvr_ty),
};
@@ -1247,7 +1303,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let target_ty = self
.autoderef(sugg_span, rcvr_ty)
.find(|(rcvr_ty, _)| {
- DeepRejectCtxt { treat_obligation_params: TreatParams::AsInfer }
+ DeepRejectCtxt { treat_obligation_params: TreatParams::AsCandidateKey }
.types_may_unify(*rcvr_ty, impl_ty)
})
.map_or(impl_ty, |(ty, _)| ty)
@@ -1506,7 +1562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.into_iter()
.any(|info| self.associated_value(info.def_id, item_name).is_some());
let found_assoc = |ty: Ty<'tcx>| {
- simplify_type(tcx, ty, TreatParams::AsInfer)
+ simplify_type(tcx, ty, TreatParams::AsCandidateKey)
.and_then(|simp| {
tcx.incoherent_impls(simp)
.iter()
@@ -1766,7 +1822,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.variants()
.iter()
.flat_map(|variant| {
- let [field] = &variant.fields[..] else { return None; };
+ let [field] = &variant.fields.raw[..] else { return None; };
let field_ty = field.ty(tcx, substs);
// Skip `_`, since that'll just lead to ambiguity.
@@ -2517,7 +2573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if !candidates.is_empty() {
// Sort from most relevant to least relevant.
- candidates.sort_by(|a, b| a.cmp(b).reverse());
+ candidates.sort_by_key(|&info| cmp::Reverse(info));
candidates.dedup();
let param_type = match rcvr_ty.kind() {
@@ -2636,7 +2692,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// cases where a positive bound implies a negative impl.
(candidates, Vec::new())
} else if let Some(simp_rcvr_ty) =
- simplify_type(self.tcx, rcvr_ty, TreatParams::AsPlaceholder)
+ simplify_type(self.tcx, rcvr_ty, TreatParams::ForLookup)
{
let mut potential_candidates = Vec::new();
let mut explicitly_negative = Vec::new();
@@ -2651,7 +2707,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.any(|imp_did| {
let imp = self.tcx.impl_trait_ref(imp_did).unwrap().subst_identity();
let imp_simp =
- simplify_type(self.tcx, imp.self_ty(), TreatParams::AsPlaceholder);
+ simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
imp_simp.map_or(false, |s| s == simp_rcvr_ty)
})
{