Rollup merge of #69838 - Centril:expand-module, r=petrochenkov

Expansion-driven outline module parsing

After this PR, the parser will not do any conditional compilation or loading of external module files when `mod foo;` is encountered. Instead, the parser only leaves `mod foo;` in place in the AST, with no items filled in. Expansion later kicks in and will load the actual files and do the parsing. This entails that the following is now valid:

```rust
#[cfg(FALSE)]
mod foo {
    mod bar {
        mod baz; // `foo/bar/baz.rs` doesn't exist, but no error!
    }
}
```

Fixes https://github.com/rust-lang/rust/issues/64197.

r? @petrochenkov
This commit is contained in:
Mazdak Farrokhzad 2020-03-18 18:03:38 +01:00 committed by GitHub
commit 23b79d83f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 601 additions and 593 deletions

View file

@ -2,10 +2,8 @@
// compile-flags: -Zquery-dep-graph
#![feature(rustc_attrs)]
#![allow(private_no_mangle_fns)]
#![rustc_partition_codegened(module="change_symbol_export_status-mod1", cfg="rpass2")]
#![rustc_partition_reused(module="change_symbol_export_status-mod2", cfg="rpass2")]
#![rustc_partition_codegened(module = "change_symbol_export_status-mod1", cfg = "rpass2")]
#![rustc_partition_reused(module = "change_symbol_export_status-mod2", cfg = "rpass2")]
// This test case makes sure that a change in symbol visibility is detected by
// our dependency tracking. We do this by changing a module's visibility to

View file

@ -1,4 +1,5 @@
// pp-exact
// pretty-compare-only
// The next line should not be expanded

View file

@ -2,16 +2,14 @@
#![feature(rustc_private)]
// We're testing linkage visibility; the compiler warns us, but we want to
// do the runtime check that these functions aren't exported.
#![allow(private_no_mangle_fns)]
extern crate rustc_metadata;
use rustc_metadata::dynamic_lib::DynamicLibrary;
#[no_mangle]
pub fn foo() { bar(); }
pub fn foo() {
bar();
}
pub fn foo2<T>() {
fn bar2() {
@ -21,11 +19,11 @@ pub fn foo2<T>() {
}
#[no_mangle]
fn bar() { }
fn bar() {}
#[allow(dead_code)]
#[no_mangle]
fn baz() { }
fn baz() {}
pub fn test() {
let lib = DynamicLibrary::open(None).unwrap();

View file

@ -1,7 +1,9 @@
// Test that macro-expanded non-inline modules behave correctly
macro_rules! mod_decl {
($i:ident) => { mod $i; } //~ ERROR Cannot declare a non-inline module inside a block
($i:ident) => {
mod $i; //~ ERROR Cannot declare a non-inline module inside a block
};
}
mod macro_expanded_mod_helper {

View file

@ -1,8 +1,8 @@
error: Cannot declare a non-inline module inside a block unless it has a path attribute
--> $DIR/macro-expanded-mod.rs:4:25
--> $DIR/macro-expanded-mod.rs:5:9
|
LL | ($i:ident) => { mod $i; }
| ^^
LL | mod $i;
| ^^^^^^^
...
LL | mod_decl!(foo);
| --------------- in this macro invocation

View file

@ -1,8 +1,8 @@
error: Cannot declare a non-inline module inside a block unless it has a path attribute
--> $DIR/non-inline-mod-restriction.rs:4:9
--> $DIR/non-inline-mod-restriction.rs:4:5
|
LL | mod foo;
| ^^^
| ^^^^^^^^
error: aborting due to previous error

View file

@ -1,8 +1,8 @@
error[E0583]: file not found for module `module_that_doesnt_exist`
--> $DIR/E0583.rs:1:5
--> $DIR/E0583.rs:1:1
|
LL | mod module_that_doesnt_exist;
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: to create the module `module_that_doesnt_exist`, create file "$DIR/module_that_doesnt_exist.rs"

View file

@ -1,8 +1,8 @@
error[E0583]: file not found for module `baz`
--> $DIR/auxiliary/foo/bar.rs:1:9
--> $DIR/auxiliary/foo/bar.rs:1:1
|
LL | pub mod baz;
| ^^^
| ^^^^^^^^^^^^
|
= help: to create the module `baz`, create file "$DIR/auxiliary/foo/bar/baz.rs"

View file

@ -0,0 +1,7 @@
// check-pass
// compile-flags: -W rust-2018-compatibility
// error-pattern: `try` is a keyword in the 2018 edition
fn main() {}
mod lint_pre_expansion_extern_module_aux;

View file

@ -0,0 +1,10 @@
warning: `try` is a keyword in the 2018 edition
--> $DIR/lint_pre_expansion_extern_module_aux.rs:3:8
|
LL | pub fn try() {}
| ^^^ help: you can use a raw identifier to stay compatible: `r#try`
|
= note: `-W keyword-idents` implied by `-W rust-2018-compatibility`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
= note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

View file

@ -0,0 +1,3 @@
// ignore-test: not a test
pub fn try() {}

View file

@ -1,8 +1,8 @@
error[E0583]: file not found for module `missing`
--> $DIR/foo.rs:4:5
--> $DIR/foo.rs:4:1
|
LL | mod missing;
| ^^^^^^^
| ^^^^^^^^^^^^
|
= help: to create the module `missing`, create file "$DIR/foo/missing.rs"

View file

@ -1,8 +1,8 @@
error[E0583]: file not found for module `missing`
--> $DIR/foo_inline.rs:4:9
--> $DIR/foo_inline.rs:4:5
|
LL | mod missing;
| ^^^^^^^
| ^^^^^^^^^^^^
|
= help: to create the module `missing`, create file "$DIR/foo_inline/inline/missing.rs"

View file

@ -2,4 +2,5 @@ mod mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` fou
fn main() {
assert_eq!(mod_file_aux::bar(), 10);
//~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux`
}

View file

@ -1,11 +1,18 @@
error[E0584]: file for module `mod_file_disambig_aux` found at both mod_file_disambig_aux.rs and mod_file_disambig_aux/mod.rs
--> $DIR/mod_file_disambig.rs:1:5
--> $DIR/mod_file_disambig.rs:1:1
|
LL | mod mod_file_disambig_aux;
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: delete or rename one of them to remove the ambiguity
error: aborting due to previous error
error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux`
--> $DIR/mod_file_disambig.rs:4:16
|
LL | assert_eq!(mod_file_aux::bar(), 10);
| ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux`
For more information about this error, try `rustc --explain E0584`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0433, E0584.
For more information about an error, try `rustc --explain E0433`.

View file

@ -6,5 +6,5 @@ pub fn hi_str() -> String {
}
fn main() {
circular_modules_hello::say_hello();
circular_modules_hello::say_hello(); //~ ERROR cannot find function `say_hello` in module
}

View file

@ -1,8 +1,20 @@
error: circular modules: $DIR/circular_modules_hello.rs -> $DIR/circular_modules_main.rs -> $DIR/circular_modules_hello.rs
--> $DIR/circular_modules_main.rs:2:5
--> $DIR/circular_modules_main.rs:2:1
|
LL | mod circular_modules_hello;
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0425]: cannot find function `say_hello` in module `circular_modules_hello`
--> $DIR/circular_modules_main.rs:9:29
|
LL | circular_modules_hello::say_hello();
| ^^^^^^^^^ not found in `circular_modules_hello`
|
help: possible candidate is found in another module, you can import it into scope
|
LL | use circular_modules_hello::say_hello;
|
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.

View file

@ -1,8 +1,8 @@
error: couldn't read $DIR/../parser: $ACCESS_DENIED_MSG (os error $ACCESS_DENIED_CODE)
--> $DIR/issue-5806.rs:5:5
--> $DIR/issue-5806.rs:5:1
|
LL | mod foo;
| ^^^
| ^^^^^^^^
error: aborting due to previous error

View file

@ -1,8 +1,9 @@
// ignore-windows
mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
//~^ HELP to create the module `not_a_real_file`, create file "
//~^ HELP to create the module `not_a_real_file`, create file
fn main() {
assert_eq!(mod_file_aux::bar(), 10);
//~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux`
}

View file

@ -1,11 +1,18 @@
error[E0583]: file not found for module `not_a_real_file`
--> $DIR/mod_file_not_exist.rs:3:5
--> $DIR/mod_file_not_exist.rs:3:1
|
LL | mod not_a_real_file;
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^
|
= help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs"
error: aborting due to previous error
error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux`
--> $DIR/mod_file_not_exist.rs:7:16
|
LL | assert_eq!(mod_file_aux::bar(), 10);
| ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux`
For more information about this error, try `rustc --explain E0583`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0433, E0583.
For more information about an error, try `rustc --explain E0433`.

View file

@ -5,4 +5,5 @@ mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
fn main() {
assert_eq!(mod_file_aux::bar(), 10);
//~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux`
}

View file

@ -1,11 +1,18 @@
error[E0583]: file not found for module `not_a_real_file`
--> $DIR/mod_file_not_exist_windows.rs:3:5
--> $DIR/mod_file_not_exist_windows.rs:3:1
|
LL | mod not_a_real_file;
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^
|
= help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs"
error: aborting due to previous error
error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux`
--> $DIR/mod_file_not_exist_windows.rs:7:16
|
LL | assert_eq!(mod_file_aux::bar(), 10);
| ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux`
For more information about this error, try `rustc --explain E0583`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0433, E0583.
For more information about an error, try `rustc --explain E0433`.

View file

@ -1,8 +1,8 @@
error: couldn't read $DIR/not_a_real_file.rs: $FILE_NOT_FOUND_MSG (os error 2)
--> $DIR/mod_file_with_path_attr.rs:4:5
--> $DIR/mod_file_with_path_attr.rs:4:1
|
LL | mod m;
| ^
| ^^^^^^
error: aborting due to previous error

View file

@ -0,0 +1,13 @@
// Expansion drives parsing, so conditional compilation will strip
// out outline modules and we will never attempt parsing them.
// check-pass
fn main() {}
#[cfg(FALSE)]
mod foo {
mod bar {
mod baz; // This was an error before.
}
}