Skip to content

Commit 6b3cd03

Browse files
committed
Auto merge of #107215 - Dylan-DPC:rollup-zqtiufk, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #104926 (Move relationships from FulfillmentContext to Inherited) - #106854 (Add `Arc::into_inner` for safely discarding `Arc`s without calling the destructor on the inner type.) - #107108 (Consider doc(alias) when providing typo suggestions) - #107186 (rustdoc: Use correct pseudo-element selector) - #107192 (Add myself to the mailmap) - #107195 (Fix typo in universal_regions.rs comment) - #107203 (Suggest remove deref for type mismatch) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents ad48c10 + 66d6a0b commit 6b3cd03

File tree

27 files changed

+465
-136
lines changed

27 files changed

+465
-136
lines changed

.mailmap

+1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ Lennart Kudling <[email protected]>
325325
Léo Lanteri Thauvin <[email protected]>
326326
Léo Lanteri Thauvin <[email protected]> <[email protected]>
327327
Léo Testard <[email protected]>
328+
León Orell Valerian Liehr <[email protected]> <[email protected]>
328329
Leonardo Yvens <[email protected]>
329330
Liigo Zhuang <[email protected]>
330331

compiler/rustc_borrowck/src/universal_regions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ struct UniversalRegionIndices<'tcx> {
162162
/// `ty::Region` to the internal `RegionVid` we are using. This is
163163
/// used because trait matching and type-checking will feed us
164164
/// region constraints that reference those regions and we need to
165-
/// be able to map them our internal `RegionVid`. This is
165+
/// be able to map them to our internal `RegionVid`. This is
166166
/// basically equivalent to an `InternalSubsts`, except that it also
167167
/// contains an entry for `ReStatic` -- it might be nice to just
168168
/// use a substs, and then handle `ReStatic` another way.

compiler/rustc_hir_typeck/src/demand.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12331233
sugg_sp = receiver.span;
12341234
}
12351235
}
1236+
1237+
if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner) = expr.kind
1238+
&& let Some(1) = self.deref_steps(expected, checked_ty) {
1239+
// We have `*&T`, check if what was expected was `&T`.
1240+
// If so, we may want to suggest removing a `*`.
1241+
sugg_sp = sugg_sp.with_hi(inner.span.lo());
1242+
return Some((
1243+
sugg_sp,
1244+
"consider removing deref here".to_string(),
1245+
"".to_string(),
1246+
Applicability::MachineApplicable,
1247+
true,
1248+
false,
1249+
));
1250+
}
1251+
12361252
if let Ok(src) = sm.span_to_snippet(sugg_sp) {
12371253
let needs_parens = match expr.kind {
12381254
// parenthesize if needed (Issue #46756)

compiler/rustc_hir_typeck/src/fallback.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
196196
) -> FxHashMap<Ty<'tcx>, Ty<'tcx>> {
197197
debug!("calculate_diverging_fallback({:?})", unsolved_variables);
198198

199-
let relationships = self.fulfillment_cx.borrow_mut().relationships().clone();
200-
201199
// Construct a coercion graph where an edge `A -> B` indicates
202200
// a type variable is that is coerced
203201
let coercion_graph = self.create_coercion_graph();
@@ -281,9 +279,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
281279
roots_reachable_from_non_diverging,
282280
);
283281

284-
debug!("inherited: {:#?}", self.inh.fulfillment_cx.borrow_mut().pending_obligations());
285282
debug!("obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations());
286-
debug!("relationships: {:#?}", relationships);
287283

288284
// For each diverging variable, figure out whether it can
289285
// reach a member of N. If so, it falls back to `()`. Else
@@ -297,16 +293,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
297293
.depth_first_search(root_vid)
298294
.any(|n| roots_reachable_from_non_diverging.visited(n));
299295

300-
let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false };
296+
let mut found_infer_var_info = ty::InferVarInfo { self_in_trait: false, output: false };
301297

302-
for (vid, rel) in relationships.iter() {
303-
if self.root_var(*vid) == root_vid {
304-
relationship.self_in_trait |= rel.self_in_trait;
305-
relationship.output |= rel.output;
298+
for (vid, info) in self.inh.infer_var_info.borrow().iter() {
299+
if self.infcx.root_var(*vid) == root_vid {
300+
found_infer_var_info.self_in_trait |= info.self_in_trait;
301+
found_infer_var_info.output |= info.output;
306302
}
307303
}
308304

309-
if relationship.self_in_trait && relationship.output {
305+
if found_infer_var_info.self_in_trait && found_infer_var_info.output {
310306
// This case falls back to () to ensure that the code pattern in
311307
// tests/ui/never_type/fallback-closure-ret.rs continues to
312308
// compile when never_type_fallback is enabled.

compiler/rustc_hir_typeck/src/inherited.rs

+48-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::callee::DeferredCallResolution;
22

3-
use rustc_data_structures::fx::FxHashSet;
3+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44
use rustc_hir as hir;
55
use rustc_hir::def_id::LocalDefId;
66
use rustc_hir::HirIdMap;
@@ -10,7 +10,8 @@ use rustc_middle::ty::visit::TypeVisitable;
1010
use rustc_middle::ty::{self, Ty, TyCtxt};
1111
use rustc_span::def_id::LocalDefIdMap;
1212
use rustc_span::{self, Span};
13-
use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
13+
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
14+
use rustc_trait_selection::traits::{self, PredicateObligation, TraitEngine, TraitEngineExt as _};
1415

1516
use std::cell::RefCell;
1617
use std::ops::Deref;
@@ -63,6 +64,8 @@ pub struct Inherited<'tcx> {
6364
/// we record that type variable here. This is later used to inform
6465
/// fallback. See the `fallback` module for details.
6566
pub(super) diverging_type_vars: RefCell<FxHashSet<Ty<'tcx>>>,
67+
68+
pub(super) infer_var_info: RefCell<FxHashMap<ty::TyVid, ty::InferVarInfo>>,
6669
}
6770

6871
impl<'tcx> Deref for Inherited<'tcx> {
@@ -128,6 +131,7 @@ impl<'tcx> Inherited<'tcx> {
128131
deferred_generator_interiors: RefCell::new(Vec::new()),
129132
diverging_type_vars: RefCell::new(Default::default()),
130133
body_id,
134+
infer_var_info: RefCell::new(Default::default()),
131135
}
132136
}
133137

@@ -136,6 +140,9 @@ impl<'tcx> Inherited<'tcx> {
136140
if obligation.has_escaping_bound_vars() {
137141
span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
138142
}
143+
144+
self.update_infer_var_info(&obligation);
145+
139146
self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
140147
}
141148

@@ -152,4 +159,43 @@ impl<'tcx> Inherited<'tcx> {
152159
self.register_predicates(infer_ok.obligations);
153160
infer_ok.value
154161
}
162+
163+
pub fn update_infer_var_info(&self, obligation: &PredicateObligation<'tcx>) {
164+
let infer_var_info = &mut self.infer_var_info.borrow_mut();
165+
166+
// (*) binder skipped
167+
if let ty::PredicateKind::Clause(ty::Clause::Trait(tpred)) = obligation.predicate.kind().skip_binder()
168+
&& let Some(ty) = self.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| self.root_var(t))
169+
&& self.tcx.lang_items().sized_trait().map_or(false, |st| st != tpred.trait_ref.def_id)
170+
{
171+
let new_self_ty = self.tcx.types.unit;
172+
173+
// Then construct a new obligation with Self = () added
174+
// to the ParamEnv, and see if it holds.
175+
let o = obligation.with(self.tcx,
176+
obligation
177+
.predicate
178+
.kind()
179+
.rebind(
180+
// (*) binder moved here
181+
ty::PredicateKind::Clause(ty::Clause::Trait(tpred.with_self_ty(self.tcx, new_self_ty)))
182+
),
183+
);
184+
// Don't report overflow errors. Otherwise equivalent to may_hold.
185+
if let Ok(result) = self.probe(|_| self.evaluate_obligation(&o)) && result.may_apply() {
186+
infer_var_info.entry(ty).or_default().self_in_trait = true;
187+
}
188+
}
189+
190+
if let ty::PredicateKind::Clause(ty::Clause::Projection(predicate)) =
191+
obligation.predicate.kind().skip_binder()
192+
{
193+
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
194+
// we need to make it into one.
195+
if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) {
196+
debug!("infer_var_info: {:?}.output = true", vid);
197+
infer_var_info.entry(vid).or_default().output = true;
198+
}
199+
}
200+
}
155201
}

compiler/rustc_hir_typeck/src/method/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub struct NoMatchData<'tcx> {
7676
pub unsatisfied_predicates:
7777
Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
7878
pub out_of_scope_traits: Vec<DefId>,
79-
pub lev_candidate: Option<ty::AssocItem>,
79+
pub similar_candidate: Option<ty::AssocItem>,
8080
pub mode: probe::Mode,
8181
}
8282

compiler/rustc_hir_typeck/src/method/probe.rs

+45-4
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
461461
static_candidates: Vec::new(),
462462
unsatisfied_predicates: Vec::new(),
463463
out_of_scope_traits: Vec::new(),
464-
lev_candidate: None,
464+
similar_candidate: None,
465465
mode,
466466
}));
467467
}
@@ -1076,13 +1076,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
10761076
if let Some((kind, def_id)) = private_candidate {
10771077
return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits));
10781078
}
1079-
let lev_candidate = self.probe_for_lev_candidate()?;
1079+
let similar_candidate = self.probe_for_similar_candidate()?;
10801080

10811081
Err(MethodError::NoMatch(NoMatchData {
10821082
static_candidates,
10831083
unsatisfied_predicates,
10841084
out_of_scope_traits,
1085-
lev_candidate,
1085+
similar_candidate,
10861086
mode: self.mode,
10871087
}))
10881088
}
@@ -1787,7 +1787,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
17871787
/// Similarly to `probe_for_return_type`, this method attempts to find the best matching
17881788
/// candidate method where the method name may have been misspelled. Similarly to other
17891789
/// Levenshtein based suggestions, we provide at most one such suggestion.
1790-
fn probe_for_lev_candidate(&mut self) -> Result<Option<ty::AssocItem>, MethodError<'tcx>> {
1790+
fn probe_for_similar_candidate(&mut self) -> Result<Option<ty::AssocItem>, MethodError<'tcx>> {
17911791
debug!("probing for method names similar to {:?}", self.method_name);
17921792

17931793
let steps = self.steps.clone();
@@ -1831,6 +1831,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
18311831
None,
18321832
)
18331833
}
1834+
.or_else(|| {
1835+
applicable_close_candidates
1836+
.iter()
1837+
.find(|cand| self.matches_by_doc_alias(cand.def_id))
1838+
.map(|cand| cand.name)
1839+
})
18341840
.unwrap();
18351841
Ok(applicable_close_candidates.into_iter().find(|method| method.name == best_name))
18361842
}
@@ -1981,6 +1987,38 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
19811987
}
19821988
}
19831989

1990+
/// Determine if the associated item withe the given DefId matches
1991+
/// the desired name via a doc alias.
1992+
fn matches_by_doc_alias(&self, def_id: DefId) -> bool {
1993+
let Some(name) = self.method_name else { return false; };
1994+
let Some(local_def_id) = def_id.as_local() else { return false; };
1995+
let hir_id = self.fcx.tcx.hir().local_def_id_to_hir_id(local_def_id);
1996+
let attrs = self.fcx.tcx.hir().attrs(hir_id);
1997+
for attr in attrs {
1998+
let sym::doc = attr.name_or_empty() else { continue; };
1999+
let Some(values) = attr.meta_item_list() else { continue; };
2000+
for v in values {
2001+
if v.name_or_empty() != sym::alias {
2002+
continue;
2003+
}
2004+
if let Some(nested) = v.meta_item_list() {
2005+
// #[doc(alias("foo", "bar"))]
2006+
for n in nested {
2007+
if let Some(lit) = n.lit() && name.as_str() == lit.symbol.as_str() {
2008+
return true;
2009+
}
2010+
}
2011+
} else if let Some(meta) = v.meta_item()
2012+
&& let Some(lit) = meta.name_value_literal()
2013+
&& name.as_str() == lit.symbol.as_str() {
2014+
// #[doc(alias = "foo")]
2015+
return true;
2016+
}
2017+
}
2018+
}
2019+
false
2020+
}
2021+
19842022
/// Finds the method with the appropriate name (or return type, as the case may be). If
19852023
/// `allow_similar_names` is set, find methods with close-matching names.
19862024
// The length of the returned iterator is nearly always 0 or 1 and this
@@ -1996,6 +2034,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
19962034
if !self.is_relevant_kind_for_mode(x.kind) {
19972035
return false;
19982036
}
2037+
if self.matches_by_doc_alias(x.def_id) {
2038+
return true;
2039+
}
19992040
match lev_distance_with_substrings(name.as_str(), x.name.as_str(), max_dist)
20002041
{
20012042
Some(d) => d > 0,

compiler/rustc_hir_typeck/src/method/suggest.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
262262
let ty_str = with_forced_trimmed_paths!(self.ty_to_string(rcvr_ty));
263263
let is_method = mode == Mode::MethodCall;
264264
let unsatisfied_predicates = &no_match_data.unsatisfied_predicates;
265-
let lev_candidate = no_match_data.lev_candidate;
265+
let similar_candidate = no_match_data.similar_candidate;
266266
let item_kind = if is_method {
267267
"method"
268268
} else if rcvr_ty.is_enum() {
@@ -937,7 +937,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
937937
// give a helping note that it has to be called as `(x.f)(...)`.
938938
if let SelfSource::MethodCall(expr) = source {
939939
if !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_name, &mut err)
940-
&& lev_candidate.is_none()
940+
&& similar_candidate.is_none()
941941
&& !custom_span_label
942942
{
943943
label_span_not_found(&mut err);
@@ -1015,20 +1015,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10151015
if fallback_span {
10161016
err.span_label(span, msg);
10171017
}
1018-
} else if let Some(lev_candidate) = lev_candidate {
1018+
} else if let Some(similar_candidate) = similar_candidate {
10191019
// Don't emit a suggestion if we found an actual method
10201020
// that had unsatisfied trait bounds
10211021
if unsatisfied_predicates.is_empty() {
1022-
let def_kind = lev_candidate.kind.as_def_kind();
1022+
let def_kind = similar_candidate.kind.as_def_kind();
10231023
// Methods are defined within the context of a struct and their first parameter is always self,
10241024
// which represents the instance of the struct the method is being called on
10251025
// Associated functions don’t take self as a parameter and
10261026
// they are not methods because they don’t have an instance of the struct to work with.
1027-
if def_kind == DefKind::AssocFn && lev_candidate.fn_has_self_parameter {
1027+
if def_kind == DefKind::AssocFn && similar_candidate.fn_has_self_parameter {
10281028
err.span_suggestion(
10291029
span,
10301030
"there is a method with a similar name",
1031-
lev_candidate.name,
1031+
similar_candidate.name,
10321032
Applicability::MaybeIncorrect,
10331033
);
10341034
} else {
@@ -1037,9 +1037,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10371037
&format!(
10381038
"there is {} {} with a similar name",
10391039
def_kind.article(),
1040-
def_kind.descr(lev_candidate.def_id),
1040+
def_kind.descr(similar_candidate.def_id),
10411041
),
1042-
lev_candidate.name,
1042+
similar_candidate.name,
10431043
Applicability::MaybeIncorrect,
10441044
);
10451045
}

compiler/rustc_infer/src/traits/engine.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::infer::InferCtxt;
22
use crate::traits::Obligation;
3-
use rustc_data_structures::fx::FxHashMap;
43
use rustc_hir::def_id::DefId;
54
use rustc_middle::ty::{self, ToPredicate, Ty};
65

@@ -42,8 +41,6 @@ pub trait TraitEngine<'tcx>: 'tcx {
4241
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
4342

4443
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
45-
46-
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships>;
4744
}
4845

4946
pub trait TraitEngineExt<'tcx> {

compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2619,7 +2619,7 @@ impl<'tcx> fmt::Debug for SymbolName<'tcx> {
26192619
}
26202620

26212621
#[derive(Debug, Default, Copy, Clone)]
2622-
pub struct FoundRelationships {
2622+
pub struct InferVarInfo {
26232623
/// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
26242624
/// obligation, where:
26252625
///

compiler/rustc_trait_selection/src/solve/fulfill.rs

-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use std::mem;
22

3-
use rustc_data_structures::fx::FxHashMap;
43
use rustc_infer::{
54
infer::InferCtxt,
65
traits::{
76
query::NoSolution, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
87
SelectionError, TraitEngine,
98
},
109
};
11-
use rustc_middle::ty;
1210

1311
use super::{search_graph, Certainty, EvalCtxt};
1412

@@ -102,8 +100,4 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
102100
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
103101
self.obligations.clone()
104102
}
105-
106-
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
107-
unimplemented!("Should be moved out of `TraitEngine`")
108-
}
109103
}

0 commit comments

Comments
 (0)