Skip to content

Commit c0e8581

Browse files
committed
Arbitrary self types v2: no deshadowing on traits
This is a hacky temporary "fix" for problems encountered where our deshadowing algorithm is blocking legitimate code. This will need to be reworked, but pushing to see if we get through CI. The solution here involves only applying the deshadowing algorithm in cases where both methods are inherent rather than in traits. That's probably what we want to do? - but it needs discussion, and the code needs a bit of restructuring.
1 parent 49acfb4 commit c0e8581

File tree

2 files changed

+67
-41
lines changed

2 files changed

+67
-41
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
917917
[candidate] => format!(
918918
"the method of the same name on {} `{}`",
919919
match candidate.kind {
920-
probe::CandidateKind::InherentImplCandidate(_) => "the inherent impl for",
920+
probe::CandidateKind::InherentImplCandidate(..) => "the inherent impl for",
921921
_ => "trait",
922922
},
923923
self.tcx.def_path_str(candidate.item.container_id(self.tcx))

compiler/rustc_hir_typeck/src/method/probe.rs

+66-40
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,6 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
8585
/// machinery, since we don't particularly care about, for example, similarly named
8686
/// candidates if we're *reporting* similarly named candidates.
8787
is_suggestion: IsSuggestion,
88-
89-
/// Number of times we've hopped along the chain of `Receiver::Target`.
90-
/// Used to spot cases where an "outer" method in a smart pointer might
91-
/// "shadow" a pre-existing method in the pointee.
92-
receiver_trait_derefs: usize,
9388
}
9489

9590
impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> {
@@ -104,12 +99,11 @@ pub(crate) struct Candidate<'tcx> {
10499
pub(crate) item: ty::AssocItem,
105100
pub(crate) kind: CandidateKind<'tcx>,
106101
pub(crate) import_ids: SmallVec<[LocalDefId; 1]>,
107-
receiver_trait_derefs: usize,
108102
}
109103

110104
#[derive(Debug, Clone)]
111105
pub(crate) enum CandidateKind<'tcx> {
112-
InherentImplCandidate(DefId),
106+
InherentImplCandidate(DefId, usize),
113107
ObjectCandidate(ty::PolyTraitRef<'tcx>),
114108
TraitCandidate(ty::PolyTraitRef<'tcx>),
115109
WhereClauseCandidate(ty::PolyTraitRef<'tcx>),
@@ -183,7 +177,7 @@ struct PickDiagHints<'a, 'tcx> {
183177
#[derive(Debug)]
184178
struct PickConstraintsForShadowed {
185179
autoderefs: usize,
186-
receiver_trait_derefs: usize,
180+
receiver_trait_derefs: Option<usize>,
187181
def_id: DefId,
188182
}
189183

@@ -192,8 +186,17 @@ impl PickConstraintsForShadowed {
192186
autoderefs == self.autoderefs
193187
}
194188

195-
fn may_shadow_based_on_receiver_trait_derefs(&self, receiver_trait_derefs: usize) -> bool {
196-
receiver_trait_derefs != self.receiver_trait_derefs
189+
fn may_shadow_based_on_kind(&self, kind: &CandidateKind<'_>) -> bool {
190+
if let Some(receiver_trait_derefs) = self.receiver_trait_derefs {
191+
match kind {
192+
CandidateKind::InherentImplCandidate(_, other_derefs) => {
193+
*other_derefs != receiver_trait_derefs
194+
}
195+
_ => false,
196+
}
197+
} else {
198+
false
199+
}
197200
}
198201

199202
fn may_shadow_based_on_defid(&self, def_id: DefId) -> bool {
@@ -223,7 +226,8 @@ pub(crate) struct Pick<'tcx> {
223226

224227
/// Number of jumps along the `Receiver::Target` chain we followed
225228
/// to identify this method. Used only for deshadowing errors.
226-
pub receiver_trait_derefs: usize,
229+
/// Only applies for inherent impls.
230+
pub receiver_trait_derefs: Option<usize>,
227231
}
228232

229233
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -708,7 +712,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
708712
static_candidates: RefCell::new(Vec::new()),
709713
scope_expr_id,
710714
is_suggestion,
711-
receiver_trait_derefs: 0usize,
712715
}
713716
}
714717

@@ -741,8 +744,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
741744
import_ids: SmallVec<[LocalDefId; 1]>,
742745
is_inherent: bool,
743746
) {
744-
let candidate =
745-
Candidate { item, kind, import_ids, receiver_trait_derefs: self.receiver_trait_derefs };
747+
let candidate = Candidate { item, kind, import_ids };
746748
let is_accessible = if let Some(name) = self.method_name {
747749
let item = candidate.item;
748750
let hir_id = self.tcx.local_def_id_to_hir_id(self.body_id);
@@ -765,13 +767,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
765767

766768
fn assemble_inherent_candidates(&mut self) {
767769
for step in self.steps.iter() {
768-
self.receiver_trait_derefs = step.autoderefs;
769-
self.assemble_probe(&step.self_ty);
770+
self.assemble_probe(&step.self_ty, step.autoderefs);
770771
}
771772
}
772773

773774
#[instrument(level = "debug", skip(self))]
774-
fn assemble_probe(&mut self, self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>) {
775+
fn assemble_probe(
776+
&mut self,
777+
self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
778+
receiver_steps: usize,
779+
) {
775780
let raw_self_ty = self_ty.value.value;
776781
match *raw_self_ty.kind() {
777782
ty::Dynamic(data, ..) if let Some(p) = data.principal() => {
@@ -796,22 +801,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
796801
self.fcx.instantiate_canonical(self.span, self_ty);
797802

798803
self.assemble_inherent_candidates_from_object(generalized_self_ty);
799-
self.assemble_inherent_impl_candidates_for_type(p.def_id());
804+
self.assemble_inherent_impl_candidates_for_type(p.def_id(), receiver_steps);
800805
if self.tcx.has_attr(p.def_id(), sym::rustc_has_incoherent_inherent_impls) {
801-
self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
806+
self.assemble_inherent_candidates_for_incoherent_ty(
807+
raw_self_ty,
808+
receiver_steps,
809+
);
802810
}
803811
}
804812
ty::Adt(def, _) => {
805813
let def_id = def.did();
806-
self.assemble_inherent_impl_candidates_for_type(def_id);
814+
self.assemble_inherent_impl_candidates_for_type(def_id, receiver_steps);
807815
if self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) {
808-
self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
816+
self.assemble_inherent_candidates_for_incoherent_ty(
817+
raw_self_ty,
818+
receiver_steps,
819+
);
809820
}
810821
}
811822
ty::Foreign(did) => {
812-
self.assemble_inherent_impl_candidates_for_type(did);
823+
self.assemble_inherent_impl_candidates_for_type(did, receiver_steps);
813824
if self.tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
814-
self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
825+
self.assemble_inherent_candidates_for_incoherent_ty(
826+
raw_self_ty,
827+
receiver_steps,
828+
);
815829
}
816830
}
817831
ty::Param(p) => {
@@ -828,29 +842,35 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
828842
| ty::RawPtr(_, _)
829843
| ty::Ref(..)
830844
| ty::Never
831-
| ty::Tuple(..) => self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty),
845+
| ty::Tuple(..) => {
846+
self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps)
847+
}
832848
_ => {}
833849
}
834850
}
835851

836-
fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
852+
fn assemble_inherent_candidates_for_incoherent_ty(
853+
&mut self,
854+
self_ty: Ty<'tcx>,
855+
receiver_steps: usize,
856+
) {
837857
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else {
838858
bug!("unexpected incoherent type: {:?}", self_ty)
839859
};
840860
for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter() {
841-
self.assemble_inherent_impl_probe(impl_def_id);
861+
self.assemble_inherent_impl_probe(impl_def_id, receiver_steps);
842862
}
843863
}
844864

845-
fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
865+
fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId, receiver_steps: usize) {
846866
let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter();
847867
for &impl_def_id in impl_def_ids {
848-
self.assemble_inherent_impl_probe(impl_def_id);
868+
self.assemble_inherent_impl_probe(impl_def_id, receiver_steps);
849869
}
850870
}
851871

852872
#[instrument(level = "debug", skip(self))]
853-
fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
873+
fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId, receiver_steps: usize) {
854874
if !self.impl_dups.insert(impl_def_id) {
855875
return; // already visited
856876
}
@@ -861,7 +881,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
861881
self.record_static_candidate(CandidateSource::Impl(impl_def_id));
862882
continue;
863883
}
864-
self.push_candidate(item, InherentImplCandidate(impl_def_id), smallvec![], true);
884+
self.push_candidate(
885+
item,
886+
InherentImplCandidate(impl_def_id, receiver_steps),
887+
smallvec![],
888+
true,
889+
);
865890
}
866891
}
867892

@@ -1569,9 +1594,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15691594
pick_constraints
15701595
.map(|pick_constraints| {
15711596
pick_constraints.may_shadow_based_on_defid(candidate.item.def_id)
1572-
&& pick_constraints.may_shadow_based_on_receiver_trait_derefs(
1573-
candidate.receiver_trait_derefs,
1574-
)
1597+
&& pick_constraints.may_shadow_based_on_kind(&candidate.kind)
15751598
})
15761599
.unwrap_or(true)
15771600
})
@@ -1724,7 +1747,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
17241747
/// so do not use to make a decision that may lead to a successful compilation.
17251748
fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource {
17261749
match candidate.kind {
1727-
InherentImplCandidate(_) => {
1750+
InherentImplCandidate(..) => {
17281751
CandidateSource::Impl(candidate.item.container_id(self.tcx))
17291752
}
17301753
ObjectCandidate(_) | WhereClauseCandidate(_) => {
@@ -1787,7 +1810,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
17871810
let (mut xform_self_ty, mut xform_ret_ty);
17881811

17891812
match probe.kind {
1790-
InherentImplCandidate(impl_def_id) => {
1813+
InherentImplCandidate(impl_def_id, _) => {
17911814
let impl_args = self.fresh_args_for_item(self.span, impl_def_id);
17921815
let impl_ty = self.tcx.type_of(impl_def_id).instantiate(self.tcx, impl_args);
17931816
(xform_self_ty, xform_ret_ty) =
@@ -1956,7 +1979,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
19561979
// We don't normalize the other candidates for perf/backwards-compat reasons...
19571980
// but `self.return_type` is only set on the diagnostic-path, so we
19581981
// should be okay doing it here.
1959-
if !matches!(probe.kind, InherentImplCandidate(_)) {
1982+
if !matches!(probe.kind, InherentImplCandidate(..)) {
19601983
xform_ret_ty = ocx.normalize(&cause, self.param_env, xform_ret_ty);
19611984
}
19621985

@@ -2030,11 +2053,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
20302053
item: probes[0].0.item,
20312054
kind: TraitPick,
20322055
import_ids: probes[0].0.import_ids.clone(),
2033-
autoderefs: probes[0].0.receiver_trait_derefs,
2056+
autoderefs: 0,
20342057
autoref_or_ptr_adjustment: None,
20352058
self_ty,
20362059
unstable_candidates: vec![],
2037-
receiver_trait_derefs: 0,
2060+
receiver_trait_derefs: None,
20382061
})
20392062
}
20402063

@@ -2306,7 +2329,7 @@ impl<'tcx> Candidate<'tcx> {
23062329
Pick {
23072330
item: self.item,
23082331
kind: match self.kind {
2309-
InherentImplCandidate(_) => InherentImplPick,
2332+
InherentImplCandidate(..) => InherentImplPick,
23102333
ObjectCandidate(_) => ObjectPick,
23112334
TraitCandidate(_) => TraitPick,
23122335
WhereClauseCandidate(trait_ref) => {
@@ -2328,7 +2351,10 @@ impl<'tcx> Candidate<'tcx> {
23282351
autoref_or_ptr_adjustment: None,
23292352
self_ty,
23302353
unstable_candidates,
2331-
receiver_trait_derefs: self.receiver_trait_derefs,
2354+
receiver_trait_derefs: match self.kind {
2355+
InherentImplCandidate(_, receiver_steps) => Some(receiver_steps),
2356+
_ => None,
2357+
},
23322358
}
23332359
}
23342360
}

0 commit comments

Comments
 (0)