Skip to content

Commit 92fbfae

Browse files
committed
Emit pre-expansion feature gate warning for item modifier default
1 parent 394012b commit 92fbfae

13 files changed

Lines changed: 238 additions & 32 deletions

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
224224
}
225225

226226
if let ast::Defaultness::Default(_) = of_trait.defaultness {
227-
gate!(self, specialization, i.span, "specialization is unstable");
227+
gate!(self, specialization, i.span, "specialization is experimental");
228228
}
229229
}
230230

@@ -450,7 +450,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
450450
self.features.specialization() || (is_fn && self.features.min_specialization()),
451451
sym::specialization,
452452
i.span,
453-
"specialization is unstable"
453+
"specialization is experimental"
454454
);
455455
}
456456
visit::walk_assoc_item(self, i, ctxt)
@@ -615,10 +615,21 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
615615
soft_gate_all_legacy_dont_use!(box_patterns, "box pattern syntax is experimental");
616616
soft_gate_all_legacy_dont_use!(decl_macro, "`macro` is experimental");
617617
soft_gate_all_legacy_dont_use!(negative_impls, "negative impls are experimental");
618+
soft_gate_all_legacy_dont_use!(specialization, "specialization is experimental");
618619
soft_gate_all_legacy_dont_use!(trait_alias, "trait aliases are experimental");
619620
soft_gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable");
620621
// tidy-alphabetical-end
621622

623+
for &span in spans.get(&sym::min_specialization).into_iter().flatten() {
624+
if !visitor.features.specialization()
625+
&& !visitor.features.min_specialization()
626+
&& !span.allows_unstable(sym::specialization)
627+
&& !span.allows_unstable(sym::min_specialization)
628+
{
629+
feature_warn(visitor.sess, sym::specialization, span, "specialization is experimental");
630+
}
631+
}
632+
622633
// -----------------------------------------------------------------------------
623634

624635
visit::walk_crate(&mut visitor, krate);

compiler/rustc_parse/src/parser/item.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,18 @@ impl<'a> Parser<'a> {
248248
self.parse_use_item()?
249249
} else if self.check_fn_front_matter(check_pub, case) {
250250
// FUNCTION ITEM
251+
let defaultness = def_();
252+
if let Defaultness::Default(span) = defaultness {
253+
// Default functions should only require feature `min_specialization`. We remove the
254+
// `specialization` tag again as such spans *require* feature `specialization` to be
255+
// enabled. In a later stage, we make `specialization` imply `min_specialization`.
256+
self.psess.gated_spans.gate(sym::min_specialization, span);
257+
self.psess.gated_spans.ungate_last(sym::specialization, span);
258+
}
251259
let (ident, sig, generics, contract, body) =
252260
self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
253261
ItemKind::Fn(Box::new(Fn {
254-
defaultness: def_(),
262+
defaultness,
255263
ident,
256264
sig,
257265
generics,
@@ -1016,6 +1024,7 @@ impl<'a> Parser<'a> {
10161024
if self.check_keyword(exp!(Default))
10171025
&& self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
10181026
{
1027+
self.psess.gated_spans.gate(sym::specialization, self.token.span);
10191028
self.bump(); // `default`
10201029
Defaultness::Default(self.prev_token_uninterpolated_span())
10211030
} else if self.eat_keyword(exp!(Final)) {

tests/ui/macros/stringify.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
#![feature(const_trait_impl)]
1010
#![feature(coroutines)]
1111
#![feature(decl_macro)]
12+
#![feature(macro_guard_matcher)]
1213
#![feature(more_qualified_paths)]
1314
#![feature(never_patterns)]
15+
#![feature(specialization)]
1416
#![feature(trait_alias)]
1517
#![feature(try_blocks)]
1618
#![feature(yeet_expr)]
17-
#![feature(macro_guard_matcher)]
1819
#![deny(unused_macros)]
1920

2021
// These macros force the use of AST pretty-printing by converting the input to

tests/ui/parser/trait-item-with-defaultness-pass.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@ check-pass
2+
#![feature(specialization)]
23

34
fn main() {}
45

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
trait Trait {
2+
type Ty;
3+
const CT: ();
4+
fn fn_(&self);
5+
}
6+
7+
impl<T> Trait for T {
8+
default type Ty = (); //~ ERROR specialization is experimental
9+
default const CT: () = (); //~ ERROR specialization is experimental
10+
default fn fn_(&self) {} //~ ERROR specialization is experimental
11+
}
12+
13+
trait OtherTrait {
14+
fn fn_();
15+
}
16+
17+
default impl<T> OtherTrait for T { //~ ERROR specialization is experimental
18+
fn fn_() {}
19+
}
20+
21+
fn main() {}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
error[E0658]: specialization is experimental
2+
--> $DIR/feature-gate-specialization.rs:8:5
3+
|
4+
LL | default type Ty = ();
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: add `#![feature(specialization)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error[E0658]: specialization is experimental
12+
--> $DIR/feature-gate-specialization.rs:9:5
13+
|
14+
LL | default const CT: () = ();
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
18+
= help: add `#![feature(specialization)]` to the crate attributes to enable
19+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
20+
21+
error[E0658]: specialization is experimental
22+
--> $DIR/feature-gate-specialization.rs:10:5
23+
|
24+
LL | default fn fn_(&self) {}
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^
26+
|
27+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
28+
= help: add `#![feature(specialization)]` to the crate attributes to enable
29+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
30+
31+
error[E0658]: specialization is experimental
32+
--> $DIR/feature-gate-specialization.rs:17:1
33+
|
34+
LL | / default impl<T> OtherTrait for T {
35+
LL | | fn fn_() {}
36+
LL | | }
37+
| |_^
38+
|
39+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
40+
= help: add `#![feature(specialization)]` to the crate attributes to enable
41+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
42+
43+
error: aborting due to 4 previous errors
44+
45+
For more information about this error, try `rustc --explain E0658`.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
warning: specialization is experimental
2+
--> $DIR/soft-feature-gate-specialization.rs:21:5
3+
|
4+
LL | default type Ty = ();
5+
| ^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: add `#![feature(specialization)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
= warning: unstable syntax can change at any point in the future, causing a hard error!
11+
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
12+
13+
warning: specialization is experimental
14+
--> $DIR/soft-feature-gate-specialization.rs:24:5
15+
|
16+
LL | default const CT: () = ();
17+
| ^^^^^^^
18+
|
19+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
20+
= help: add `#![feature(specialization)]` to the crate attributes to enable
21+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
22+
= warning: unstable syntax can change at any point in the future, causing a hard error!
23+
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
24+
25+
warning: specialization is experimental
26+
--> $DIR/soft-feature-gate-specialization.rs:40:1
27+
|
28+
LL | default impl Trait for () {}
29+
| ^^^^^^^
30+
|
31+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
32+
= help: add `#![feature(specialization)]` to the crate attributes to enable
33+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
34+
= warning: unstable syntax can change at any point in the future, causing a hard error!
35+
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
36+
37+
warning: specialization is experimental
38+
--> $DIR/soft-feature-gate-specialization.rs:27:5
39+
|
40+
LL | default fn fn_();
41+
| ^^^^^^^
42+
|
43+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
44+
= help: add `#![feature(specialization)]` to the crate attributes to enable
45+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
46+
= warning: unstable syntax can change at any point in the future, causing a hard error!
47+
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
48+
49+
warning: specialization is experimental
50+
--> $DIR/soft-feature-gate-specialization.rs:35:1
51+
|
52+
LL | default fn fn_() {}
53+
| ^^^^^^^
54+
|
55+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
56+
= help: add `#![feature(specialization)]` to the crate attributes to enable
57+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
58+
= warning: unstable syntax can change at any point in the future, causing a hard error!
59+
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
60+
61+
warning: 5 warnings emitted
62+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
warning: specialization is experimental
2+
--> $DIR/soft-feature-gate-specialization.rs:21:5
3+
|
4+
LL | default type Ty = ();
5+
| ^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: add `#![feature(specialization)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
= warning: unstable syntax can change at any point in the future, causing a hard error!
11+
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
12+
13+
warning: specialization is experimental
14+
--> $DIR/soft-feature-gate-specialization.rs:24:5
15+
|
16+
LL | default const CT: () = ();
17+
| ^^^^^^^
18+
|
19+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
20+
= help: add `#![feature(specialization)]` to the crate attributes to enable
21+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
22+
= warning: unstable syntax can change at any point in the future, causing a hard error!
23+
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
24+
25+
warning: specialization is experimental
26+
--> $DIR/soft-feature-gate-specialization.rs:40:1
27+
|
28+
LL | default impl Trait for () {}
29+
| ^^^^^^^
30+
|
31+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
32+
= help: add `#![feature(specialization)]` to the crate attributes to enable
33+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
34+
= warning: unstable syntax can change at any point in the future, causing a hard error!
35+
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
36+
37+
warning: 3 warnings emitted
38+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// For historical reasons, item modifier `default` doesn't have a proper pre-expansion feature gate.
2+
// We're now at least issuing a *warning* for those that only exist before macro expansion.
3+
// FIXME(#154045): Turn their post-expansion feature gate into a proper pre-expansion one.
4+
// As part of this, move these test cases into `feature-gate-specialization.rs`.
5+
//
6+
// Moreover, `specialization` implies `min_specialization` similar to the post-expansion gate.
7+
//
8+
// However, while we only gate `default` *associated* functions only behind `min_specialization` OR
9+
// `specialization` in the post-expansion case, in the pre-expansion case we gate all kinds of
10+
// functions (free, assoc, foreign) behind `min_specialization` OR `specialization` if marked with
11+
// `default` for simplicity of implementation. Ultimately it doesn't matter since we later reject
12+
// `default` on anything other than impls & impl assoc items during semantic analysis.
13+
//
14+
//@ revisions: default min full
15+
//@ check-pass
16+
#![cfg_attr(min, feature(min_specialization))]
17+
#![cfg_attr(full, feature(specialization))]
18+
19+
#[cfg(false)]
20+
impl Trait for () {
21+
default type Ty = ();
22+
//[default,min]~^ WARN specialization is experimental
23+
//[default,min]~| WARN unstable syntax can change at any point in the future
24+
default const CT: () = ();
25+
//[default,min]~^ WARN specialization is experimental
26+
//[default,min]~| WARN unstable syntax can change at any point in the future
27+
default fn fn_();
28+
//[default]~^ WARN specialization is experimental
29+
//[default]~| WARN unstable syntax can change at any point in the future
30+
}
31+
32+
// While free ty/ct/fn items marked `default` are
33+
// semantically malformed we still need to gate the keyword!
34+
#[cfg(false)]
35+
default fn fn_() {}
36+
//[default]~^ WARN specialization is experimental
37+
//[default]~| WARN unstable syntax can change at any point in the future
38+
39+
#[cfg(false)]
40+
default impl Trait for () {}
41+
//[default,min]~^ WARN specialization is experimental
42+
//[default,min]~| WARN unstable syntax can change at any point in the future
43+
44+
fn main() {}

tests/ui/specialization/specialization-feature-gate-default.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)