Skip to content

Commit 3abaf43

Browse files
committed
Auto merge of #37954 - eddyb:rustdoc-2, r=alexcrichton
rustdoc: link to cross-crate sources directly. Fixes #37684 by implementing proper support for getting the `Span` of definitions across crates. In rustdoc this is used to generate direct links to the original source instead of fragile redirects. This functionality could be expanded further for making error reporting code more uniform and seamless across crates, although at the moment there is no actual source to print, only file/line/column information. Closes #37870 which is also "fixes" #37684 by throwing away the builtin macro docs from libcore. After this lands, #37727 could be reverted, although it doesn't matter much either way.
2 parents 8e373b4 + 9001918 commit 3abaf43

File tree

26 files changed

+296
-325
lines changed

26 files changed

+296
-325
lines changed

src/librustc/hir/map/mod.rs

+26-33
Original file line numberDiff line numberDiff line change
@@ -760,47 +760,40 @@ impl<'ast> Map<'ast> {
760760
}
761761
}
762762

763-
pub fn opt_span(&self, id: NodeId) -> Option<Span> {
764-
let sp = match self.find(id) {
765-
Some(NodeItem(item)) => item.span,
766-
Some(NodeForeignItem(foreign_item)) => foreign_item.span,
767-
Some(NodeTraitItem(trait_method)) => trait_method.span,
768-
Some(NodeImplItem(ref impl_item)) => impl_item.span,
769-
Some(NodeVariant(variant)) => variant.span,
770-
Some(NodeField(field)) => field.span,
771-
Some(NodeExpr(expr)) => expr.span,
772-
Some(NodeStmt(stmt)) => stmt.span,
773-
Some(NodeTy(ty)) => ty.span,
774-
Some(NodeTraitRef(tr)) => tr.path.span,
775-
Some(NodeLocal(pat)) => pat.span,
776-
Some(NodePat(pat)) => pat.span,
777-
Some(NodeBlock(block)) => block.span,
778-
Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
779-
Some(NodeTyParam(ty_param)) => ty_param.span,
780-
Some(NodeVisibility(&Visibility::Restricted { ref path, .. })) => path.span,
781-
_ => return None,
782-
};
783-
Some(sp)
784-
}
785-
786763
pub fn span(&self, id: NodeId) -> Span {
787764
self.read(id); // reveals span from node
788-
self.opt_span(id)
789-
.unwrap_or_else(|| bug!("AstMap.span: could not find span for id {:?}", id))
765+
match self.find_entry(id) {
766+
Some(EntryItem(_, item)) => item.span,
767+
Some(EntryForeignItem(_, foreign_item)) => foreign_item.span,
768+
Some(EntryTraitItem(_, trait_method)) => trait_method.span,
769+
Some(EntryImplItem(_, impl_item)) => impl_item.span,
770+
Some(EntryVariant(_, variant)) => variant.span,
771+
Some(EntryField(_, field)) => field.span,
772+
Some(EntryExpr(_, expr)) => expr.span,
773+
Some(EntryStmt(_, stmt)) => stmt.span,
774+
Some(EntryTy(_, ty)) => ty.span,
775+
Some(EntryTraitRef(_, tr)) => tr.path.span,
776+
Some(EntryLocal(_, pat)) => pat.span,
777+
Some(EntryPat(_, pat)) => pat.span,
778+
Some(EntryBlock(_, block)) => block.span,
779+
Some(EntryStructCtor(_, _)) => self.expect_item(self.get_parent(id)).span,
780+
Some(EntryLifetime(_, lifetime)) => lifetime.span,
781+
Some(EntryTyParam(_, ty_param)) => ty_param.span,
782+
Some(EntryVisibility(_, &Visibility::Restricted { ref path, .. })) => path.span,
783+
Some(EntryVisibility(_, v)) => bug!("unexpected Visibility {:?}", v),
784+
785+
Some(RootCrate) => self.krate().span,
786+
Some(RootInlinedParent(parent)) => parent.body.span,
787+
Some(NotPresent) | None => {
788+
bug!("hir::map::Map::span: id not in map: {:?}", id)
789+
}
790+
}
790791
}
791792

792793
pub fn span_if_local(&self, id: DefId) -> Option<Span> {
793794
self.as_local_node_id(id).map(|id| self.span(id))
794795
}
795796

796-
pub fn def_id_span(&self, def_id: DefId, fallback: Span) -> Span {
797-
if let Some(node_id) = self.as_local_node_id(def_id) {
798-
self.opt_span(node_id).unwrap_or(fallback)
799-
} else {
800-
fallback
801-
}
802-
}
803-
804797
pub fn node_to_string(&self, id: NodeId) -> String {
805798
node_id_to_string(self, id, true)
806799
}

src/librustc/middle/cstore.rs

+2
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ pub struct ExternCrate {
260260
pub trait CrateStore<'tcx> {
261261
// item info
262262
fn describe_def(&self, def: DefId) -> Option<Def>;
263+
fn def_span(&self, sess: &Session, def: DefId) -> Span;
263264
fn stability(&self, def: DefId) -> Option<attr::Stability>;
264265
fn deprecation(&self, def: DefId) -> Option<attr::Deprecation>;
265266
fn visibility(&self, def: DefId) -> ty::Visibility;
@@ -404,6 +405,7 @@ pub struct DummyCrateStore;
404405
impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
405406
// item info
406407
fn describe_def(&self, def: DefId) -> Option<Def> { bug!("describe_def") }
408+
fn def_span(&self, sess: &Session, def: DefId) -> Span { bug!("def_span") }
407409
fn stability(&self, def: DefId) -> Option<attr::Stability> { bug!("stability") }
408410
fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { bug!("deprecation") }
409411
fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }

src/librustc/ty/error.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
283283
expected.ty,
284284
found.ty));
285285

286-
match
287-
self.map.as_local_node_id(expected.def_id)
288-
.and_then(|node_id| self.map.opt_span(node_id))
289-
{
286+
match self.map.span_if_local(expected.def_id) {
290287
Some(span) => {
291288
db.span_note(span, "a default was defined here...");
292289
}
@@ -300,10 +297,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
300297
expected.origin_span,
301298
"...that was applied to an unconstrained type variable here");
302299

303-
match
304-
self.map.as_local_node_id(found.def_id)
305-
.and_then(|node_id| self.map.opt_span(node_id))
306-
{
300+
match self.map.span_if_local(found.def_id) {
307301
Some(span) => {
308302
db.span_note(span, "a second default was defined here...");
309303
}

src/librustc/ty/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2360,6 +2360,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
23602360
}
23612361
}
23622362

2363+
pub fn def_span(self, def_id: DefId) -> Span {
2364+
if let Some(id) = self.map.as_local_node_id(def_id) {
2365+
self.map.span(id)
2366+
} else {
2367+
self.sess.cstore.def_span(&self.sess, def_id)
2368+
}
2369+
}
2370+
23632371
pub fn item_name(self, id: DefId) -> ast::Name {
23642372
if let Some(id) = self.map.as_local_node_id(id) {
23652373
self.map.name(id)

src/librustc_borrowck/borrowck/fragments.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,8 @@ fn add_fragment_siblings_for_extension<'a, 'tcx>(this: &MoveData<'tcx>,
496496
},
497497

498498
ref ty => {
499-
let opt_span = origin_id.and_then(|id|tcx.map.opt_span(id));
500-
span_bug!(opt_span.unwrap_or(DUMMY_SP),
499+
let span = origin_id.map_or(DUMMY_SP, |id| tcx.map.span(id));
500+
span_bug!(span,
501501
"type {:?} ({:?}) is not fragmentable",
502502
parent_ty, ty);
503503
}

src/librustc_driver/pretty.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1006,11 +1006,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
10061006
got {:?}",
10071007
node);
10081008

1009-
// Point to what was found, if there's an accessible span.
1010-
match tcx.map.opt_span(nodeid) {
1011-
Some(sp) => tcx.sess.span_fatal(sp, &message),
1012-
None => tcx.sess.fatal(&message),
1013-
}
1009+
tcx.sess.span_fatal(tcx.map.span(nodeid), &message)
10141010
}
10151011
}
10161012
}

src/librustc_metadata/cstore_impl.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use syntax::ast;
3232
use syntax::attr;
3333
use syntax::parse::new_parser_from_source_str;
3434
use syntax::symbol::Symbol;
35-
use syntax_pos::mk_sp;
35+
use syntax_pos::{mk_sp, Span};
3636
use rustc::hir::svh::Svh;
3737
use rustc_back::target::Target;
3838
use rustc::hir;
@@ -43,6 +43,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
4343
self.get_crate_data(def.krate).get_def(def.index)
4444
}
4545

46+
fn def_span(&self, sess: &Session, def: DefId) -> Span {
47+
self.dep_graph.read(DepNode::MetaData(def));
48+
self.get_crate_data(def.krate).get_span(def.index, sess)
49+
}
50+
4651
fn stability(&self, def: DefId) -> Option<attr::Stability> {
4752
self.dep_graph.read(DepNode::MetaData(def));
4853
self.get_crate_data(def.krate).get_stability(def.index)
@@ -383,20 +388,23 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
383388
let local_span = mk_sp(lo, parser.prev_span.hi);
384389

385390
// Mark the attrs as used
386-
for attr in &def.attrs {
391+
let attrs = data.get_item_attrs(id.index);
392+
for attr in &attrs {
387393
attr::mark_used(attr);
388394
}
389395

396+
let name = data.def_key(id.index).disambiguated_data.data
397+
.get_opt_name().expect("no name in load_macro");
390398
sess.imported_macro_spans.borrow_mut()
391-
.insert(local_span, (def.name.as_str().to_string(), def.span));
399+
.insert(local_span, (name.to_string(), data.get_span(id.index, sess)));
392400

393401
LoadedMacro::MacroRules(ast::MacroDef {
394-
ident: ast::Ident::with_empty_ctxt(def.name),
402+
ident: ast::Ident::with_empty_ctxt(name),
395403
id: ast::DUMMY_NODE_ID,
396404
span: local_span,
397405
imported_from: None, // FIXME
398-
allow_internal_unstable: attr::contains_name(&def.attrs, "allow_internal_unstable"),
399-
attrs: def.attrs,
406+
allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
407+
attrs: attrs,
400408
body: body,
401409
})
402410
}

src/librustc_metadata/decoder.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc::middle::cstore::{InlinedItem, LinkagePreference};
2525
use rustc::hir::def::{self, Def, CtorKind};
2626
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
2727
use rustc::middle::lang_items;
28+
use rustc::session::Session;
2829
use rustc::ty::{self, Ty, TyCtxt};
2930
use rustc::ty::subst::Substs;
3031

@@ -47,8 +48,9 @@ use syntax_pos::{self, Span, BytePos, Pos};
4748

4849
pub struct DecodeContext<'a, 'tcx: 'a> {
4950
opaque: opaque::Decoder<'a>,
50-
tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
5151
cdata: Option<&'a CrateMetadata>,
52+
sess: Option<&'a Session>,
53+
tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
5254
from_id_range: IdRange,
5355
to_id_range: IdRange,
5456

@@ -61,22 +63,21 @@ pub struct DecodeContext<'a, 'tcx: 'a> {
6163
/// Abstract over the various ways one can create metadata decoders.
6264
pub trait Metadata<'a, 'tcx>: Copy {
6365
fn raw_bytes(self) -> &'a [u8];
64-
fn cdata(self) -> Option<&'a CrateMetadata> {
65-
None
66-
}
67-
fn tcx(self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> {
68-
None
69-
}
66+
fn cdata(self) -> Option<&'a CrateMetadata> { None }
67+
fn sess(self) -> Option<&'a Session> { None }
68+
fn tcx(self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> { None }
7069

7170
fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> {
7271
let id_range = IdRange {
7372
min: NodeId::from_u32(u32::MIN),
7473
max: NodeId::from_u32(u32::MAX),
7574
};
75+
let tcx = self.tcx();
7676
DecodeContext {
7777
opaque: opaque::Decoder::new(self.raw_bytes(), pos),
7878
cdata: self.cdata(),
79-
tcx: self.tcx(),
79+
sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
80+
tcx: tcx,
8081
from_id_range: id_range,
8182
to_id_range: id_range,
8283
last_filemap_index: 0,
@@ -104,6 +105,18 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadata {
104105
}
105106
}
106107

108+
impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, &'a Session) {
109+
fn raw_bytes(self) -> &'a [u8] {
110+
self.0.raw_bytes()
111+
}
112+
fn cdata(self) -> Option<&'a CrateMetadata> {
113+
Some(self.0)
114+
}
115+
fn sess(self) -> Option<&'a Session> {
116+
Some(&self.1)
117+
}
118+
}
119+
107120
impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'a, 'tcx, 'tcx>) {
108121
fn raw_bytes(self) -> &'a [u8] {
109122
self.0.raw_bytes()
@@ -280,8 +293,8 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
280293
let lo = BytePos::decode(self)?;
281294
let hi = BytePos::decode(self)?;
282295

283-
let tcx = if let Some(tcx) = self.tcx {
284-
tcx
296+
let sess = if let Some(sess) = self.sess {
297+
sess
285298
} else {
286299
return Ok(syntax_pos::mk_sp(lo, hi));
287300
};
@@ -299,7 +312,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
299312
(lo, hi)
300313
};
301314

302-
let imported_filemaps = self.cdata().imported_filemaps(&tcx.sess.codemap());
315+
let imported_filemaps = self.cdata().imported_filemaps(&sess.codemap());
303316
let filemap = {
304317
// Optimize for the case that most spans within a translated item
305318
// originate from the same filemap.
@@ -537,6 +550,10 @@ impl<'a, 'tcx> CrateMetadata {
537550
}
538551
}
539552

553+
pub fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
554+
self.entry(index).span.decode((self, sess))
555+
}
556+
540557
pub fn get_trait_def(&self,
541558
item_id: DefIndex,
542559
tcx: TyCtxt<'a, 'tcx, 'tcx>)

0 commit comments

Comments
 (0)