Skip to content

Commit 8cc8133

Browse files
committed
Fix calls to resolver from rustdoc and HIR lowering
Cleanup some surrounding code. Support resolution of intra doc links in unnamed block scopes. (Paths from rustdoc now use early resolution and no longer need results of late resolution like all the built ribs.) Fix one test hitting file path limits on Windows.
1 parent f360d79 commit 8cc8133

File tree

5 files changed

+48
-61
lines changed

5 files changed

+48
-61
lines changed

src/librustc/hir/lowering.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::hir::{self, ParamName};
3737
use crate::hir::HirVec;
3838
use crate::hir::map::{DefKey, DefPathData, Definitions};
3939
use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
40-
use crate::hir::def::{Res, DefKind, PartialRes, PerNS};
40+
use crate::hir::def::{Namespace, Res, DefKind, PartialRes, PerNS};
4141
use crate::hir::{GenericArg, ConstArg};
4242
use crate::hir::ptr::P;
4343
use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
@@ -148,13 +148,6 @@ pub struct LoweringContext<'a> {
148148
}
149149

150150
pub trait Resolver {
151-
/// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc.
152-
fn resolve_ast_path(
153-
&mut self,
154-
path: &ast::Path,
155-
is_value: bool,
156-
) -> Res<NodeId>;
157-
158151
/// Obtain resolution for a `NodeId` with a single resolution.
159152
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
160153

@@ -175,7 +168,7 @@ pub trait Resolver {
175168
span: Span,
176169
crate_root: Option<Symbol>,
177170
components: &[Symbol],
178-
is_value: bool,
171+
ns: Namespace,
179172
) -> (ast::Path, Res<NodeId>);
180173

181174
fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool;
@@ -5717,8 +5710,8 @@ impl<'a> LoweringContext<'a> {
57175710
params: Option<P<hir::GenericArgs>>,
57185711
is_value: bool,
57195712
) -> hir::Path {
5720-
let (path, res) = self.resolver
5721-
.resolve_str_path(span, self.crate_root, components, is_value);
5713+
let ns = if is_value { Namespace::ValueNS } else { Namespace::TypeNS };
5714+
let (path, res) = self.resolver.resolve_str_path(span, self.crate_root, components, ns);
57225715

57235716
let mut segments: Vec<_> = path.segments.iter().map(|segment| {
57245717
let res = self.expect_full_res(segment.id);

src/librustc_resolve/late.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
541541
crate_lint: CrateLint,
542542
) -> PathResult<'a> {
543543
self.r.resolve_path_with_ribs(
544-
path, opt_ns, &self.parent_scope, record_used, path_span, crate_lint, &self.ribs
544+
path, opt_ns, &self.parent_scope, record_used, path_span, crate_lint, Some(&self.ribs)
545545
)
546546
}
547547

src/librustc_resolve/lib.rs

+34-35
Original file line numberDiff line numberDiff line change
@@ -987,26 +987,12 @@ impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> {
987987
/// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that
988988
/// the resolver is no longer needed as all the relevant information is inline.
989989
impl<'a> hir::lowering::Resolver for Resolver<'a> {
990-
fn resolve_ast_path(
991-
&mut self,
992-
path: &ast::Path,
993-
is_value: bool,
994-
) -> Res {
995-
match self.resolve_ast_path_inner(path, is_value) {
996-
Ok(r) => r,
997-
Err((span, error)) => {
998-
self.report_error(span, error);
999-
Res::Err
1000-
}
1001-
}
1002-
}
1003-
1004990
fn resolve_str_path(
1005991
&mut self,
1006992
span: Span,
1007993
crate_root: Option<Symbol>,
1008994
components: &[Symbol],
1009-
is_value: bool
995+
ns: Namespace,
1010996
) -> (ast::Path, Res) {
1011997
let root = if crate_root.is_some() {
1012998
kw::PathRoot
@@ -1025,7 +1011,14 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
10251011
segments,
10261012
};
10271013

1028-
let res = self.resolve_ast_path(&path, is_value);
1014+
let parent_scope = &self.dummy_parent_scope();
1015+
let res = match self.resolve_ast_path(&path, ns, parent_scope) {
1016+
Ok(res) => res,
1017+
Err((span, error)) => {
1018+
self.report_error(span, error);
1019+
Res::Err
1020+
}
1021+
};
10291022
(path, res)
10301023
}
10311024

@@ -1738,7 +1731,7 @@ impl<'a> Resolver<'a> {
17381731
crate_lint: CrateLint,
17391732
) -> PathResult<'a> {
17401733
self.resolve_path_with_ribs(
1741-
path, opt_ns, parent_scope, record_used, path_span, crate_lint, &Default::default()
1734+
path, opt_ns, parent_scope, record_used, path_span, crate_lint, None
17421735
)
17431736
}
17441737

@@ -1750,7 +1743,7 @@ impl<'a> Resolver<'a> {
17501743
record_used: bool,
17511744
path_span: Span,
17521745
crate_lint: CrateLint,
1753-
ribs: &PerNS<Vec<Rib<'a>>>,
1746+
ribs: Option<&PerNS<Vec<Rib<'a>>>>,
17541747
) -> PathResult<'a> {
17551748
let mut module = None;
17561749
let mut allow_super = true;
@@ -1864,16 +1857,17 @@ impl<'a> Resolver<'a> {
18641857
self.resolve_ident_in_module(
18651858
module, ident, ns, parent_scope, record_used, path_span
18661859
)
1867-
} else if opt_ns.is_none() || opt_ns == Some(MacroNS) {
1868-
assert!(ns == TypeNS);
1869-
let scopes = if opt_ns.is_none() { ScopeSet::Import(ns) } else { ScopeSet::Module };
1860+
} else if ribs.is_none() || opt_ns.is_none() || opt_ns == Some(MacroNS) {
1861+
// FIXME: Decouple the import property from `ScopeSet`.
1862+
let is_import = opt_ns.is_none() || ns != TypeNS;
1863+
let scopes = if is_import { ScopeSet::Import(ns) } else { ScopeSet::Module };
18701864
self.early_resolve_ident_in_lexical_scope(ident, scopes, parent_scope, record_used,
18711865
record_used, path_span)
18721866
} else {
18731867
let record_used_id =
18741868
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
18751869
match self.resolve_ident_in_lexical_scope(
1876-
ident, ns, parent_scope, record_used_id, path_span, &ribs[ns]
1870+
ident, ns, parent_scope, record_used_id, path_span, &ribs.unwrap()[ns]
18771871
) {
18781872
// we found a locally-imported or available item/module
18791873
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
@@ -2639,8 +2633,10 @@ impl<'a> Resolver<'a> {
26392633
/// isn't something that can be returned because it can't be made to live that long,
26402634
/// and also it's a private type. Fortunately rustdoc doesn't need to know the error,
26412635
/// just that an error occurred.
2642-
pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: bool)
2643-
-> Result<(ast::Path, Res), ()> {
2636+
// FIXME(Manishearth): intra-doc links won't get warned of epoch changes.
2637+
pub fn resolve_str_path_error(
2638+
&mut self, span: Span, path_str: &str, ns: Namespace, module_id: NodeId
2639+
) -> Result<(ast::Path, Res), ()> {
26442640
let path = if path_str.starts_with("::") {
26452641
ast::Path {
26462642
span,
@@ -2661,28 +2657,31 @@ impl<'a> Resolver<'a> {
26612657
.collect(),
26622658
}
26632659
};
2664-
let res = self.resolve_ast_path_inner(&path, is_value).map_err(|_| ())?;
2660+
let module = self.block_map.get(&module_id).copied().unwrap_or_else(|| {
2661+
let def_id = self.definitions.local_def_id(module_id);
2662+
self.module_map.get(&def_id).copied().unwrap_or(self.graph_root)
2663+
});
2664+
let parent_scope = &ParentScope { module, ..self.dummy_parent_scope() };
2665+
let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?;
26652666
Ok((path, res))
26662667
}
26672668

2668-
/// Like `resolve_ast_path`, but takes a callback in case there was an error.
2669-
fn resolve_ast_path_inner(
2669+
// Resolve a path passed from rustdoc or HIR lowering.
2670+
fn resolve_ast_path(
26702671
&mut self,
26712672
path: &ast::Path,
2672-
is_value: bool,
2673+
ns: Namespace,
2674+
parent_scope: &ParentScope<'a>,
26732675
) -> Result<Res, (Span, ResolutionError<'a>)> {
2674-
let namespace = if is_value { ValueNS } else { TypeNS };
2675-
let span = path.span;
2676-
let path = Segment::from_path(&path);
2677-
// FIXME(Manishearth): intra-doc links won't get warned of epoch changes.
2678-
let parent_scope = &self.dummy_parent_scope();
2679-
match self.resolve_path(&path, Some(namespace), parent_scope, true, span, CrateLint::No) {
2676+
match self.resolve_path(
2677+
&Segment::from_path(path), Some(ns), parent_scope, true, path.span, CrateLint::No
2678+
) {
26802679
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
26812680
Ok(module.res().unwrap()),
26822681
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
26832682
Ok(path_res.base_res()),
26842683
PathResult::NonModule(..) => {
2685-
Err((span, ResolutionError::FailedToResolve {
2684+
Err((path.span, ResolutionError::FailedToResolve {
26862685
label: String::from("type-relative paths are not supported in this context"),
26872686
suggestion: None,
26882687
}))

src/librustdoc/passes/collect_intra_doc_links.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
6161
{
6262
let cx = self.cx;
6363

64-
// In case we're in a module, try to resolve the relative
65-
// path.
66-
if let Some(id) = parent_id.or(self.mod_ids.last().cloned()) {
67-
// FIXME: `with_scope` requires the `NodeId` of a module.
68-
let node_id = cx.tcx.hir().hir_to_node_id(id);
64+
// In case we're in a module, try to resolve the relative path.
65+
if let Some(module_id) = parent_id.or(self.mod_ids.last().cloned()) {
66+
let module_id = cx.tcx.hir().hir_to_node_id(module_id);
6967
let result = cx.enter_resolver(|resolver| {
70-
resolver.with_scope(node_id, |resolver| {
71-
resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns == ValueNS)
72-
})
68+
resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id)
7369
});
7470
let result = match result {
7571
Ok((_, Res::Err)) => Err(()),
@@ -85,6 +81,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
8581
Res::Def(DefKind::AssocTy, _) => false,
8682
Res::Def(DefKind::Variant, _) => return handle_variant(cx, res),
8783
// Not a trait item; just return what we found.
84+
Res::PrimTy(..) => return Ok((res, Some(path_str.to_owned()))),
8885
_ => return Ok((res, None))
8986
};
9087

@@ -133,11 +130,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
133130
.ok_or(());
134131
}
135132

136-
// FIXME: `with_scope` requires the `NodeId` of a module.
137-
let node_id = cx.tcx.hir().hir_to_node_id(id);
138-
let (_, ty_res) = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| {
139-
resolver.resolve_str_path_error(DUMMY_SP, &path, false)
140-
}))?;
133+
let (_, ty_res) = cx.enter_resolver(|resolver| {
134+
resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
135+
})?;
141136
if let Res::Err = ty_res {
142137
return Err(());
143138
}

src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// edition:2018
2-
// build-pass (FIXME(62277): could be check-pass?)
2+
// check-pass
33
// revisions: migrate mir
44
//[mir]compile-flags: -Z borrowck=mir
55

0 commit comments

Comments
 (0)