Skip to content

Commit e620d61

Browse files
committed
Emit pre-expansion feature gate warning for item modifier default
1 parent 2bb9e92 commit e620d61

17 files changed

Lines changed: 254 additions & 32 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)) {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
auto trait MyTrait {}
2+
//~^ ERROR auto traits are experimental and possibly buggy
3+
4+
impl<T> !MyTrait for *mut T {}
5+
//~^ ERROR negative trait bounds are not fully implemented
6+
7+
fn main() {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0658]: auto traits are experimental and possibly buggy
2+
--> $DIR/ungated-impl.rs:1:1
3+
|
4+
LL | auto trait MyTrait {}
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #13231 <https://github.com/rust-lang/rust/issues/13231> for more information
8+
= help: add `#![feature(auto_traits)]` 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]: negative trait bounds are not fully implemented; use marker types for now
12+
--> $DIR/ungated-impl.rs:4:9
13+
|
14+
LL | impl<T> !MyTrait for *mut T {}
15+
| ^^^^^^^^
16+
|
17+
= note: see issue #68318 <https://github.com/rust-lang/rust/issues/68318> for more information
18+
= help: add `#![feature(negative_impls)]` 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: aborting due to 2 previous errors
22+
23+
For more information about this error, try `rustc --explain E0658`.

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

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`.

0 commit comments

Comments
 (0)