Skip to content

Commit a1ad41b

Browse files
committed
auto merge of #13791 : lifthrasiir/rust/mod-inner-span, r=huonw
This PR is primarily motivated by (and fixes) #12926. We currently only have a span for the individual item itself and not for the referred contents. This normally does not cause a problem since both are located in the same file; it *is* possible that the contained statement or item is located in the other file (the syntax extension can do that), but even in that case the syntax extension should be located in the same file as the item. The module item (i.e. `mod foo;`) is the only exception here, and thus warrants a special treatment. Rustdoc would now distinguish `mod foo;` from `mod foo {...}` by checking if the span for the module item and module contents is in different files. If it's the case, we'd prefer module contents over module item. There are alternative strategies, but as noted above we will have some corner cases if we don't record the contents span explicitly.
2 parents 7a19a82 + c8a29c4 commit a1ad41b

File tree

9 files changed

+58
-14
lines changed

9 files changed

+58
-14
lines changed

src/librustc/front/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
7070
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
7171
}).collect();
7272
ast::Mod {
73+
inner: m.inner,
7374
view_items: filtered_view_items,
7475
items: flattened_items
7576
}

src/librustc/front/test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
143143
}
144144

145145
let mod_nomain = ast::Mod {
146+
inner: m.inner,
146147
view_items: m.view_items.clone(),
147148
items: m.items.iter().map(|i| nomain(&self.cx, *i)).collect(),
148149
};
@@ -335,6 +336,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::Item {
335336
)).unwrap();
336337

337338
let testmod = ast::Mod {
339+
inner: DUMMY_SP,
338340
view_items: view_items,
339341
items: vec!(mainfn, tests),
340342
};

src/librustdoc/clean.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,27 @@ impl Clean<Item> for doctree::Module {
227227
self.view_items.clean().move_iter().collect(),
228228
self.macros.clean().move_iter().collect()
229229
);
230+
231+
// determine if we should display the inner contents or
232+
// the outer `mod` item for the source code.
233+
let where = {
234+
let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
235+
let cm = ctxt.sess().codemap();
236+
let outer = cm.lookup_char_pos(self.where_outer.lo);
237+
let inner = cm.lookup_char_pos(self.where_inner.lo);
238+
if outer.file.start_pos == inner.file.start_pos {
239+
// mod foo { ... }
240+
self.where_outer
241+
} else {
242+
// mod foo; (and a separate FileMap for the contents)
243+
self.where_inner
244+
}
245+
};
246+
230247
Item {
231248
name: Some(name),
232249
attrs: self.attrs.clean(),
233-
source: self.where.clean(),
250+
source: where.clean(),
234251
visibility: self.vis.clean(),
235252
id: self.id,
236253
inner: ModuleItem(Module {

src/librustdoc/doctree.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use syntax::ast::{Ident, NodeId};
1919
pub struct Module {
2020
pub name: Option<Ident>,
2121
pub attrs: Vec<ast::Attribute>,
22-
pub where: Span,
22+
pub where_outer: Span,
23+
pub where_inner: Span,
2324
pub structs: Vec<Struct>,
2425
pub enums: Vec<Enum>,
2526
pub fns: Vec<Function>,
@@ -42,7 +43,8 @@ impl Module {
4243
name : name,
4344
id: 0,
4445
vis: ast::Inherited,
45-
where: syntax::codemap::DUMMY_SP,
46+
where_outer: syntax::codemap::DUMMY_SP,
47+
where_inner: syntax::codemap::DUMMY_SP,
4648
attrs : Vec::new(),
4749
structs : Vec::new(),
4850
enums : Vec::new(),

src/librustdoc/visit_ast.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ impl<'a> RustdocVisitor<'a> {
118118
for item in m.view_items.iter() {
119119
self.visit_view_item(item, &mut om);
120120
}
121-
om.where = span;
121+
om.where_outer = span;
122+
om.where_inner = m.inner;
122123
om.attrs = attrs;
123124
om.vis = vis;
124125
om.id = id;

src/libsyntax/ast.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,12 @@ pub struct Method {
921921

922922
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
923923
pub struct Mod {
924-
pub view_items: Vec<ViewItem> ,
925-
pub items: Vec<@Item> ,
924+
/// A span from the first token past `{` to the last token until `}`.
925+
/// For `mod foo;`, the inner span ranges from the first token
926+
/// to the last token in the external file.
927+
pub inner: Span,
928+
pub view_items: Vec<ViewItem>,
929+
pub items: Vec<@Item>,
926930
}
927931

928932
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
@@ -1165,7 +1169,15 @@ mod test {
11651169
fn check_asts_encodable() {
11661170
use std::io;
11671171
let e = Crate {
1168-
module: Mod {view_items: Vec::new(), items: Vec::new()},
1172+
module: Mod {
1173+
inner: Span {
1174+
lo: BytePos(11),
1175+
hi: BytePos(19),
1176+
expn_info: None,
1177+
},
1178+
view_items: Vec::new(),
1179+
items: Vec::new(),
1180+
},
11691181
attrs: Vec::new(),
11701182
config: Vec::new(),
11711183
span: Span {

src/libsyntax/ext/build.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ pub trait AstBuilder {
220220
generics: Generics) -> @ast::Item;
221221
fn item_struct(&self, span: Span, name: Ident, struct_def: ast::StructDef) -> @ast::Item;
222222

223-
fn item_mod(&self, span: Span,
223+
fn item_mod(&self, span: Span, inner_span: Span,
224224
name: Ident, attrs: Vec<ast::Attribute> ,
225225
vi: Vec<ast::ViewItem> , items: Vec<@ast::Item> ) -> @ast::Item;
226226

@@ -898,7 +898,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
898898
self.item(span, name, Vec::new(), ast::ItemStruct(@struct_def, generics))
899899
}
900900

901-
fn item_mod(&self, span: Span, name: Ident,
901+
fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
902902
attrs: Vec<ast::Attribute> ,
903903
vi: Vec<ast::ViewItem> ,
904904
items: Vec<@ast::Item> ) -> @ast::Item {
@@ -907,6 +907,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
907907
name,
908908
attrs,
909909
ast::ItemMod(ast::Mod {
910+
inner: inner_span,
910911
view_items: vi,
911912
items: items,
912913
})

src/libsyntax/fold.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMeth
652652

653653
pub fn noop_fold_mod<T: Folder>(m: &Mod, folder: &mut T) -> Mod {
654654
ast::Mod {
655+
inner: folder.new_span(m.inner),
655656
view_items: m.view_items
656657
.iter()
657658
.map(|x| folder.fold_view_item(x)).collect(),

src/libsyntax/parse/parser.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4036,7 +4036,8 @@ impl<'a> Parser<'a> {
40364036
// attributes (of length 0 or 1), parse all of the items in a module
40374037
fn parse_mod_items(&mut self,
40384038
term: token::Token,
4039-
first_item_attrs: Vec<Attribute> )
4039+
first_item_attrs: Vec<Attribute>,
4040+
inner_lo: BytePos)
40404041
-> Mod {
40414042
// parse all of the items up to closing or an attribute.
40424043
// view items are legal here.
@@ -4081,7 +4082,11 @@ impl<'a> Parser<'a> {
40814082
self.span_err(self.last_span, "expected item after attributes");
40824083
}
40834084

4084-
ast::Mod { view_items: view_items, items: items }
4085+
ast::Mod {
4086+
inner: mk_sp(inner_lo, self.span.lo),
4087+
view_items: view_items,
4088+
items: items
4089+
}
40854090
}
40864091

40874092
fn parse_item_const(&mut self) -> ItemInfo {
@@ -4107,8 +4112,9 @@ impl<'a> Parser<'a> {
41074112
} else {
41084113
self.push_mod_path(id, outer_attrs);
41094114
self.expect(&token::LBRACE);
4115+
let mod_inner_lo = self.span.lo;
41104116
let (inner, next) = self.parse_inner_attrs_and_next();
4111-
let m = self.parse_mod_items(token::RBRACE, next);
4117+
let m = self.parse_mod_items(token::RBRACE, next, mod_inner_lo);
41124118
self.expect(&token::RBRACE);
41134119
self.pop_mod_path();
41144120
(id, ItemMod(m), Some(inner))
@@ -4197,10 +4203,11 @@ impl<'a> Parser<'a> {
41974203
self.cfg.clone(),
41984204
&path,
41994205
id_sp);
4206+
let mod_inner_lo = p0.span.lo;
42004207
let (inner, next) = p0.parse_inner_attrs_and_next();
42014208
let mod_attrs = outer_attrs.append(inner.as_slice());
42024209
let first_item_outer_attrs = next;
4203-
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
4210+
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs, mod_inner_lo);
42044211
self.sess.included_mod_stack.borrow_mut().pop();
42054212
return (ast::ItemMod(m0), mod_attrs);
42064213
}
@@ -5061,7 +5068,7 @@ impl<'a> Parser<'a> {
50615068
let (inner, next) = self.parse_inner_attrs_and_next();
50625069
let first_item_outer_attrs = next;
50635070
// parse the items inside the crate:
5064-
let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
5071+
let m = self.parse_mod_items(token::EOF, first_item_outer_attrs, lo);
50655072

50665073
ast::Crate {
50675074
module: m,

0 commit comments

Comments
 (0)