Skip to content

Commit e249ce6

Browse files
committed
Auto merge of rust-lang#90422 - GuillaumeGomez:rollup-s1mdag0, r=GuillaumeGomez
Rollup of 5 pull requests Successful merges: - rust-lang#90156 (Remove underlines from non-top docblocks.) - rust-lang#90183 (Show all Deref implementations recursively) - rust-lang#90202 (Improve and test cross-crate hygiene) - rust-lang#90375 (Use `is_global` in `candidate_should_be_dropped_in_favor_of`) - rust-lang#90399 (Skipping verbose diagnostic suggestions when calling .as_ref() on type not implementing AsRef) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 2609fab + 197da45 commit e249ce6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+968
-71
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1198,8 +1198,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11981198
}
11991199
}
12001200

1201-
if let EntryKind::Mod(data) = kind {
1202-
for exp in data.decode((self, sess)).reexports.decode((self, sess)) {
1201+
if let EntryKind::Mod(exports) = kind {
1202+
for exp in exports.decode((self, sess)) {
12031203
match exp.res {
12041204
Res::Def(DefKind::Macro(..), _) => {}
12051205
_ if macros_only => continue,
@@ -1219,10 +1219,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12191219
}
12201220

12211221
fn module_expansion(&self, id: DefIndex, sess: &Session) -> ExpnId {
1222-
if let EntryKind::Mod(m) = self.kind(id) {
1223-
m.decode((self, sess)).expansion
1224-
} else {
1225-
panic!("Expected module, found {:?}", self.local_def_id(id))
1222+
match self.kind(id) {
1223+
EntryKind::Mod(_) | EntryKind::Enum(_) | EntryKind::Trait(_) => {
1224+
self.get_expn_that_defined(id, sess)
1225+
}
1226+
_ => panic!("Expected module, found {:?}", self.local_def_id(id)),
12261227
}
12271228
}
12281229

compiler/rustc_metadata/src/rmeta/encoder.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1086,11 +1086,11 @@ impl EncodeContext<'a, 'tcx> {
10861086
Lazy::empty()
10871087
};
10881088

1089-
let data = ModData { reexports, expansion: tcx.expn_that_defined(local_def_id) };
1090-
1091-
record!(self.tables.kind[def_id] <- EntryKind::Mod(self.lazy(data)));
1089+
record!(self.tables.kind[def_id] <- EntryKind::Mod(reexports));
10921090
if self.is_proc_macro {
10931091
record!(self.tables.children[def_id] <- &[]);
1092+
// Encode this here because we don't do it in encode_def_ids.
1093+
record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
10941094
} else {
10951095
record!(self.tables.children[def_id] <- md.item_ids.iter().map(|item_id| {
10961096
item_id.def_id.local_def_index

compiler/rustc_metadata/src/rmeta/mod.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ enum EntryKind {
346346
Union(Lazy<VariantData>, ReprOptions),
347347
Fn(Lazy<FnData>),
348348
ForeignFn(Lazy<FnData>),
349-
Mod(Lazy<ModData>),
349+
Mod(Lazy<[Export]>),
350350
MacroDef(Lazy<MacroDef>),
351351
ProcMacro(MacroKind),
352352
Closure,
@@ -364,12 +364,6 @@ enum EntryKind {
364364
#[derive(Encodable, Decodable)]
365365
struct RenderedConst(String);
366366

367-
#[derive(MetadataEncodable, MetadataDecodable)]
368-
struct ModData {
369-
reexports: Lazy<[Export]>,
370-
expansion: ExpnId,
371-
}
372-
373367
#[derive(MetadataEncodable, MetadataDecodable)]
374368
struct FnData {
375369
asyncness: hir::IsAsync,

compiler/rustc_resolve/src/build_reduced_graph.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,11 @@ impl<'a> Resolver<'a> {
145145
} else {
146146
def_key.disambiguated_data.data.get_opt_name().expect("module without name")
147147
};
148-
let expn_id = if def_kind == DefKind::Mod {
149-
self.cstore().module_expansion_untracked(def_id, &self.session)
150-
} else {
151-
// FIXME: Parent expansions for enums and traits are not kept in metadata.
152-
ExpnId::root()
153-
};
154148

155149
Some(self.new_module(
156150
parent,
157151
ModuleKind::Def(def_kind, def_id, name),
158-
expn_id,
152+
self.cstore().module_expansion_untracked(def_id, &self.session),
159153
self.cstore().get_span_untracked(def_id, &self.session),
160154
// FIXME: Account for `#[no_implicit_prelude]` attributes.
161155
parent.map_or(false, |module| module.no_implicit_prelude),

compiler/rustc_resolve/src/diagnostics.rs

+2
Original file line numberDiff line numberDiff line change
@@ -842,9 +842,11 @@ impl<'a> Resolver<'a> {
842842

843843
// collect results based on the filter function
844844
// avoid suggesting anything from the same module in which we are resolving
845+
// avoid suggesting anything with a hygienic name
845846
if ident.name == lookup_ident.name
846847
&& ns == namespace
847848
&& !ptr::eq(in_module, parent_scope.module)
849+
&& !ident.span.normalize_to_macros_2_0().from_expansion()
848850
{
849851
let res = name_binding.res();
850852
if filter_fn(res) {

compiler/rustc_span/src/hygiene.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ impl SyntaxContext {
709709
/// pub fn f() {} // `f`'s `SyntaxContext` has a single `ExpnId` from `m`.
710710
/// pub fn $i() {} // `$i`'s `SyntaxContext` is empty.
711711
/// }
712-
/// n(f);
712+
/// n!(f);
713713
/// macro n($j:ident) {
714714
/// use foo::*;
715715
/// f(); // `f`'s `SyntaxContext` has a mark from `m` and a mark from `n`

compiler/rustc_trait_selection/src/traits/select/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1547,8 +1547,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15471547
// Check if a bound would previously have been removed when normalizing
15481548
// the param_env so that it can be given the lowest priority. See
15491549
// #50825 for the motivation for this.
1550-
let is_global =
1551-
|cand: &ty::PolyTraitRef<'_>| cand.is_known_global() && !cand.has_late_bound_regions();
1550+
let is_global = |cand: &ty::PolyTraitRef<'tcx>| {
1551+
cand.is_global(self.infcx.tcx) && !cand.has_late_bound_regions()
1552+
};
15521553

15531554
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
15541555
// and `DiscriminantKindCandidate` to anything else.

compiler/rustc_typeck/src/check/method/suggest.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_middle::ty::print::with_crate_prefix;
1515
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
1616
use rustc_span::lev_distance;
1717
use rustc_span::symbol::{kw, sym, Ident};
18-
use rustc_span::{source_map, FileName, MultiSpan, Span};
18+
use rustc_span::{source_map, FileName, MultiSpan, Span, Symbol};
1919
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
2020
use rustc_trait_selection::traits::{FulfillmentError, Obligation};
2121

@@ -1251,6 +1251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12511251
self.tcx.lang_items().deref_trait(),
12521252
self.tcx.lang_items().deref_mut_trait(),
12531253
self.tcx.lang_items().drop_trait(),
1254+
self.tcx.get_diagnostic_item(sym::AsRef),
12541255
];
12551256
// Try alternative arbitrary self types that could fulfill this call.
12561257
// FIXME: probe for all types that *could* be arbitrary self-types, not
@@ -1300,7 +1301,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13001301
// We don't want to suggest a container type when the missing
13011302
// method is `.clone()` or `.deref()` otherwise we'd suggest
13021303
// `Arc::new(foo).clone()`, which is far from what the user wants.
1303-
let skip = skippable.contains(&did);
1304+
// Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
1305+
// implement the `AsRef` trait.
1306+
let skip = skippable.contains(&did)
1307+
|| (("Pin::new" == *pre)
1308+
&& (Symbol::intern("as_ref") == item_name.name));
13041309
// Make sure the method is defined for the *actual* receiver: we don't
13051310
// want to treat `Box<Self>` as a receiver if it only works because of
13061311
// an autoderef to `&self`

src/librustdoc/html/render/context.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::rc::Rc;
66
use std::sync::mpsc::{channel, Receiver};
77

88
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
9-
use rustc_hir::def_id::LOCAL_CRATE;
9+
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1010
use rustc_middle::ty::TyCtxt;
1111
use rustc_session::Session;
1212
use rustc_span::edition::Edition;
@@ -54,6 +54,9 @@ crate struct Context<'tcx> {
5454
/// real location of an item. This is used to allow external links to
5555
/// publicly reused items to redirect to the right location.
5656
pub(super) render_redirect_pages: bool,
57+
/// Tracks section IDs for `Deref` targets so they match in both the main
58+
/// body and the sidebar.
59+
pub(super) deref_id_map: RefCell<FxHashMap<DefId, String>>,
5760
/// The map used to ensure all generated 'id=' attributes are unique.
5861
pub(super) id_map: RefCell<IdMap>,
5962
/// Shared mutable state.
@@ -70,7 +73,7 @@ crate struct Context<'tcx> {
7073

7174
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
7275
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
73-
rustc_data_structures::static_assert_size!(Context<'_>, 104);
76+
rustc_data_structures::static_assert_size!(Context<'_>, 144);
7477

7578
/// Shared mutable state used in [`Context`] and elsewhere.
7679
crate struct SharedContext<'tcx> {
@@ -513,6 +516,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
513516
dst,
514517
render_redirect_pages: false,
515518
id_map: RefCell::new(id_map),
519+
deref_id_map: RefCell::new(FxHashMap::default()),
516520
shared: Rc::new(scx),
517521
include_sources,
518522
};
@@ -536,6 +540,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
536540
current: self.current.clone(),
537541
dst: self.dst.clone(),
538542
render_redirect_pages: self.render_redirect_pages,
543+
deref_id_map: RefCell::new(FxHashMap::default()),
539544
id_map: RefCell::new(IdMap::new()),
540545
shared: Rc::clone(&self.shared),
541546
include_sources: self.include_sources,

src/librustdoc/html/render/mod.rs

+78-16
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,19 @@ fn render_assoc_items(
10541054
containing_item: &clean::Item,
10551055
it: DefId,
10561056
what: AssocItemRender<'_>,
1057+
) {
1058+
let mut derefs = FxHashSet::default();
1059+
derefs.insert(it);
1060+
render_assoc_items_inner(w, cx, containing_item, it, what, &mut derefs)
1061+
}
1062+
1063+
fn render_assoc_items_inner(
1064+
w: &mut Buffer,
1065+
cx: &Context<'_>,
1066+
containing_item: &clean::Item,
1067+
it: DefId,
1068+
what: AssocItemRender<'_>,
1069+
derefs: &mut FxHashSet<DefId>,
10571070
) {
10581071
info!("Documenting associated items of {:?}", containing_item.name);
10591072
let cache = cx.cache();
@@ -1063,31 +1076,39 @@ fn render_assoc_items(
10631076
};
10641077
let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
10651078
if !non_trait.is_empty() {
1079+
let mut tmp_buf = Buffer::empty_from(w);
10661080
let render_mode = match what {
10671081
AssocItemRender::All => {
1068-
w.write_str(
1082+
tmp_buf.write_str(
10691083
"<h2 id=\"implementations\" class=\"small-section-header\">\
10701084
Implementations<a href=\"#implementations\" class=\"anchor\"></a>\
10711085
</h2>",
10721086
);
10731087
RenderMode::Normal
10741088
}
10751089
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
1090+
let id =
1091+
cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
1092+
if let Some(def_id) = type_.def_id(cx.cache()) {
1093+
cx.deref_id_map.borrow_mut().insert(def_id, id.clone());
1094+
}
10761095
write!(
1077-
w,
1078-
"<h2 id=\"deref-methods\" class=\"small-section-header\">\
1096+
tmp_buf,
1097+
"<h2 id=\"{id}\" class=\"small-section-header\">\
10791098
<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>\
1080-
<a href=\"#deref-methods\" class=\"anchor\"></a>\
1099+
<a href=\"#{id}\" class=\"anchor\"></a>\
10811100
</h2>",
1101+
id = id,
10821102
trait_ = trait_.print(cx),
10831103
type_ = type_.print(cx),
10841104
);
10851105
RenderMode::ForDeref { mut_: deref_mut_ }
10861106
}
10871107
};
1108+
let mut impls_buf = Buffer::empty_from(w);
10881109
for i in &non_trait {
10891110
render_impl(
1090-
w,
1111+
&mut impls_buf,
10911112
cx,
10921113
i,
10931114
containing_item,
@@ -1104,18 +1125,27 @@ fn render_assoc_items(
11041125
},
11051126
);
11061127
}
1128+
if !impls_buf.is_empty() {
1129+
w.push_buffer(tmp_buf);
1130+
w.push_buffer(impls_buf);
1131+
}
11071132
}
1108-
if let AssocItemRender::DerefFor { .. } = what {
1109-
return;
1110-
}
1133+
11111134
if !traits.is_empty() {
11121135
let deref_impl =
11131136
traits.iter().find(|t| t.trait_did() == cx.tcx().lang_items().deref_trait());
11141137
if let Some(impl_) = deref_impl {
11151138
let has_deref_mut =
11161139
traits.iter().any(|t| t.trait_did() == cx.tcx().lang_items().deref_mut_trait());
1117-
render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
1140+
render_deref_methods(w, cx, impl_, containing_item, has_deref_mut, derefs);
1141+
}
1142+
1143+
// If we were already one level into rendering deref methods, we don't want to render
1144+
// anything after recursing into any further deref methods above.
1145+
if let AssocItemRender::DerefFor { .. } = what {
1146+
return;
11181147
}
1148+
11191149
let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
11201150
traits.iter().partition(|t| t.inner_impl().synthetic);
11211151
let (blanket_impl, concrete): (Vec<&&Impl>, _) =
@@ -1167,6 +1197,7 @@ fn render_deref_methods(
11671197
impl_: &Impl,
11681198
container_item: &clean::Item,
11691199
deref_mut: bool,
1200+
derefs: &mut FxHashSet<DefId>,
11701201
) {
11711202
let cache = cx.cache();
11721203
let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
@@ -1188,16 +1219,16 @@ fn render_deref_methods(
11881219
if let Some(did) = target.def_id(cache) {
11891220
if let Some(type_did) = impl_.inner_impl().for_.def_id(cache) {
11901221
// `impl Deref<Target = S> for S`
1191-
if did == type_did {
1222+
if did == type_did || !derefs.insert(did) {
11921223
// Avoid infinite cycles
11931224
return;
11941225
}
11951226
}
1196-
render_assoc_items(w, cx, container_item, did, what);
1227+
render_assoc_items_inner(w, cx, container_item, did, what, derefs);
11971228
} else {
11981229
if let Some(prim) = target.primitive_type() {
11991230
if let Some(&did) = cache.primitive_locations.get(&prim) {
1200-
render_assoc_items(w, cx, container_item, did, what);
1231+
render_assoc_items_inner(w, cx, container_item, did, what, derefs);
12011232
}
12021233
}
12031234
}
@@ -1987,7 +2018,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
19872018
if let Some(impl_) =
19882019
v.iter().find(|i| i.trait_did() == cx.tcx().lang_items().deref_trait())
19892020
{
1990-
sidebar_deref_methods(cx, out, impl_, v);
2021+
let mut derefs = FxHashSet::default();
2022+
derefs.insert(did);
2023+
sidebar_deref_methods(cx, out, impl_, v, &mut derefs);
19912024
}
19922025

19932026
let format_impls = |impls: Vec<&Impl>| {
@@ -2061,7 +2094,13 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
20612094
}
20622095
}
20632096

2064-
fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &[Impl]) {
2097+
fn sidebar_deref_methods(
2098+
cx: &Context<'_>,
2099+
out: &mut Buffer,
2100+
impl_: &Impl,
2101+
v: &[Impl],
2102+
derefs: &mut FxHashSet<DefId>,
2103+
) {
20652104
let c = cx.cache();
20662105

20672106
debug!("found Deref: {:?}", impl_);
@@ -2078,7 +2117,7 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &[
20782117
if let Some(did) = target.def_id(c) {
20792118
if let Some(type_did) = impl_.inner_impl().for_.def_id(c) {
20802119
// `impl Deref<Target = S> for S`
2081-
if did == type_did {
2120+
if did == type_did || !derefs.insert(did) {
20822121
// Avoid infinite cycles
20832122
return;
20842123
}
@@ -2102,9 +2141,17 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &[
21022141
})
21032142
.collect::<Vec<_>>();
21042143
if !ret.is_empty() {
2144+
let map;
2145+
let id = if let Some(target_def_id) = real_target.def_id(c) {
2146+
map = cx.deref_id_map.borrow();
2147+
map.get(&target_def_id).expect("Deref section without derived id")
2148+
} else {
2149+
"deref-methods"
2150+
};
21052151
write!(
21062152
out,
2107-
"<h3 class=\"sidebar-title\"><a href=\"#deref-methods\">Methods from {}&lt;Target={}&gt;</a></h3>",
2153+
"<h3 class=\"sidebar-title\"><a href=\"#{}\">Methods from {}&lt;Target={}&gt;</a></h3>",
2154+
id,
21082155
Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(cx))),
21092156
Escape(&format!("{:#}", real_target.print(cx))),
21102157
);
@@ -2117,6 +2164,21 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &[
21172164
out.push_str("</div>");
21182165
}
21192166
}
2167+
2168+
// Recurse into any further impls that might exist for `target`
2169+
if let Some(target_did) = target.def_id_no_primitives() {
2170+
if let Some(target_impls) = c.impls.get(&target_did) {
2171+
if let Some(target_deref_impl) = target_impls.iter().find(|i| {
2172+
i.inner_impl()
2173+
.trait_
2174+
.as_ref()
2175+
.map(|t| Some(t.def_id()) == cx.tcx().lang_items().deref_trait())
2176+
.unwrap_or(false)
2177+
}) {
2178+
sidebar_deref_methods(cx, out, target_deref_impl, target_impls, derefs);
2179+
}
2180+
}
2181+
}
21202182
}
21212183
}
21222184

0 commit comments

Comments
 (0)