Skip to content

Commit e6ee8a0

Browse files
committed
rustc: produce AST instead of HIR from hir::lowering::Resolver methods.
1 parent 53ae6d2 commit e6ee8a0

File tree

3 files changed

+46
-46
lines changed

3 files changed

+46
-46
lines changed

src/librustc/hir/lowering.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,11 @@ pub struct LoweringContext<'a> {
148148

149149
pub trait Resolver {
150150
/// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc.
151-
fn resolve_hir_path(
151+
fn resolve_ast_path(
152152
&mut self,
153153
path: &ast::Path,
154154
is_value: bool,
155-
) -> hir::Path;
155+
) -> Res<NodeId>;
156156

157157
/// Obtain resolution for a `NodeId` with a single resolution.
158158
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
@@ -167,15 +167,15 @@ pub trait Resolver {
167167
/// This should only return `None` during testing.
168168
fn definitions(&mut self) -> &mut Definitions;
169169

170-
/// Given suffix `["b", "c", "d"]`, creates a HIR path for `[::crate_root]::b::c::d` and
170+
/// Given suffix `["b", "c", "d"]`, creates an AST path for `[::crate_root]::b::c::d` and
171171
/// resolves it based on `is_value`.
172172
fn resolve_str_path(
173173
&mut self,
174174
span: Span,
175175
crate_root: Option<Symbol>,
176176
components: &[Symbol],
177177
is_value: bool,
178-
) -> hir::Path;
178+
) -> (ast::Path, Res<NodeId>);
179179
}
180180

181181
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
@@ -5546,16 +5546,26 @@ impl<'a> LoweringContext<'a> {
55465546
params: Option<P<hir::GenericArgs>>,
55475547
is_value: bool,
55485548
) -> hir::Path {
5549-
let mut path = self.resolver
5549+
let (path, res) = self.resolver
55505550
.resolve_str_path(span, self.crate_root, components, is_value);
5551-
path.segments.last_mut().unwrap().args = params;
55525551

5553-
for seg in path.segments.iter_mut() {
5554-
if seg.hir_id.is_some() {
5555-
seg.hir_id = Some(self.next_id());
5552+
let mut segments: Vec<_> = path.segments.iter().map(|segment| {
5553+
let res = self.expect_full_res(segment.id);
5554+
hir::PathSegment {
5555+
ident: segment.ident,
5556+
hir_id: Some(self.lower_node_id(segment.id)),
5557+
res: Some(self.lower_res(res)),
5558+
infer_args: true,
5559+
args: None,
55565560
}
5561+
}).collect();
5562+
segments.last_mut().unwrap().args = params;
5563+
5564+
hir::Path {
5565+
span,
5566+
res: res.map_id(|_| panic!("unexpected node_id")),
5567+
segments: segments.into(),
55575568
}
5558-
path
55595569
}
55605570

55615571
fn ty_path(&mut self, mut hir_id: hir::HirId, span: Span, qpath: hir::QPath) -> hir::Ty {

src/librustc_resolve/lib.rs

+15-27
Original file line numberDiff line numberDiff line change
@@ -1744,12 +1744,12 @@ impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> {
17441744
/// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that
17451745
/// the resolver is no longer needed as all the relevant information is inline.
17461746
impl<'a> hir::lowering::Resolver for Resolver<'a> {
1747-
fn resolve_hir_path(
1747+
fn resolve_ast_path(
17481748
&mut self,
17491749
path: &ast::Path,
17501750
is_value: bool,
1751-
) -> hir::Path {
1752-
self.resolve_hir_path_cb(path, is_value,
1751+
) -> Res {
1752+
self.resolve_ast_path_cb(path, is_value,
17531753
|resolver, span, error| resolve_error(resolver, span, error))
17541754
}
17551755

@@ -1759,7 +1759,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
17591759
crate_root: Option<Symbol>,
17601760
components: &[Symbol],
17611761
is_value: bool
1762-
) -> hir::Path {
1762+
) -> (ast::Path, Res) {
17631763
let root = if crate_root.is_some() {
17641764
kw::PathRoot
17651765
} else {
@@ -1777,7 +1777,8 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
17771777
segments,
17781778
};
17791779

1780-
self.resolve_hir_path(&path, is_value)
1780+
let res = self.resolve_ast_path(&path, is_value);
1781+
(path, res)
17811782
}
17821783

17831784
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> {
@@ -1803,7 +1804,7 @@ impl<'a> Resolver<'a> {
18031804
/// and also it's a private type. Fortunately rustdoc doesn't need to know the error,
18041805
/// just that an error occurred.
18051806
pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: bool)
1806-
-> Result<hir::Path, ()> {
1807+
-> Result<(ast::Path, Res), ()> {
18071808
let mut errored = false;
18081809

18091810
let path = if path_str.starts_with("::") {
@@ -1826,29 +1827,29 @@ impl<'a> Resolver<'a> {
18261827
.collect(),
18271828
}
18281829
};
1829-
let path = self.resolve_hir_path_cb(&path, is_value, |_, _, _| errored = true);
1830-
if errored || path.res == def::Res::Err {
1830+
let res = self.resolve_ast_path_cb(&path, is_value, |_, _, _| errored = true);
1831+
if errored || res == def::Res::Err {
18311832
Err(())
18321833
} else {
1833-
Ok(path)
1834+
Ok((path, res))
18341835
}
18351836
}
18361837

1837-
/// Like `resolve_hir_path`, but takes a callback in case there was an error.
1838-
fn resolve_hir_path_cb<F>(
1838+
/// Like `resolve_ast_path`, but takes a callback in case there was an error.
1839+
// FIXME(eddyb) use `Result` or something instead of callbacks.
1840+
fn resolve_ast_path_cb<F>(
18391841
&mut self,
18401842
path: &ast::Path,
18411843
is_value: bool,
18421844
error_callback: F,
1843-
) -> hir::Path
1845+
) -> Res
18441846
where F: for<'c, 'b> FnOnce(&'c mut Resolver<'_>, Span, ResolutionError<'b>)
18451847
{
18461848
let namespace = if is_value { ValueNS } else { TypeNS };
18471849
let span = path.span;
1848-
let segments = &path.segments;
18491850
let path = Segment::from_path(&path);
18501851
// FIXME(Manishearth): intra-doc links won't get warned of epoch changes.
1851-
let res = match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
1852+
match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
18521853
span, CrateLint::No) {
18531854
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
18541855
module.res().unwrap(),
@@ -1869,19 +1870,6 @@ impl<'a> Resolver<'a> {
18691870
});
18701871
Res::Err
18711872
}
1872-
};
1873-
1874-
let segments: Vec<_> = segments.iter().map(|seg| {
1875-
let mut hir_seg = hir::PathSegment::from_ident(seg.ident);
1876-
hir_seg.res = Some(self.partial_res_map.get(&seg.id).map_or(def::Res::Err, |p| {
1877-
p.base_res().map_id(|_| panic!("unexpected node_id"))
1878-
}));
1879-
hir_seg
1880-
}).collect();
1881-
hir::Path {
1882-
span,
1883-
res: res.map_id(|_| panic!("unexpected node_id")),
1884-
segments: segments.into(),
18851873
}
18861874
}
18871875

src/librustdoc/passes/collect_intra_doc_links.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
7171
})
7272
});
7373

74-
if let Ok(result) = result {
74+
if let Ok((_, res)) = result {
75+
let res = res.map_id(|_| panic!("unexpected node_id"));
7576
// In case this is a trait item, skip the
7677
// early return and try looking for the trait.
77-
let value = match result.res {
78+
let value = match res {
7879
Res::Def(DefKind::Method, _) | Res::Def(DefKind::AssocConst, _) => true,
7980
Res::Def(DefKind::AssocTy, _) => false,
80-
Res::Def(DefKind::Variant, _) => return handle_variant(cx, result.res),
81+
Res::Def(DefKind::Variant, _) => return handle_variant(cx, res),
8182
// Not a trait item; just return what we found.
82-
_ => return Ok((result.res, None))
83+
_ => return Ok((res, None))
8384
};
8485

8586
if value != (ns == ValueNS) {
@@ -129,10 +130,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
129130

130131
// FIXME: `with_scope` requires the `NodeId` of a module.
131132
let node_id = cx.tcx.hir().hir_to_node_id(id);
132-
let ty = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| {
133+
let (_, ty_res) = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| {
133134
resolver.resolve_str_path_error(DUMMY_SP, &path, false)
134135
}))?;
135-
match ty.res {
136+
let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
137+
match ty_res {
136138
Res::Def(DefKind::Struct, did)
137139
| Res::Def(DefKind::Union, did)
138140
| Res::Def(DefKind::Enum, did)
@@ -147,7 +149,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
147149
ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
148150
_ => return Err(())
149151
};
150-
Ok((ty.res, Some(format!("{}.{}", out, item_name))))
152+
Ok((ty_res, Some(format!("{}.{}", out, item_name))))
151153
} else {
152154
match cx.tcx.type_of(did).sty {
153155
ty::Adt(def, _) => {
@@ -159,7 +161,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
159161
.iter()
160162
.find(|item| item.ident.name == item_name)
161163
} {
162-
Ok((ty.res,
164+
Ok((ty_res,
163165
Some(format!("{}.{}",
164166
if def.is_enum() {
165167
"variant"
@@ -193,7 +195,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
193195
_ => return Err(())
194196
};
195197

196-
Ok((ty.res, Some(format!("{}.{}", kind, item_name))))
198+
Ok((ty_res, Some(format!("{}.{}", kind, item_name))))
197199
} else {
198200
Err(())
199201
}

0 commit comments

Comments
 (0)