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:
commit
23b79d83f2
47 changed files with 601 additions and 593 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// pp-exact
|
||||
// pretty-compare-only
|
||||
|
||||
// The next line should not be expanded
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
7
src/test/ui/lint/lint-pre-expansion-extern-module.rs
Normal file
7
src/test/ui/lint/lint-pre-expansion-extern-module.rs
Normal 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;
|
||||
10
src/test/ui/lint/lint-pre-expansion-extern-module.stderr
Normal file
10
src/test/ui/lint/lint-pre-expansion-extern-module.stderr
Normal 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>
|
||||
|
||||
3
src/test/ui/lint/lint_pre_expansion_extern_module_aux.rs
Normal file
3
src/test/ui/lint/lint_pre_expansion_extern_module_aux.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// ignore-test: not a test
|
||||
|
||||
pub fn try() {}
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
13
src/test/ui/parser/stripped-nested-outline-mod-pass.rs
Normal file
13
src/test/ui/parser/stripped-nested-outline-mod-pass.rs
Normal 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.
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue