Auto merge of #52319 - tinco:issue_12590, r=pnkfelix
Track whether module declarations are inline (fixes #12590) To track whether module declarations are inline I added a field `inline: bool` to `ast::Mod`. The main use case is for pretty to know whether it should render the items associated with the module, but perhaps there are use cases for this information to not be forgotten in the AST.
This commit is contained in:
commit
c4501a0f1d
12 changed files with 143 additions and 17 deletions
|
@ -1885,6 +1885,8 @@ pub struct Mod {
|
||||||
/// to the last token in the external file.
|
/// to the last token in the external file.
|
||||||
pub inner: Span,
|
pub inner: Span,
|
||||||
pub items: Vec<P<Item>>,
|
pub items: Vec<P<Item>>,
|
||||||
|
/// For `mod foo;` inline is false, for `mod foo { .. }` it is true.
|
||||||
|
pub inline: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Foreign module declaration.
|
/// Foreign module declaration.
|
||||||
|
|
|
@ -1101,6 +1101,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
ast::ItemKind::Mod(ast::Mod {
|
ast::ItemKind::Mod(ast::Mod {
|
||||||
inner: inner_span,
|
inner: inner_span,
|
||||||
items,
|
items,
|
||||||
|
inline: true
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,6 +303,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
krate.module = ast::Mod {
|
krate.module = ast::Mod {
|
||||||
inner: orig_mod_span,
|
inner: orig_mod_span,
|
||||||
items: vec![],
|
items: vec![],
|
||||||
|
inline: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
|
@ -1044,10 +1044,11 @@ pub fn noop_fold_fn_header<T: Folder>(mut header: FnHeader, folder: &mut T) -> F
|
||||||
header
|
header
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
|
pub fn noop_fold_mod<T: Folder>(Mod {inner, items, inline}: Mod, folder: &mut T) -> Mod {
|
||||||
Mod {
|
Mod {
|
||||||
inner: folder.new_span(inner),
|
inner: folder.new_span(inner),
|
||||||
items: items.move_flat_map(|x| folder.fold_item(x)),
|
items: items.move_flat_map(|x| folder.fold_item(x)),
|
||||||
|
inline: inline,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,6 +1078,7 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, span}: Crate,
|
||||||
None => (ast::Mod {
|
None => (ast::Mod {
|
||||||
inner: span,
|
inner: span,
|
||||||
items: vec![],
|
items: vec![],
|
||||||
|
inline: true,
|
||||||
}, vec![], span)
|
}, vec![], span)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6297,6 +6297,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(ast::Mod {
|
Ok(ast::Mod {
|
||||||
inner: inner_lo.to(hi),
|
inner: inner_lo.to(hi),
|
||||||
items,
|
items,
|
||||||
|
inline: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6334,6 +6335,7 @@ impl<'a> Parser<'a> {
|
||||||
self.submod_path(id, &outer_attrs, id_span)?;
|
self.submod_path(id, &outer_attrs, id_span)?;
|
||||||
let (module, mut attrs) =
|
let (module, mut attrs) =
|
||||||
self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
|
self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
|
||||||
|
// Record that we fetched the mod from an external file
|
||||||
if warn {
|
if warn {
|
||||||
let attr = Attribute {
|
let attr = Attribute {
|
||||||
id: attr::mk_attr_id(),
|
id: attr::mk_attr_id(),
|
||||||
|
@ -6346,9 +6348,13 @@ impl<'a> Parser<'a> {
|
||||||
attr::mark_known(&attr);
|
attr::mark_known(&attr);
|
||||||
attrs.push(attr);
|
attrs.push(attr);
|
||||||
}
|
}
|
||||||
Ok((id, module, Some(attrs)))
|
Ok((id, ItemKind::Mod(module), Some(attrs)))
|
||||||
} else {
|
} else {
|
||||||
let placeholder = ast::Mod { inner: syntax_pos::DUMMY_SP, items: Vec::new() };
|
let placeholder = ast::Mod {
|
||||||
|
inner: syntax_pos::DUMMY_SP,
|
||||||
|
items: Vec::new(),
|
||||||
|
inline: false
|
||||||
|
};
|
||||||
Ok((id, ItemKind::Mod(placeholder), None))
|
Ok((id, ItemKind::Mod(placeholder), None))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -6548,7 +6554,7 @@ impl<'a> Parser<'a> {
|
||||||
directory_ownership: DirectoryOwnership,
|
directory_ownership: DirectoryOwnership,
|
||||||
name: String,
|
name: String,
|
||||||
id_sp: Span)
|
id_sp: Span)
|
||||||
-> PResult<'a, (ast::ItemKind, Vec<Attribute> )> {
|
-> PResult<'a, (ast::Mod, Vec<Attribute> )> {
|
||||||
let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
|
let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
|
||||||
if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
|
if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
|
||||||
let mut err = String::from("circular modules: ");
|
let mut err = String::from("circular modules: ");
|
||||||
|
@ -6568,9 +6574,10 @@ impl<'a> Parser<'a> {
|
||||||
p0.cfg_mods = self.cfg_mods;
|
p0.cfg_mods = self.cfg_mods;
|
||||||
let mod_inner_lo = p0.span;
|
let mod_inner_lo = p0.span;
|
||||||
let mod_attrs = p0.parse_inner_attributes()?;
|
let mod_attrs = p0.parse_inner_attributes()?;
|
||||||
let m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?;
|
let mut m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?;
|
||||||
|
m0.inline = false;
|
||||||
self.sess.included_mod_stack.borrow_mut().pop();
|
self.sess.included_mod_stack.borrow_mut().pop();
|
||||||
Ok((ast::ItemKind::Mod(m0), mod_attrs))
|
Ok((m0, mod_attrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a function declaration from a foreign module
|
/// Parse a function declaration from a foreign module
|
||||||
|
|
|
@ -61,6 +61,7 @@ pub struct State<'a> {
|
||||||
cur_cmnt: usize,
|
cur_cmnt: usize,
|
||||||
boxes: Vec<pp::Breaks>,
|
boxes: Vec<pp::Breaks>,
|
||||||
ann: &'a (dyn PpAnn+'a),
|
ann: &'a (dyn PpAnn+'a),
|
||||||
|
is_expanded: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a> {
|
fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a> {
|
||||||
|
@ -72,6 +73,7 @@ fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a>
|
||||||
cur_cmnt: 0,
|
cur_cmnt: 0,
|
||||||
boxes: Vec::new(),
|
boxes: Vec::new(),
|
||||||
ann,
|
ann,
|
||||||
|
is_expanded: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,14 +135,17 @@ impl<'a> State<'a> {
|
||||||
// If the code is post expansion, don't use the table of
|
// If the code is post expansion, don't use the table of
|
||||||
// literals, since it doesn't correspond with the literals
|
// literals, since it doesn't correspond with the literals
|
||||||
// in the AST anymore.
|
// in the AST anymore.
|
||||||
if is_expanded { None } else { Some(lits) })
|
if is_expanded { None } else { Some(lits) },
|
||||||
|
is_expanded
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(cm: &'a SourceMap,
|
pub fn new(cm: &'a SourceMap,
|
||||||
out: Box<dyn Write+'a>,
|
out: Box<dyn Write+'a>,
|
||||||
ann: &'a dyn PpAnn,
|
ann: &'a dyn PpAnn,
|
||||||
comments: Option<Vec<comments::Comment>>,
|
comments: Option<Vec<comments::Comment>>,
|
||||||
literals: Option<Vec<comments::Literal>>) -> State<'a> {
|
literals: Option<Vec<comments::Literal>>,
|
||||||
|
is_expanded: bool) -> State<'a> {
|
||||||
State {
|
State {
|
||||||
s: pp::mk_printer(out, DEFAULT_COLUMNS),
|
s: pp::mk_printer(out, DEFAULT_COLUMNS),
|
||||||
cm: Some(cm),
|
cm: Some(cm),
|
||||||
|
@ -149,6 +154,7 @@ impl<'a> State<'a> {
|
||||||
cur_cmnt: 0,
|
cur_cmnt: 0,
|
||||||
boxes: Vec::new(),
|
boxes: Vec::new(),
|
||||||
ann,
|
ann,
|
||||||
|
is_expanded: is_expanded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1260,10 +1266,18 @@ impl<'a> State<'a> {
|
||||||
ast::ItemKind::Mod(ref _mod) => {
|
ast::ItemKind::Mod(ref _mod) => {
|
||||||
self.head(&visibility_qualified(&item.vis, "mod"))?;
|
self.head(&visibility_qualified(&item.vis, "mod"))?;
|
||||||
self.print_ident(item.ident)?;
|
self.print_ident(item.ident)?;
|
||||||
self.nbsp()?;
|
|
||||||
self.bopen()?;
|
if _mod.inline || self.is_expanded {
|
||||||
self.print_mod(_mod, &item.attrs)?;
|
self.nbsp()?;
|
||||||
self.bclose(item.span)?;
|
self.bopen()?;
|
||||||
|
self.print_mod(_mod, &item.attrs)?;
|
||||||
|
self.bclose(item.span)?;
|
||||||
|
} else {
|
||||||
|
self.s.word(";")?;
|
||||||
|
self.end()?; // end inner head-block
|
||||||
|
self.end()?; // end outer head-block
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
ast::ItemKind::ForeignMod(ref nmod) => {
|
ast::ItemKind::ForeignMod(ref nmod) => {
|
||||||
self.head("extern")?;
|
self.head("extern")?;
|
||||||
|
|
|
@ -237,6 +237,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt,
|
||||||
})).collect();
|
})).collect();
|
||||||
|
|
||||||
let reexport_mod = ast::Mod {
|
let reexport_mod = ast::Mod {
|
||||||
|
inline: true,
|
||||||
inner: DUMMY_SP,
|
inner: DUMMY_SP,
|
||||||
items,
|
items,
|
||||||
};
|
};
|
||||||
|
|
17
src/test/pretty/issue_12590_a.rs
Normal file
17
src/test/pretty/issue_12590_a.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// pp-exact
|
||||||
|
|
||||||
|
// The next line should not be expanded
|
||||||
|
|
||||||
|
mod issue_12590_b;
|
||||||
|
|
||||||
|
fn main() { }
|
14
src/test/pretty/issue_12590_b.rs
Normal file
14
src/test/pretty/issue_12590_b.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Second part of two file test
|
||||||
|
fn b() { }
|
||||||
|
|
||||||
|
fn main() { }
|
28
src/test/pretty/issue_12590_c.pp
Normal file
28
src/test/pretty/issue_12590_c.pp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#![feature(prelude_import)]
|
||||||
|
#![no_std]
|
||||||
|
#[prelude_import]
|
||||||
|
use ::std::prelude::v1::*;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate std;
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// pretty-compare-only
|
||||||
|
// pretty-mode:expanded
|
||||||
|
// pp-exact:issue_12590_c.pp
|
||||||
|
|
||||||
|
// The next line should be expanded
|
||||||
|
|
||||||
|
mod issue_12590_b {
|
||||||
|
|
||||||
|
fn b() { }
|
||||||
|
fn main() { }
|
||||||
|
}
|
||||||
|
fn main() { }
|
19
src/test/pretty/issue_12590_c.rs
Normal file
19
src/test/pretty/issue_12590_c.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// pretty-compare-only
|
||||||
|
// pretty-mode:expanded
|
||||||
|
// pp-exact:issue_12590_c.pp
|
||||||
|
|
||||||
|
// The next line should be expanded
|
||||||
|
|
||||||
|
mod issue_12590_b;
|
||||||
|
|
||||||
|
fn main() { }
|
|
@ -240,6 +240,11 @@ struct DebuggerCommands {
|
||||||
breakpoint_lines: Vec<usize>,
|
breakpoint_lines: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ReadFrom {
|
||||||
|
Path,
|
||||||
|
Stdin(String),
|
||||||
|
}
|
||||||
|
|
||||||
impl<'test> TestCx<'test> {
|
impl<'test> TestCx<'test> {
|
||||||
/// Code executed for each revision in turn (or, if there are no
|
/// Code executed for each revision in turn (or, if there are no
|
||||||
/// revisions, exactly once, with revision == None).
|
/// revisions, exactly once, with revision == None).
|
||||||
|
@ -450,8 +455,14 @@ impl<'test> TestCx<'test> {
|
||||||
round, self.revision
|
round, self.revision
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
let proc_res = self.print_source(srcs[round].to_owned(), &self.props.pretty_mode);
|
let read_from = if round == 0 {
|
||||||
|
ReadFrom::Path
|
||||||
|
} else {
|
||||||
|
ReadFrom::Stdin(srcs[round].to_owned())
|
||||||
|
};
|
||||||
|
|
||||||
|
let proc_res = self.print_source(read_from,
|
||||||
|
&self.props.pretty_mode);
|
||||||
if !proc_res.status.success() {
|
if !proc_res.status.success() {
|
||||||
self.fatal_proc_rec(
|
self.fatal_proc_rec(
|
||||||
&format!(
|
&format!(
|
||||||
|
@ -506,7 +517,7 @@ impl<'test> TestCx<'test> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// additionally, run `--pretty expanded` and try to build it.
|
// additionally, run `--pretty expanded` and try to build it.
|
||||||
let proc_res = self.print_source(srcs[round].clone(), "expanded");
|
let proc_res = self.print_source(ReadFrom::Path, "expanded");
|
||||||
if !proc_res.status.success() {
|
if !proc_res.status.success() {
|
||||||
self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
|
self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
|
||||||
}
|
}
|
||||||
|
@ -524,12 +535,16 @@ impl<'test> TestCx<'test> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_source(&self, src: String, pretty_type: &str) -> ProcRes {
|
fn print_source(&self, read_from: ReadFrom, pretty_type: &str) -> ProcRes {
|
||||||
let aux_dir = self.aux_output_dir_name();
|
let aux_dir = self.aux_output_dir_name();
|
||||||
|
let input: &str = match read_from {
|
||||||
|
ReadFrom::Stdin(_) => "-",
|
||||||
|
ReadFrom::Path => self.testpaths.file.to_str().unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut rustc = Command::new(&self.config.rustc_path);
|
let mut rustc = Command::new(&self.config.rustc_path);
|
||||||
rustc
|
rustc
|
||||||
.arg("-")
|
.arg(input)
|
||||||
.args(&["-Z", &format!("unpretty={}", pretty_type)])
|
.args(&["-Z", &format!("unpretty={}", pretty_type)])
|
||||||
.args(&["--target", &self.config.target])
|
.args(&["--target", &self.config.target])
|
||||||
.arg("-L")
|
.arg("-L")
|
||||||
|
@ -538,11 +553,16 @@ impl<'test> TestCx<'test> {
|
||||||
.args(&self.props.compile_flags)
|
.args(&self.props.compile_flags)
|
||||||
.envs(self.props.exec_env.clone());
|
.envs(self.props.exec_env.clone());
|
||||||
|
|
||||||
|
let src = match read_from {
|
||||||
|
ReadFrom::Stdin(src) => Some(src),
|
||||||
|
ReadFrom::Path => None
|
||||||
|
};
|
||||||
|
|
||||||
self.compose_and_run(
|
self.compose_and_run(
|
||||||
rustc,
|
rustc,
|
||||||
self.config.compile_lib_path.to_str().unwrap(),
|
self.config.compile_lib_path.to_str().unwrap(),
|
||||||
Some(aux_dir.to_str().unwrap()),
|
Some(aux_dir.to_str().unwrap()),
|
||||||
Some(src),
|
src,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue