Skip to content

Commit e656883

Browse files
committed
Pull the unstable name collision hint emission out of method probing
1 parent e694ef5 commit e656883

File tree

2 files changed

+60
-60
lines changed

2 files changed

+60
-60
lines changed

compiler/rustc_hir_typeck/src/method/mod.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
101101
call_expr_id,
102102
ProbeScope::TraitsInScope,
103103
) {
104-
Ok(..) => true,
104+
Ok(pick) => {
105+
pick.emit_unstable_name_collision_hint(self.tcx, method_name.span, call_expr_id);
106+
true
107+
}
105108
Err(NoMatch(..)) => false,
106109
Err(Ambiguity(..)) => true,
107110
Err(PrivateMatch(..)) => allow_private,
@@ -245,14 +248,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
245248
call_expr: &'tcx hir::Expr<'tcx>,
246249
scope: ProbeScope,
247250
) -> probe::PickResult<'tcx> {
248-
self.probe_for_name(
251+
let pick = self.probe_for_name(
249252
probe::Mode::MethodCall,
250253
method_name,
251254
IsSuggestion(false),
252255
self_ty,
253256
call_expr.hir_id,
254257
scope,
255-
)
258+
)?;
259+
pick.emit_unstable_name_collision_hint(self.tcx, method_name.span, call_expr.hir_id);
260+
Ok(pick)
256261
}
257262

258263
pub(super) fn obligation_for_method(
@@ -577,13 +582,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
577582

578583
let pick = self.probe_for_name(
579584
probe::Mode::Path,
580-
method_name.with_span_pos(span),
585+
method_name,
581586
IsSuggestion(false),
582587
self_ty,
583588
expr_id,
584589
ProbeScope::TraitsInScope,
585590
)?;
586591

592+
pick.emit_unstable_name_collision_hint(self.tcx, span, expr_id);
593+
587594
self.lint_fully_qualified_call_from_2018(
588595
span,
589596
method_name,

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ struct ProbeContext<'a, 'tcx> {
8383
unsatisfied_predicates:
8484
Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
8585

86-
is_suggestion: IsSuggestion,
87-
8886
scope_expr_id: hir::HirId,
8987
}
9088

@@ -209,6 +207,9 @@ pub struct Pick<'tcx> {
209207
/// `*mut T`, convert it to `*const T`.
210208
pub autoref_or_ptr_adjustment: Option<AutorefOrPtrAdjustment>,
211209
pub self_ty: Ty<'tcx>,
210+
211+
/// Unstable candidates alongside the stable ones.
212+
unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>,
212213
}
213214

214215
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -445,7 +446,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
445446
return_type,
446447
orig_values,
447448
steps.steps,
448-
is_suggestion,
449449
scope_expr_id,
450450
);
451451

@@ -540,7 +540,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
540540
return_type: Option<Ty<'tcx>>,
541541
orig_steps_var_values: OriginalQueryValues<'tcx>,
542542
steps: &'tcx [CandidateStep<'tcx>],
543-
is_suggestion: IsSuggestion,
544543
scope_expr_id: hir::HirId,
545544
) -> ProbeContext<'a, 'tcx> {
546545
ProbeContext {
@@ -558,7 +557,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
558557
allow_similar_names: false,
559558
private_candidate: None,
560559
unsatisfied_predicates: Vec::new(),
561-
is_suggestion,
562560
scope_expr_id,
563561
}
564562
}
@@ -880,7 +878,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
880878
}
881879
}
882880

883-
pub fn matches_return_type(
881+
fn matches_return_type(
884882
&self,
885883
method: &ty::AssocItem,
886884
self_ty: Option<Ty<'tcx>>,
@@ -1051,26 +1049,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
10511049
}
10521050

10531051
fn pick_core(&mut self) -> Option<PickResult<'tcx>> {
1054-
let mut unstable_candidates = Vec::new();
1055-
let pick = self.pick_all_method(Some(&mut unstable_candidates));
1052+
let pick = self.pick_all_method(Some(&mut vec![]));
10561053

10571054
// In this case unstable picking is done by `pick_method`.
10581055
if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable {
10591056
return pick;
10601057
}
10611058

1062-
match pick {
1063-
// Emit a lint if there are unstable candidates alongside the stable ones.
1064-
//
1065-
// We suppress warning if we're picking the method only because it is a
1066-
// suggestion.
1067-
Some(Ok(ref p)) if !self.is_suggestion.0 && !unstable_candidates.is_empty() => {
1068-
self.emit_unstable_name_collision_hint(p, &unstable_candidates);
1069-
pick
1070-
}
1071-
Some(_) => pick,
1072-
None => self.pick_all_method(None),
1059+
if pick.is_none() {
1060+
return self.pick_all_method(None);
10731061
}
1062+
pick
10741063
}
10751064

10761065
fn pick_all_method(
@@ -1215,7 +1204,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12151204
debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty));
12161205

12171206
let mut possibly_unsatisfied_predicates = Vec::new();
1218-
let mut unstable_candidates = Vec::new();
12191207

12201208
for (kind, candidates) in
12211209
&[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
@@ -1225,26 +1213,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12251213
self_ty,
12261214
candidates.iter(),
12271215
&mut possibly_unsatisfied_predicates,
1228-
Some(&mut unstable_candidates),
1216+
Some(&mut vec![]),
12291217
);
1230-
if let Some(pick) = res {
1231-
if !self.is_suggestion.0 && !unstable_candidates.is_empty() {
1232-
if let Ok(p) = &pick {
1233-
// Emit a lint if there are unstable candidates alongside the stable ones.
1234-
//
1235-
// We suppress warning if we're picking the method only because it is a
1236-
// suggestion.
1237-
self.emit_unstable_name_collision_hint(p, &unstable_candidates);
1238-
}
1239-
}
1240-
return Some(pick);
1218+
if res.is_some() {
1219+
return res;
12411220
}
12421221
}
12431222

12441223
debug!("searching unstable candidates");
12451224
let res = self.consider_candidates(
12461225
self_ty,
1247-
unstable_candidates.iter().map(|(c, _)| c),
1226+
self.inherent_candidates.iter().chain(&self.extension_candidates),
12481227
&mut possibly_unsatisfied_predicates,
12491228
None,
12501229
);
@@ -1299,7 +1278,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12991278
Option<ty::Predicate<'tcx>>,
13001279
Option<ObligationCause<'tcx>>,
13011280
)>,
1302-
unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
1281+
mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
13031282
) -> Option<PickResult<'tcx>>
13041283
where
13051284
ProbesIter: Iterator<Item = &'b Candidate<'tcx>> + Clone,
@@ -1323,7 +1302,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13231302
}
13241303
}
13251304

1326-
if let Some(uc) = unstable_candidates {
1305+
if let Some(uc) = &mut unstable_candidates {
13271306
applicable_candidates.retain(|&(p, _)| {
13281307
if let stability::EvalResult::Deny { feature, .. } =
13291308
self.tcx.eval_stability(p.item.def_id, None, self.span, None)
@@ -1342,30 +1321,37 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13421321

13431322
applicable_candidates.pop().map(|(probe, status)| {
13441323
if status == ProbeResult::Match {
1345-
Ok(probe.to_unadjusted_pick(self_ty))
1324+
Ok(probe
1325+
.to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default()))
13461326
} else {
13471327
Err(MethodError::BadReturnType)
13481328
}
13491329
})
13501330
}
1331+
}
13511332

1352-
fn emit_unstable_name_collision_hint(
1333+
impl<'tcx> Pick<'tcx> {
1334+
pub fn emit_unstable_name_collision_hint(
13531335
&self,
1354-
stable_pick: &Pick<'_>,
1355-
unstable_candidates: &[(Candidate<'tcx>, Symbol)],
1336+
tcx: TyCtxt<'tcx>,
1337+
span: Span,
1338+
scope_expr_id: hir::HirId,
13561339
) {
1357-
let def_kind = stable_pick.item.kind.as_def_kind();
1358-
self.tcx.struct_span_lint_hir(
1340+
if self.unstable_candidates.is_empty() {
1341+
return;
1342+
}
1343+
let def_kind = self.item.kind.as_def_kind();
1344+
tcx.struct_span_lint_hir(
13591345
lint::builtin::UNSTABLE_NAME_COLLISIONS,
1360-
self.scope_expr_id,
1361-
self.span,
1346+
scope_expr_id,
1347+
span,
13621348
format!(
13631349
"{} {} with this name may be added to the standard library in the future",
13641350
def_kind.article(),
1365-
def_kind.descr(stable_pick.item.def_id),
1351+
def_kind.descr(self.item.def_id),
13661352
),
13671353
|lint| {
1368-
match (stable_pick.item.kind, stable_pick.item.container) {
1354+
match (self.item.kind, self.item.container) {
13691355
(ty::AssocKind::Fn, _) => {
13701356
// FIXME: This should be a `span_suggestion` instead of `help`
13711357
// However `self.span` only
@@ -1374,31 +1360,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13741360
lint.help(&format!(
13751361
"call with fully qualified syntax `{}(...)` to keep using the current \
13761362
method",
1377-
self.tcx.def_path_str(stable_pick.item.def_id),
1363+
tcx.def_path_str(self.item.def_id),
13781364
));
13791365
}
13801366
(ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => {
1381-
let def_id = stable_pick.item.container_id(self.tcx);
1367+
let def_id = self.item.container_id(tcx);
13821368
lint.span_suggestion(
1383-
self.span,
1369+
span,
13841370
"use the fully qualified path to the associated const",
13851371
format!(
13861372
"<{} as {}>::{}",
1387-
stable_pick.self_ty,
1388-
self.tcx.def_path_str(def_id),
1389-
stable_pick.item.name
1373+
self.self_ty,
1374+
tcx.def_path_str(def_id),
1375+
self.item.name
13901376
),
13911377
Applicability::MachineApplicable,
13921378
);
13931379
}
13941380
_ => {}
13951381
}
1396-
if self.tcx.sess.is_nightly_build() {
1397-
for (candidate, feature) in unstable_candidates {
1382+
if tcx.sess.is_nightly_build() {
1383+
for (candidate, feature) in &self.unstable_candidates {
13981384
lint.help(&format!(
13991385
"add `#![feature({})]` to the crate attributes to enable `{}`",
14001386
feature,
1401-
self.tcx.def_path_str(candidate.item.def_id),
1387+
tcx.def_path_str(candidate.item.def_id),
14021388
));
14031389
}
14041390
}
@@ -1407,7 +1393,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14071393
},
14081394
);
14091395
}
1396+
}
14101397

1398+
impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14111399
fn select_trait_candidate(
14121400
&self,
14131401
trait_ref: ty::TraitRef<'tcx>,
@@ -1666,6 +1654,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16661654
autoderefs: 0,
16671655
autoref_or_ptr_adjustment: None,
16681656
self_ty,
1657+
unstable_candidates: vec![],
16691658
})
16701659
}
16711660

@@ -1685,7 +1674,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16851674
self.return_type,
16861675
self.orig_steps_var_values.clone(),
16871676
steps,
1688-
IsSuggestion(true),
16891677
self.scope_expr_id,
16901678
);
16911679
pcx.allow_similar_names = true;
@@ -1893,7 +1881,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
18931881
}
18941882

18951883
impl<'tcx> Candidate<'tcx> {
1896-
fn to_unadjusted_pick(&self, self_ty: Ty<'tcx>) -> Pick<'tcx> {
1884+
fn to_unadjusted_pick(
1885+
&self,
1886+
self_ty: Ty<'tcx>,
1887+
unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>,
1888+
) -> Pick<'tcx> {
18971889
Pick {
18981890
item: self.item,
18991891
kind: match self.kind {
@@ -1918,6 +1910,7 @@ impl<'tcx> Candidate<'tcx> {
19181910
autoderefs: 0,
19191911
autoref_or_ptr_adjustment: None,
19201912
self_ty,
1913+
unstable_candidates,
19211914
}
19221915
}
19231916
}

0 commit comments

Comments
 (0)