Skip to content

Rollup of 9 pull requests #82885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6a679ff
bypass auto_da_alloc for metadata files
the8472 Feb 12, 2021
6e52b23
Fix jemalloc usage on OSX
sfackler Feb 28, 2021
920e2d8
Add natvis for Result, NonNull, CString, CStr, and Cow
rylev Feb 26, 2021
bc18eb4
expand: Remove obsolete `DirectoryOwnership::UnownedViaMod`
petrochenkov Feb 22, 2021
39052c5
expand: Move module file path stack from global session to expansion …
petrochenkov Feb 21, 2021
5bdf81d
expand: Determine module directory path directly instead of relying o…
petrochenkov Feb 22, 2021
3d0b622
expand: Less path cloning during module loading
petrochenkov Feb 22, 2021
46b67aa
expand: Some more consistent naming in module loading
petrochenkov Feb 22, 2021
da3419e
rustc_interface: Hide some hacky details of early linting from expand
petrochenkov Feb 22, 2021
29a9ef2
expand: Align some code with the PR fixing inner attributes on out-of…
petrochenkov Feb 22, 2021
1e1d574
expand: Share some code between inline and out-of-line module treatment
petrochenkov Feb 22, 2021
1fe2eb8
expand: Introduce enum for module loading errors and make module load…
petrochenkov Feb 22, 2021
1b4860a
Update compiler/rustc/src/main.rs
sfackler Mar 5, 2021
6f49aad
Disable destination propagation on all mir-opt-levels
tmiasko Mar 6, 2021
069e612
rustc_ast: Replace `AstLike::finalize_tokens` with a getter `tokens_mut`
petrochenkov Mar 6, 2021
5dad6c2
Implement built-in attribute macro `#[cfg_eval]`
petrochenkov Mar 6, 2021
cf52469
Remove Item::kind, use tagged enum. Rename variants to match
CraftSpider Feb 28, 2021
ca48d15
Add roundtrip testing and bump format version
CraftSpider Mar 4, 2021
83cece4
Move tests to own file
CraftSpider Mar 5, 2021
70c9b37
x.py fmt
CraftSpider Mar 5, 2021
18841ec
Revert fmt version, add rustdoc-json-types to bootstrap tests
CraftSpider Mar 6, 2021
f9019b7
Move full configuration logic from `rustc_expand` to `rustc_builtin_m…
petrochenkov Mar 6, 2021
10ed08f
cfg_eval: Configure everything through mutable visitor methods
petrochenkov Mar 6, 2021
5d27728
rustc_builtin_macros: Share some more logic between `derive` and `cfg…
petrochenkov Mar 6, 2021
6b2eb0e
Edit ructc_ast_lowering docs
pierwill Mar 7, 2021
ab8995b
Generalize Write impl for Vec<u8> to Vec<u8, A>
athre0z Mar 7, 2021
743df86
Rollup merge of #82047 - the8472:fast-rename, r=davidtwco
Dylan-DPC Mar 8, 2021
f0393e8
Rollup merge of #82415 - petrochenkov:modin3, r=davidtwco
Dylan-DPC Mar 8, 2021
b9bdf69
Rollup merge of #82557 - rylev:natvis-improvements, r=varkor
Dylan-DPC Mar 8, 2021
648cb7f
Rollup merge of #82613 - CraftSpider:fix-de, r=aDotInTheVoid
Dylan-DPC Mar 8, 2021
b6d1f77
Rollup merge of #82642 - sfackler:jemalloc-zone, r=pnkfelix
Dylan-DPC Mar 8, 2021
577ee2f
Rollup merge of #82682 - petrochenkov:cfgeval, r=Aaron1011
Dylan-DPC Mar 8, 2021
a2a7c25
Rollup merge of #82684 - tmiasko:dest-prop, r=jonas-schievink
Dylan-DPC Mar 8, 2021
8c281ea
Rollup merge of #82857 - pierwill:edit-ast-lowering-lib, r=Dylan-DPC
Dylan-DPC Mar 8, 2021
0b98fa1
Rollup merge of #82862 - athre0z:generalize-vec-write-impl, r=TimDiek…
Dylan-DPC Mar 8, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
expand: Introduce enum for module loading errors and make module load…
…ing speculative
  • Loading branch information
petrochenkov committed Mar 4, 2021
commit 1fe2eb83ecfed43874b4cdf39d0be8910995dd1d
1 change: 1 addition & 0 deletions compiler/rustc_expand/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(decl_macro)]
#![feature(destructuring_assignment)]
Expand Down
172 changes: 85 additions & 87 deletions compiler/rustc_expand/src/module.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::base::ModuleData;
use rustc_ast::ptr::P;
use rustc_ast::{token, Attribute, Item};
use rustc_errors::{struct_span_err, PResult};
use rustc_errors::{struct_span_err, DiagnosticBuilder};
use rustc_parse::new_parser_from_file;
use rustc_session::parse::ParseSess;
use rustc_session::Session;
Expand All @@ -19,14 +19,6 @@ pub enum DirOwnership {
UnownedViaBlock,
}

/// Information about the path to a module.
// Public for rustfmt usage.
pub struct ModulePath<'a> {
name: String,
path_exists: bool,
pub result: PResult<'a, ModulePathSuccess>,
}

// Public for rustfmt usage.
pub struct ModulePathSuccess {
pub file_path: PathBuf,
Expand All @@ -41,6 +33,14 @@ crate struct ParsedExternalMod {
pub dir_ownership: DirOwnership,
}

pub enum ModError<'a> {
CircularInclusion(Vec<PathBuf>),
ModInBlock(Option<Ident>),
FileNotFound(Ident, PathBuf),
MultipleCandidates(Ident, String, String),
ParserError(DiagnosticBuilder<'a>),
}

crate fn parse_external_mod(
sess: &Session,
ident: Ident,
Expand All @@ -50,47 +50,33 @@ crate fn parse_external_mod(
attrs: &mut Vec<Attribute>,
) -> ParsedExternalMod {
// We bail on the first error, but that error does not cause a fatal error... (1)
let result: PResult<'_, _> = try {
let result: Result<_, ModError<'_>> = try {
// Extract the file path and the new ownership.
let mp = mod_file_path(sess, ident, span, &attrs, &module.dir_path, dir_ownership)?;
let mp = mod_file_path(sess, ident, &attrs, &module.dir_path, dir_ownership)?;
dir_ownership = mp.dir_ownership;

// Ensure file paths are acyclic.
error_on_circular_module(&sess.parse_sess, span, &mp.file_path, &module.file_path_stack)?;
if let Some(pos) = module.file_path_stack.iter().position(|p| p == &mp.file_path) {
Err(ModError::CircularInclusion(module.file_path_stack[pos..].to_vec()))?;
}

// Actually parse the external file as a module.
let mut parser = new_parser_from_file(&sess.parse_sess, &mp.file_path, Some(span));
let (mut inner_attrs, items, inner_span) = parser.parse_mod(&token::Eof)?;
let (mut inner_attrs, items, inner_span) =
parser.parse_mod(&token::Eof).map_err(|err| ModError::ParserError(err))?;
attrs.append(&mut inner_attrs);
(items, inner_span, mp.file_path)
};
// (1) ...instead, we return a dummy module.
let (items, inner_span, file_path) = result.map_err(|mut err| err.emit()).unwrap_or_default();
let (items, inner_span, file_path) =
result.map_err(|err| err.report(sess, span)).unwrap_or_default();

// Extract the directory path for submodules of the module.
let dir_path = file_path.parent().unwrap_or(&file_path).to_owned();

ParsedExternalMod { items, inner_span, file_path, dir_path, dir_ownership }
}

fn error_on_circular_module<'a>(
sess: &'a ParseSess,
span: Span,
file_path: &Path,
file_path_stack: &[PathBuf],
) -> PResult<'a, ()> {
if let Some(i) = file_path_stack.iter().position(|p| *p == file_path) {
let mut err = String::from("circular modules: ");
for p in &file_path_stack[i..] {
err.push_str(&p.to_string_lossy());
err.push_str(" -> ");
}
err.push_str(&file_path.to_string_lossy());
return Err(sess.span_diagnostic.struct_span_err(span, &err[..]));
}
Ok(())
}

crate fn mod_dir_path(
sess: &Session,
ident: Ident,
Expand Down Expand Up @@ -125,11 +111,10 @@ crate fn mod_dir_path(
fn mod_file_path<'a>(
sess: &'a Session,
ident: Ident,
span: Span,
attrs: &[Attribute],
dir_path: &Path,
dir_ownership: DirOwnership,
) -> PResult<'a, ModulePathSuccess> {
) -> Result<ModulePathSuccess, ModError<'a>> {
if let Some(file_path) = mod_file_path_from_attr(sess, attrs, dir_path) {
// All `#[path]` files are treated as though they are a `mod.rs` file.
// This means that `mod foo;` declarations inside `#[path]`-included
Expand All @@ -146,30 +131,14 @@ fn mod_file_path<'a>(
DirOwnership::Owned { relative } => relative,
DirOwnership::UnownedViaBlock => None,
};
let ModulePath { path_exists, name, result } =
default_submod_path(&sess.parse_sess, ident, span, relative, dir_path);
let result = default_submod_path(&sess.parse_sess, ident, relative, dir_path);
match dir_ownership {
DirOwnership::Owned { .. } => Ok(result?),
DirOwnership::UnownedViaBlock => {
let _ = result.map_err(|mut err| err.cancel());
error_decl_mod_in_block(&sess.parse_sess, span, path_exists, &name)
}
}
}

fn error_decl_mod_in_block<'a, T>(
sess: &'a ParseSess,
span: Span,
path_exists: bool,
name: &str,
) -> PResult<'a, T> {
let msg = "Cannot declare a non-inline module inside a block unless it has a path attribute";
let mut err = sess.span_diagnostic.struct_span_err(span, msg);
if path_exists {
let msg = format!("Maybe `use` the module `{}` instead of redeclaring it", name);
err.span_note(span, &msg);
DirOwnership::Owned { .. } => result,
DirOwnership::UnownedViaBlock => Err(ModError::ModInBlock(match result {
Ok(_) | Err(ModError::MultipleCandidates(..)) => Some(ident),
_ => None,
})),
}
Err(err)
}

/// Derive a submodule path from the first found `#[path = "path_string"]`.
Expand Down Expand Up @@ -197,10 +166,9 @@ fn mod_file_path_from_attr(
pub fn default_submod_path<'a>(
sess: &'a ParseSess,
ident: Ident,
span: Span,
relative: Option<Ident>,
dir_path: &Path,
) -> ModulePath<'a> {
) -> Result<ModulePathSuccess, ModError<'a>> {
// If we're in a foo.rs file instead of a mod.rs file,
// we need to look for submodules in
// `./foo/<ident>.rs` and `./foo/<ident>/mod.rs` rather than
Expand All @@ -222,7 +190,7 @@ pub fn default_submod_path<'a>(
let default_exists = sess.source_map().file_exists(&default_path);
let secondary_exists = sess.source_map().file_exists(&secondary_path);

let result = match (default_exists, secondary_exists) {
match (default_exists, secondary_exists) {
(true, false) => Ok(ModulePathSuccess {
file_path: default_path,
dir_ownership: DirOwnership::Owned { relative: Some(ident) },
Expand All @@ -231,35 +199,65 @@ pub fn default_submod_path<'a>(
file_path: secondary_path,
dir_ownership: DirOwnership::Owned { relative: None },
}),
(false, false) => {
let mut err = struct_span_err!(
sess.span_diagnostic,
span,
E0583,
"file not found for module `{}`",
mod_name,
);
err.help(&format!(
"to create the module `{}`, create file \"{}\"",
mod_name,
default_path.display(),
));
Err(err)
}
(false, false) => Err(ModError::FileNotFound(ident, default_path)),
(true, true) => {
let mut err = struct_span_err!(
sess.span_diagnostic,
span,
E0761,
"file for module `{}` found at both {} and {}",
mod_name,
default_path_str,
secondary_path_str,
);
err.help("delete or rename one of them to remove the ambiguity");
Err(err)
Err(ModError::MultipleCandidates(ident, default_path_str, secondary_path_str))
}
};
}
}

ModulePath { name: mod_name, path_exists: default_exists || secondary_exists, result }
impl ModError<'_> {
fn report(self, sess: &Session, span: Span) {
let diag = &sess.parse_sess.span_diagnostic;
match self {
ModError::CircularInclusion(file_paths) => {
let mut msg = String::from("circular modules: ");
for file_path in &file_paths {
msg.push_str(&file_path.display().to_string());
msg.push_str(" -> ");
}
msg.push_str(&file_paths[0].display().to_string());
diag.struct_span_err(span, &msg)
}
ModError::ModInBlock(ident) => {
let msg = "cannot declare a non-inline module inside a block unless it has a path attribute";
let mut err = diag.struct_span_err(span, msg);
if let Some(ident) = ident {
let note =
format!("maybe `use` the module `{}` instead of redeclaring it", ident);
err.span_note(span, &note);
}
err
}
ModError::FileNotFound(ident, default_path) => {
let mut err = struct_span_err!(
diag,
span,
E0583,
"file not found for module `{}`",
ident,
);
err.help(&format!(
"to create the module `{}`, create file \"{}\"",
ident,
default_path.display(),
));
err
}
ModError::MultipleCandidates(ident, default_path_short, secondary_path_short) => {
let mut err = struct_span_err!(
diag,
span,
E0761,
"file for module `{}` found at both {} and {}",
ident,
default_path_short,
secondary_path_short,
);
err.help("delete or rename one of them to remove the ambiguity");
err
}
ModError::ParserError(err) => err,
}.emit()
}
}
2 changes: 1 addition & 1 deletion src/test/ui/directory_ownership/macro-expanded-mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

macro_rules! mod_decl {
($i:ident) => {
mod $i; //~ ERROR Cannot declare a non-inline module inside a block
mod $i; //~ ERROR cannot declare a non-inline module inside a block
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/directory_ownership/macro-expanded-mod.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Cannot declare a non-inline module inside a block unless it has a path attribute
error: cannot declare a non-inline module inside a block unless it has a path attribute
--> $DIR/macro-expanded-mod.rs:5:9
|
LL | mod $i;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Test that non-inline modules are not allowed inside blocks.

fn main() {
mod foo; //~ ERROR Cannot declare a non-inline module inside a block
mod foo; //~ ERROR cannot declare a non-inline module inside a block
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: Cannot declare a non-inline module inside a block unless it has a path attribute
error: cannot declare a non-inline module inside a block unless it has a path attribute
--> $DIR/non-inline-mod-restriction.rs:4:5
|
LL | mod foo;
Expand Down