Syntactically permit unsafety on mods
This commit is contained in:
parent
25b2f48612
commit
fd4dd00dde
17 changed files with 284 additions and 37 deletions
|
|
@ -1 +1 @@
|
|||
{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
|
||||
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
|
||||
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
|
||||
|
|
|
|||
9
src/test/ui/parser/unsafe-foreign-mod.rs
Normal file
9
src/test/ui/parser/unsafe-foreign-mod.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
unsafe extern {
|
||||
//~^ ERROR extern block cannot be declared unsafe
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
//~^ ERROR extern block cannot be declared unsafe
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
14
src/test/ui/parser/unsafe-foreign-mod.stderr
Normal file
14
src/test/ui/parser/unsafe-foreign-mod.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
error: extern block cannot be declared unsafe
|
||||
--> $DIR/unsafe-foreign-mod.rs:1:1
|
||||
|
|
||||
LL | unsafe extern {
|
||||
| ^^^^^^
|
||||
|
||||
error: extern block cannot be declared unsafe
|
||||
--> $DIR/unsafe-foreign-mod.rs:5:1
|
||||
|
|
||||
LL | unsafe extern "C" {
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
9
src/test/ui/parser/unsafe-mod.rs
Normal file
9
src/test/ui/parser/unsafe-mod.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
unsafe mod m {
|
||||
//~^ ERROR module cannot be declared unsafe
|
||||
}
|
||||
|
||||
unsafe mod n;
|
||||
//~^ ERROR module cannot be declared unsafe
|
||||
//~^^ ERROR file not found for module `n`
|
||||
|
||||
fn main() {}
|
||||
23
src/test/ui/parser/unsafe-mod.stderr
Normal file
23
src/test/ui/parser/unsafe-mod.stderr
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
error[E0583]: file not found for module `n`
|
||||
--> $DIR/unsafe-mod.rs:5:1
|
||||
|
|
||||
LL | unsafe mod n;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: to create the module `n`, create file "$DIR/n.rs"
|
||||
|
||||
error: module cannot be declared unsafe
|
||||
--> $DIR/unsafe-mod.rs:1:1
|
||||
|
|
||||
LL | unsafe mod m {
|
||||
| ^^^^^^
|
||||
|
||||
error: module cannot be declared unsafe
|
||||
--> $DIR/unsafe-mod.rs:5:1
|
||||
|
|
||||
LL | unsafe mod n;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0583`.
|
||||
89
src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs
Normal file
89
src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
// force-host
|
||||
// no-prefer-dynamic
|
||||
|
||||
// These are tests for syntax that is accepted by the Rust parser but
|
||||
// unconditionally rejected semantically after macro expansion. Attribute macros
|
||||
// are permitted to accept such syntax as long as they replace it with something
|
||||
// that makes sense to Rust.
|
||||
//
|
||||
// We also inspect some of the spans to verify the syntax is not triggering the
|
||||
// lossy string reparse hack (https://github.com/rust-lang/rust/issues/43081).
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro_span)]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::{token_stream, Delimiter, TokenStream, TokenTree};
|
||||
use std::path::Component;
|
||||
|
||||
// unsafe mod m {
|
||||
// pub unsafe mod inner;
|
||||
// }
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_unsafe_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let tokens = &mut input.into_iter();
|
||||
expect(tokens, "unsafe");
|
||||
expect(tokens, "mod");
|
||||
expect(tokens, "m");
|
||||
let tokens = &mut expect_brace(tokens);
|
||||
expect(tokens, "pub");
|
||||
expect(tokens, "unsafe");
|
||||
expect(tokens, "mod");
|
||||
let ident = expect(tokens, "inner");
|
||||
expect(tokens, ";");
|
||||
check_useful_span(ident, "unsafe-mod.rs");
|
||||
TokenStream::new()
|
||||
}
|
||||
|
||||
// unsafe extern {
|
||||
// type T;
|
||||
// }
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_unsafe_foreign_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let tokens = &mut input.into_iter();
|
||||
expect(tokens, "unsafe");
|
||||
expect(tokens, "extern");
|
||||
let tokens = &mut expect_brace(tokens);
|
||||
expect(tokens, "type");
|
||||
let ident = expect(tokens, "T");
|
||||
expect(tokens, ";");
|
||||
check_useful_span(ident, "unsafe-foreign-mod.rs");
|
||||
TokenStream::new()
|
||||
}
|
||||
|
||||
// unsafe extern "C++" {}
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_unsafe_extern_cpp_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let tokens = &mut input.into_iter();
|
||||
expect(tokens, "unsafe");
|
||||
expect(tokens, "extern");
|
||||
let abi = expect(tokens, "\"C++\"");
|
||||
expect_brace(tokens);
|
||||
check_useful_span(abi, "unsafe-foreign-mod.rs");
|
||||
TokenStream::new()
|
||||
}
|
||||
|
||||
fn expect(tokens: &mut token_stream::IntoIter, expected: &str) -> TokenTree {
|
||||
match tokens.next() {
|
||||
Some(token) if token.to_string() == expected => token,
|
||||
wrong => panic!("unexpected token: {:?}, expected `{}`", wrong, expected),
|
||||
}
|
||||
}
|
||||
|
||||
fn expect_brace(tokens: &mut token_stream::IntoIter) -> token_stream::IntoIter {
|
||||
match tokens.next() {
|
||||
Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Brace => {
|
||||
group.stream().into_iter()
|
||||
}
|
||||
wrong => panic!("unexpected token: {:?}, expected `{{`", wrong),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_useful_span(token: TokenTree, expected_filename: &str) {
|
||||
let span = token.span();
|
||||
assert!(span.start().column < span.end().column);
|
||||
|
||||
let source_path = span.source_file().path();
|
||||
let filename = source_path.components().last().unwrap();
|
||||
assert_eq!(filename, Component::Normal(expected_filename.as_ref()));
|
||||
}
|
||||
14
src/test/ui/proc-macro/unsafe-foreign-mod.rs
Normal file
14
src/test/ui/proc-macro/unsafe-foreign-mod.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// run-pass
|
||||
// aux-build:macro-only-syntax.rs
|
||||
|
||||
extern crate macro_only_syntax;
|
||||
|
||||
#[macro_only_syntax::expect_unsafe_foreign_mod]
|
||||
unsafe extern {
|
||||
type T;
|
||||
}
|
||||
|
||||
#[macro_only_syntax::expect_unsafe_extern_cpp_mod]
|
||||
unsafe extern "C++" {}
|
||||
|
||||
fn main() {}
|
||||
13
src/test/ui/proc-macro/unsafe-mod.rs
Normal file
13
src/test/ui/proc-macro/unsafe-mod.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// run-pass
|
||||
// aux-build:macro-only-syntax.rs
|
||||
|
||||
#![feature(proc_macro_hygiene)]
|
||||
|
||||
extern crate macro_only_syntax;
|
||||
|
||||
#[macro_only_syntax::expect_unsafe_mod]
|
||||
unsafe mod m {
|
||||
pub unsafe mod inner;
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue