mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Rollup merge of #53413 - eddyb:featured-in-the-latest-edition, r=varkor
Warn that `#![feature(rust_2018_preview)]` is implied when the edition is set to Rust 2018. cc @varkor @petrochenkov @joshtriplett
This commit is contained in:
commit
5c7b837c4e
@ -1930,7 +1930,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||
let mut features = Features::new();
|
||||
let mut edition_enabled_features = FxHashMap();
|
||||
|
||||
for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
|
||||
for &edition in ALL_EDITIONS {
|
||||
if edition <= crate_edition {
|
||||
// The `crate_edition` implies its respective umbrella feature-gate
|
||||
// (i.e. `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
|
||||
edition_enabled_features.insert(Symbol::intern(edition.feature_name()), edition);
|
||||
}
|
||||
}
|
||||
|
||||
for &(name, .., f_edition, set) in ACTIVE_FEATURES {
|
||||
if let Some(f_edition) = f_edition {
|
||||
if f_edition <= crate_edition {
|
||||
set(&mut features, DUMMY_SP);
|
||||
@ -1939,6 +1947,54 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||
}
|
||||
}
|
||||
|
||||
// Process the edition umbrella feature-gates first, to ensure
|
||||
// `edition_enabled_features` is completed before it's queried.
|
||||
for attr in krate_attrs {
|
||||
if !attr.check_name("feature") {
|
||||
continue
|
||||
}
|
||||
|
||||
let list = match attr.meta_item_list() {
|
||||
Some(list) => list,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
for mi in list {
|
||||
let name = if let Some(word) = mi.word() {
|
||||
word.name()
|
||||
} else {
|
||||
continue
|
||||
};
|
||||
|
||||
if incomplete_features.iter().any(|f| *f == name.as_str()) {
|
||||
span_handler.struct_span_warn(
|
||||
mi.span,
|
||||
&format!(
|
||||
"the feature `{}` is incomplete and may cause the compiler to crash",
|
||||
name
|
||||
)
|
||||
).emit();
|
||||
}
|
||||
|
||||
if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
|
||||
if *edition <= crate_edition {
|
||||
continue;
|
||||
}
|
||||
|
||||
for &(name, .., f_edition, set) in ACTIVE_FEATURES {
|
||||
if let Some(f_edition) = f_edition {
|
||||
if f_edition <= *edition {
|
||||
// FIXME(Manishearth) there is currently no way to set
|
||||
// lib features by edition
|
||||
set(&mut features, DUMMY_SP);
|
||||
edition_enabled_features.insert(Symbol::intern(name), *edition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for attr in krate_attrs {
|
||||
if !attr.check_name("feature") {
|
||||
continue
|
||||
@ -1962,49 +2018,26 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||
continue
|
||||
};
|
||||
|
||||
if incomplete_features.iter().any(|f| *f == name.as_str()) {
|
||||
span_handler.struct_span_warn(
|
||||
if let Some(edition) = edition_enabled_features.get(&name) {
|
||||
struct_span_warn!(
|
||||
span_handler,
|
||||
mi.span,
|
||||
&format!(
|
||||
"the feature `{}` is incomplete and may cause the compiler to crash",
|
||||
name
|
||||
)
|
||||
E0705,
|
||||
"the feature `{}` is included in the Rust {} edition",
|
||||
name,
|
||||
edition,
|
||||
).emit();
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
|
||||
if *edition <= crate_edition {
|
||||
continue
|
||||
}
|
||||
|
||||
for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
|
||||
if let Some(f_edition) = f_edition {
|
||||
if f_edition <= *edition {
|
||||
// FIXME(Manishearth) there is currently no way to set
|
||||
// lib features by edition
|
||||
set(&mut features, DUMMY_SP);
|
||||
edition_enabled_features.insert(Symbol::intern(name), *edition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
|
||||
// Handled in the separate loop above.
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
|
||||
if let Some(edition) = edition_enabled_features.get(&name) {
|
||||
struct_span_warn!(
|
||||
span_handler,
|
||||
mi.span,
|
||||
E0705,
|
||||
"the feature `{}` is included in the Rust {} edition",
|
||||
name,
|
||||
edition,
|
||||
).emit();
|
||||
} else {
|
||||
set(&mut features, mi.span);
|
||||
features.declared_lang_features.push((name, mi.span, None));
|
||||
}
|
||||
set(&mut features, mi.span);
|
||||
features.declared_lang_features.push((name, mi.span, None));
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
//
|
||||
// This test focuses on non-error cases and making sure the correct number of repetitions happen.
|
||||
|
||||
// compile-flags: --edition=2018
|
||||
// edition:2018
|
||||
|
||||
#![feature(macro_at_most_once_rep)]
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
// FIXME: once `--edition` is stable in rustdoc, remove that `compile-flags` directive
|
||||
|
||||
#![feature(rust_2018_preview, async_await, futures_api)]
|
||||
#![feature(async_await, futures_api)]
|
||||
|
||||
// @has async_fn/struct.S.html
|
||||
// @has - '//code' 'pub async fn f()'
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:suggestions-not-always-applicable.rs
|
||||
// compile-flags: --edition 2015
|
||||
// edition:2015
|
||||
// run-rustfix
|
||||
// rustfix-only-machine-applicable
|
||||
// compile-pass
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:suggestions-not-always-applicable.rs
|
||||
// compile-flags: --edition 2015
|
||||
// edition:2015
|
||||
// run-rustfix
|
||||
// rustfix-only-machine-applicable
|
||||
// compile-pass
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: --edition 2018
|
||||
// edition:2018
|
||||
|
||||
#![deny(unused_extern_crates)]
|
||||
#![feature(alloc, test, libc)]
|
||||
|
@ -10,9 +10,9 @@
|
||||
|
||||
// compile-pass
|
||||
|
||||
#![feature(rust_2018_preview)]
|
||||
#![feature(raw_identifiers)]
|
||||
//~^ WARN the feature `raw_identifiers` is included in the Rust 2018 edition
|
||||
#![feature(rust_2018_preview)]
|
||||
|
||||
fn main() {
|
||||
let foo = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning[E0705]: the feature `raw_identifiers` is included in the Rust 2018 edition
|
||||
--> $DIR/E0705.rs:14:12
|
||||
--> $DIR/E0705.rs:13:12
|
||||
|
|
||||
LL | #![feature(raw_identifiers)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
// revisions: zflag edition
|
||||
// [zflag]compile-flags: -Z borrowck=migrate
|
||||
// [edition]compile-flags: --edition 2018
|
||||
// [edition]edition:2018
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
// revisions: zflag edition
|
||||
//[zflag]compile-flags: -Z borrowck=migrate
|
||||
//[edition]compile-flags: --edition 2018
|
||||
//[edition]edition:2018
|
||||
//[zflag] run-pass
|
||||
//[edition] run-pass
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
// revisions: ast zflags edition
|
||||
//[zflags]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
|
||||
//[edition]compile-flags: --edition 2018
|
||||
//[edition]edition:2018
|
||||
|
||||
// run-pass
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:edition-extern-crate-allowed.rs
|
||||
// compile-flags: --edition 2015
|
||||
// edition:2015
|
||||
// compile-pass
|
||||
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
@ -8,7 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags:--edition 2018
|
||||
// compile-pass
|
||||
|
||||
#![feature(rust_2018_preview)]
|
||||
|
17
src/test/ui/editions/edition-feature-redundant.rs
Normal file
17
src/test/ui/editions/edition-feature-redundant.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// edition:2018
|
||||
// compile-pass
|
||||
|
||||
#![feature(rust_2018_preview)]
|
||||
//~^ WARN the feature `rust_2018_preview` is included in the Rust 2018 edition
|
||||
|
||||
fn main() {}
|
6
src/test/ui/editions/edition-feature-redundant.stderr
Normal file
6
src/test/ui/editions/edition-feature-redundant.stderr
Normal file
@ -0,0 +1,6 @@
|
||||
warning[E0705]: the feature `rust_2018_preview` is included in the Rust 2018 edition
|
||||
--> $DIR/edition-feature-redundant.rs:14:12
|
||||
|
|
||||
LL | #![feature(rust_2018_preview)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// run-rustfix
|
||||
// compile-flags: --edition 2018
|
||||
// edition:2018
|
||||
|
||||
#![allow(unused)]
|
||||
#![deny(elided_lifetimes_in_paths)]
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// run-rustfix
|
||||
// compile-flags: --edition 2018
|
||||
// edition:2018
|
||||
|
||||
#![allow(unused)]
|
||||
#![deny(elided_lifetimes_in_paths)]
|
||||
|
@ -12,7 +12,7 @@
|
||||
// with the feature flag.
|
||||
|
||||
// gate-test-macro_at_most_once_rep
|
||||
// compile-flags: --edition=2015
|
||||
// edition:2015
|
||||
|
||||
#![feature(macro_at_most_once_rep)]
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// Test behavior of `?` macro _kleene op_ under the 2015 edition. Namely, it doesn't exist.
|
||||
|
||||
// compile-flags: --edition=2015
|
||||
// edition:2015
|
||||
|
||||
macro_rules! bar {
|
||||
($(a)?) => {} //~ERROR expected `*` or `+`
|
||||
|
@ -11,7 +11,7 @@
|
||||
// Test behavior of `?` macro _separator_ under the 2015 edition. Namely, `?` can be used as a
|
||||
// separator, but you get a migration warning for the edition.
|
||||
|
||||
// compile-flags: --edition=2015
|
||||
// edition:2015
|
||||
// compile-pass
|
||||
|
||||
#![warn(rust_2018_compatibility)]
|
||||
|
@ -11,7 +11,7 @@
|
||||
// Feature gate test for macro_at_most_once_rep under 2018 edition.
|
||||
|
||||
// gate-test-macro_at_most_once_rep
|
||||
// compile-flags: --edition=2018
|
||||
// edition:2018
|
||||
|
||||
macro_rules! foo {
|
||||
($(a)?) => {}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// Tests that `?` is a Kleene op and not a macro separator in the 2018 edition.
|
||||
|
||||
// compile-flags: --edition=2018
|
||||
// edition:2018
|
||||
|
||||
#![feature(macro_at_most_once_rep)]
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: --edition 2018
|
||||
// edition:2018
|
||||
// aux-build:removing-extern-crate.rs
|
||||
// run-rustfix
|
||||
// compile-pass
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: --edition 2018
|
||||
// edition:2018
|
||||
// aux-build:removing-extern-crate.rs
|
||||
// run-rustfix
|
||||
// compile-pass
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: --edition 2015
|
||||
// edition:2015
|
||||
|
||||
#![deny(rust_2018_compatibility)]
|
||||
|
||||
|
@ -10,12 +10,11 @@
|
||||
|
||||
// aux-build:edition-lint-paths.rs
|
||||
// run-rustfix
|
||||
// compile-flags:--edition 2018
|
||||
// edition:2018
|
||||
|
||||
// The "normal case". Ideally we would remove the `extern crate` here,
|
||||
// but we don't.
|
||||
|
||||
#![feature(rust_2018_preview)]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
|
@ -10,12 +10,11 @@
|
||||
|
||||
// aux-build:edition-lint-paths.rs
|
||||
// run-rustfix
|
||||
// compile-flags:--edition 2018
|
||||
// edition:2018
|
||||
|
||||
// The "normal case". Ideally we would remove the `extern crate` here,
|
||||
// but we don't.
|
||||
|
||||
#![feature(rust_2018_preview)]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
error: unused extern crate
|
||||
--> $DIR/extern-crate-idiomatic-in-2018.rs:22:1
|
||||
--> $DIR/extern-crate-idiomatic-in-2018.rs:21:1
|
||||
|
|
||||
LL | extern crate edition_lint_paths;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/extern-crate-idiomatic-in-2018.rs:19:9
|
||||
--> $DIR/extern-crate-idiomatic-in-2018.rs:18:9
|
||||
|
|
||||
LL | #![deny(rust_2018_idioms)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
|
||||
|
||||
error: `extern crate` is not idiomatic in the new edition
|
||||
--> $DIR/extern-crate-idiomatic-in-2018.rs:25:1
|
||||
--> $DIR/extern-crate-idiomatic-in-2018.rs:24:1
|
||||
|
|
||||
LL | extern crate edition_lint_paths as bar;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: --edition 2018
|
||||
// edition:2018
|
||||
|
||||
// The local `use` suggestion should start with `crate::` (but the
|
||||
// standard-library suggestions should not, obviously).
|
||||
|
Loading…
Reference in New Issue
Block a user