Skip to content

Commit 0831bdf

Browse files
committed
Emit pre-expansion feature gate warning for item modifier default
1 parent 246be78 commit 0831bdf

13 files changed

Lines changed: 221 additions & 31 deletions

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,24 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
644644
gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable");
645645
gate_all_legacy_dont_use!(auto_traits, "`auto` traits are unstable");
646646
gate_all_legacy_dont_use!(negative_impls, "negative impls are experimental");
647+
gate_all_legacy_dont_use!(specialization, "specialization is experimental");
648+
649+
if let Some(spans) = spans.get(&sym::min_specialization) {
650+
for &span in spans {
651+
if !visitor.features.specialization()
652+
&& !visitor.features.min_specialization()
653+
&& !span.allows_unstable(sym::specialization)
654+
&& !span.allows_unstable(sym::min_specialization)
655+
{
656+
feature_warn(
657+
visitor.sess,
658+
sym::specialization,
659+
span,
660+
"specialization is experimental",
661+
);
662+
}
663+
}
664+
}
647665

648666
visit::walk_crate(&mut visitor, krate);
649667
}

compiler/rustc_parse/src/parser/item.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,15 @@ 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+
self.psess.gated_spans.gate(sym::min_specialization, span);
254+
self.psess.gated_spans.ungate_last(sym::specialization, span);
255+
}
251256
let (ident, sig, generics, contract, body) =
252257
self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
253258
ItemKind::Fn(Box::new(Fn {
254-
defaultness: def_(),
259+
defaultness,
255260
ident,
256261
sig,
257262
generics,
@@ -1016,6 +1021,7 @@ impl<'a> Parser<'a> {
10161021
if self.check_keyword(exp!(Default))
10171022
&& self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
10181023
{
1024+
self.psess.gated_spans.gate(sym::specialization, self.token.span);
10191025
self.bump(); // `default`
10201026
Defaultness::Default(self.prev_token_uninterpolated_span())
10211027
} else if self.eat_keyword(exp!(Final)) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ trait Foo {
44
fn foo(&self);
55
}
66

7-
default impl<T> Foo for T { //~ ERROR specialization is unstable
7+
default impl<T> Foo for T { //~ ERROR specialization is experimental
88
fn foo(&self) {}
99
}
1010

tests/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0658]: specialization is unstable
1+
error[E0658]: specialization is experimental
22
--> $DIR/specialization-feature-gate-default.rs:7:1
33
|
44
LL | / default impl<T> Foo for T {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// The gate for `default impl` is exercised in `defaultimpl/specialization-feature-gate-default.rs`.
2+
3+
trait Trait {
4+
type Ty;
5+
const CT: ();
6+
fn fn_(&self);
7+
}
8+
9+
impl<T> Trait for T {
10+
default type Ty = (); //~ ERROR specialization is experimental
11+
default const CT: () = (); //~ ERROR specialization is experimental
12+
default fn fn_(&self) {} //~ ERROR specialization is experimental
13+
}
14+
15+
fn main() {}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0658]: specialization is experimental
2+
--> $DIR/feature-gate-specialization.rs:10: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:11: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:12: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: aborting due to 3 previous errors
32+
33+
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)