Rollup merge of #65742 - Centril:gate-pre-expansion-subset, r=davidtwco

Pre-expansion gate most of the things

This is a subset of https://github.com/rust-lang/rust/pull/64672. A crater run has already been done and this PR implements conclusions according to https://github.com/rust-lang/rust/pull/64672#issuecomment-542703363.

r? @davidtwco
cc @petrochenkov
This commit is contained in:
Mazdak Farrokhzad 2019-10-25 06:18:09 +02:00 committed by GitHub
commit d6a18b6baf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 295 additions and 182 deletions

View file

@ -220,7 +220,7 @@
#![cfg_attr(test, feature(print_internals, set_stdio, update_panic_count))]
#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
feature(slice_index_methods, decl_macro, coerce_unsized,
feature(slice_index_methods, coerce_unsized,
sgx_platform, ptr_wrapping_offset_from))]
#![cfg_attr(all(test, target_vendor = "fortanix", target_env = "sgx"),
feature(fixed_size_array, maybe_uninit_extra))]
@ -251,6 +251,7 @@
#![feature(container_error_extra)]
#![feature(core_intrinsics)]
#![feature(custom_test_frameworks)]
#![feature(decl_macro)]
#![feature(doc_alias)]
#![feature(doc_cfg)]
#![feature(doc_keyword)]

View file

@ -3,12 +3,8 @@ use super::accepted::ACCEPTED_FEATURES;
use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
use super::builtin_attrs::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
use crate::ast::{
self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
PatKind, RangeEnd, VariantData,
};
use crate::ast::{self, NodeId, PatKind, VariantData};
use crate::attr::{self, check_builtin_attribute};
use crate::source_map::Spanned;
use crate::edition::{ALL_EDITIONS, Edition};
use crate::visit::{self, FnKind, Visitor};
use crate::parse::token;
@ -157,9 +153,6 @@ fn leveled_feature_err<'a, S: Into<MultiSpan>>(
}
const EXPLAIN_BOX_SYNTAX: &str =
"box expression syntax is experimental; you can call `Box::new` instead";
pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
"attributes on expressions are experimental";
@ -291,6 +284,25 @@ impl<'a> PostExpansionVisitor<'a> {
err.emit();
}
}
fn check_gat(&self, generics: &ast::Generics, span: Span) {
if !generics.params.is_empty() {
gate_feature_post!(
&self,
generic_associated_types,
span,
"generic associated types are unstable"
);
}
if !generics.where_clause.predicates.is_empty() {
gate_feature_post!(
&self,
generic_associated_types,
span,
"where clauses on associated types are unstable"
);
}
}
}
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
@ -423,20 +435,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
"auto traits are experimental and possibly buggy");
}
ast::ItemKind::TraitAlias(..) => {
gate_feature_post!(
&self,
trait_alias,
i.span,
"trait aliases are experimental"
);
}
ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => {
let msg = "`macro` is experimental";
gate_feature_post!(&self, decl_macro, i.span, msg);
}
ast::ItemKind::OpaqueTy(..) => {
gate_feature_post!(
&self,
@ -500,37 +498,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
fn visit_expr(&mut self, e: &'a ast::Expr) {
match e.kind {
ast::ExprKind::Box(_) => {
gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX);
}
ast::ExprKind::Type(..) => {
// To avoid noise about type ascription in common syntax errors, only emit if it
// is the *only* error.
if self.parse_sess.span_diagnostic.err_count() == 0 {
gate_feature_post!(&self, type_ascription, e.span,
"type ascription is experimental");
}
}
ast::ExprKind::TryBlock(_) => {
gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
}
ast::ExprKind::Block(_, opt_label) => {
if let Some(label) = opt_label {
gate_feature_post!(&self, label_break_value, label.ident.span,
"labels on blocks are unstable");
}
}
_ => {}
}
visit::walk_expr(self, e)
}
fn visit_arm(&mut self, arm: &'a ast::Arm) {
visit::walk_arm(self, arm)
}
fn visit_pat(&mut self, pattern: &'a ast::Pat) {
match &pattern.kind {
PatKind::Slice(pats) => {
@ -550,25 +517,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
}
PatKind::Box(..) => {
gate_feature_post!(&self, box_patterns,
pattern.span,
"box pattern syntax is experimental");
}
PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => {
gate_feature_post!(&self, exclusive_range_pattern, pattern.span,
"exclusive range pattern syntax is experimental");
}
_ => {}
}
visit::walk_pat(self, pattern)
}
fn visit_fn(&mut self,
fn_kind: FnKind<'a>,
fn_decl: &'a ast::FnDecl,
span: Span,
_node_id: NodeId) {
fn visit_fn(&mut self, fn_kind: FnKind<'a>, fn_decl: &'a ast::FnDecl, span: Span, _: NodeId) {
if let Some(header) = fn_kind.header() {
// Stability of const fn methods are covered in
// `visit_trait_item` and `visit_impl_item` below; this is
@ -583,26 +537,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
visit::walk_fn(self, fn_kind, fn_decl, span)
}
fn visit_generic_param(&mut self, param: &'a GenericParam) {
match param.kind {
GenericParamKind::Const { .. } =>
gate_feature_post!(&self, const_generics, param.ident.span,
"const generics are unstable"),
_ => {}
}
visit::walk_generic_param(self, param)
}
fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
match constraint.kind {
AssocTyConstraintKind::Bound { .. } =>
gate_feature_post!(&self, associated_type_bounds, constraint.span,
"associated type bounds are unstable"),
_ => {}
}
visit::walk_assoc_ty_constraint(self, constraint)
}
fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
match ti.kind {
ast::TraitItemKind::Method(ref sig, ref block) => {
@ -624,14 +558,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, associated_type_defaults, ti.span,
"associated type defaults are unstable");
}
if !ti.generics.params.is_empty() {
gate_feature_post!(&self, generic_associated_types, ti.span,
"generic associated types are unstable");
}
if !ti.generics.where_clause.predicates.is_empty() {
gate_feature_post!(&self, generic_associated_types, ti.span,
"where clauses on associated types are unstable");
}
self.check_gat(&ti.generics, ti.span);
}
_ => {}
}
@ -661,27 +588,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
);
}
ast::ImplItemKind::TyAlias(_) => {
if !ii.generics.params.is_empty() {
gate_feature_post!(&self, generic_associated_types, ii.span,
"generic associated types are unstable");
}
if !ii.generics.where_clause.predicates.is_empty() {
gate_feature_post!(&self, generic_associated_types, ii.span,
"where clauses on associated types are unstable");
}
self.check_gat(&ii.generics, ii.span);
}
_ => {}
}
visit::walk_impl_item(self, ii)
}
fn visit_vis(&mut self, vis: &'a ast::Visibility) {
if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node {
gate_feature_post!(&self, crate_visibility_modifier, vis.span,
"`crate` visibility modifier is experimental");
}
visit::walk_vis(self, vis)
}
}
pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
@ -867,6 +779,22 @@ pub fn check_crate(krate: &ast::Crate,
gate_all!(yields, generators, "yield syntax is experimental");
gate_all!(or_patterns, "or-patterns syntax is experimental");
gate_all!(const_extern_fn, "`const extern fn` definitions are unstable");
gate_all!(trait_alias, "trait aliases are experimental");
gate_all!(associated_type_bounds, "associated type bounds are unstable");
gate_all!(crate_visibility_modifier, "`crate` visibility modifier is experimental");
gate_all!(const_generics, "const generics are unstable");
gate_all!(decl_macro, "`macro` is experimental");
gate_all!(box_patterns, "box pattern syntax is experimental");
gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
gate_all!(try_blocks, "`try` blocks are unstable");
gate_all!(label_break_value, "labels on blocks are unstable");
gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
// To avoid noise about type ascription in common syntax errors,
// only emit if it is the *only* error. (Also check it last.)
if parse_sess.span_diagnostic.err_count() == 0 {
gate_all!(type_ascription, "type ascription is experimental");
}
visit::walk_crate(&mut visitor, krate);
}

View file

@ -1122,6 +1122,7 @@ impl<'a> Parser<'a> {
self.expected_tokens.push(TokenType::Keyword(kw::Crate));
if self.is_crate_vis() {
self.bump(); // `crate`
self.sess.gated_spans.crate_visibility_modifier.borrow_mut().push(self.prev_span);
return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate)));
}

View file

@ -252,6 +252,7 @@ impl<'a> Parser<'a> {
self.last_type_ascription = Some((self.prev_span, maybe_path));
lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
self.sess.gated_spans.type_ascription.borrow_mut().push(lhs.span);
continue
} else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
// If we didnt have to handle `x..`/`x..=`, it would be pretty easy to
@ -453,7 +454,9 @@ impl<'a> Parser<'a> {
self.bump();
let e = self.parse_prefix_expr(None);
let (span, e) = self.interpolated_or_expr_span(e)?;
(lo.to(span), ExprKind::Box(e))
let span = lo.to(span);
self.sess.gated_spans.box_syntax.borrow_mut().push(span);
(span, ExprKind::Box(e))
}
token::Ident(..) if self.token.is_ident_named(sym::not) => {
// `not` is just an ordinary identifier in Rust-the-language,
@ -1260,6 +1263,10 @@ impl<'a> Parser<'a> {
blk_mode: BlockCheckMode,
outer_attrs: ThinVec<Attribute>,
) -> PResult<'a, P<Expr>> {
if let Some(label) = opt_label {
self.sess.gated_spans.label_break_value.borrow_mut().push(label.ident.span);
}
self.expect(&token::OpenDelim(token::Brace))?;
let mut attrs = outer_attrs;
@ -1646,7 +1653,9 @@ impl<'a> Parser<'a> {
error.emit();
Err(error)
} else {
Ok(self.mk_expr(span_lo.to(body.span), ExprKind::TryBlock(body), attrs))
let span = span_lo.to(body.span);
self.sess.gated_spans.try_blocks.borrow_mut().push(span);
Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs))
}
}

View file

@ -55,11 +55,15 @@ impl<'a> Parser<'a> {
}
fn parse_const_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, GenericParam> {
let lo = self.token.span;
self.expect_keyword(kw::Const)?;
let ident = self.parse_ident()?;
self.expect(&token::Colon)?;
let ty = self.parse_ty()?;
self.sess.gated_spans.const_generics.borrow_mut().push(lo.to(self.prev_span));
Ok(GenericParam {
ident,
id: ast::DUMMY_NODE_ID,

View file

@ -211,7 +211,7 @@ impl<'a> Parser<'a> {
{
// UNSAFE TRAIT ITEM
self.bump(); // `unsafe`
let info = self.parse_item_trait(Unsafety::Unsafe)?;
let info = self.parse_item_trait(lo, Unsafety::Unsafe)?;
return self.mk_item_with_info(attrs, lo, vis, info);
}
@ -289,7 +289,7 @@ impl<'a> Parser<'a> {
&& self.is_keyword_ahead(1, &[kw::Trait]))
{
// TRAIT ITEM
let info = self.parse_item_trait(Unsafety::Normal)?;
let info = self.parse_item_trait(lo, Unsafety::Normal)?;
return self.mk_item_with_info(attrs, lo, vis, info);
}
@ -780,7 +780,7 @@ impl<'a> Parser<'a> {
}
/// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
fn parse_item_trait(&mut self, lo: Span, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
// Parse optional `auto` prefix.
let is_auto = if self.eat_keyword(kw::Auto) {
IsAuto::Yes
@ -793,29 +793,43 @@ impl<'a> Parser<'a> {
let mut tps = self.parse_generics()?;
// Parse optional colon and supertrait bounds.
let bounds = if self.eat(&token::Colon) {
let had_colon = self.eat(&token::Colon);
let span_at_colon = self.prev_span;
let bounds = if had_colon {
self.parse_generic_bounds(Some(self.prev_span))?
} else {
Vec::new()
};
let span_before_eq = self.prev_span;
if self.eat(&token::Eq) {
// It's a trait alias.
if had_colon {
let span = span_at_colon.to(span_before_eq);
self.struct_span_err(span, "bounds are not allowed on trait aliases")
.emit();
}
let bounds = self.parse_generic_bounds(None)?;
tps.where_clause = self.parse_where_clause()?;
self.expect(&token::Semi)?;
let whole_span = lo.to(self.prev_span);
if is_auto == IsAuto::Yes {
let msg = "trait aliases cannot be `auto`";
self.struct_span_err(self.prev_span, msg)
.span_label(self.prev_span, msg)
self.struct_span_err(whole_span, msg)
.span_label(whole_span, msg)
.emit();
}
if unsafety != Unsafety::Normal {
let msg = "trait aliases cannot be `unsafe`";
self.struct_span_err(self.prev_span, msg)
.span_label(self.prev_span, msg)
self.struct_span_err(whole_span, msg)
.span_label(whole_span, msg)
.emit();
}
self.sess.gated_spans.trait_alias.borrow_mut().push(whole_span);
Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
} else {
// It's a normal trait.
@ -1692,6 +1706,11 @@ impl<'a> Parser<'a> {
};
let span = lo.to(self.prev_span);
if !def.legacy {
self.sess.gated_spans.decl_macro.borrow_mut().push(span);
}
Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
}

View file

@ -324,7 +324,9 @@ impl<'a> Parser<'a> {
self.parse_pat_ident(BindingMode::ByRef(mutbl))?
} else if self.eat_keyword(kw::Box) {
// Parse `box pat`
PatKind::Box(self.parse_pat_with_range_pat(false, None)?)
let pat = self.parse_pat_with_range_pat(false, None)?;
self.sess.gated_spans.box_patterns.borrow_mut().push(lo.to(self.prev_span));
PatKind::Box(pat)
} else if self.can_be_ident_pat() {
// Parse `ident @ pat`
// This can give false positives and parse nullary enums,
@ -609,6 +611,11 @@ impl<'a> Parser<'a> {
Ok(PatKind::Mac(mac))
}
fn excluded_range_end(&self, span: Span) -> RangeEnd {
self.sess.gated_spans.exclusive_range_pattern.borrow_mut().push(span);
RangeEnd::Excluded
}
/// Parse a range pattern `$path $form $end?` where `$form = ".." | "..." | "..=" ;`.
/// The `$path` has already been parsed and the next token is the `$form`.
fn parse_pat_range_starting_with_path(
@ -618,7 +625,7 @@ impl<'a> Parser<'a> {
path: Path
) -> PResult<'a, PatKind> {
let (end_kind, form) = match self.token.kind {
token::DotDot => (RangeEnd::Excluded, ".."),
token::DotDot => (self.excluded_range_end(self.token.span), ".."),
token::DotDotDot => (RangeEnd::Included(RangeSyntax::DotDotDot), "..."),
token::DotDotEq => (RangeEnd::Included(RangeSyntax::DotDotEq), "..="),
_ => panic!("can only parse `..`/`...`/`..=` for ranges (checked above)"),
@ -641,7 +648,7 @@ impl<'a> Parser<'a> {
} else if self.eat(&token::DotDotEq) {
(RangeEnd::Included(RangeSyntax::DotDotEq), "..=")
} else if self.eat(&token::DotDot) {
(RangeEnd::Excluded, "..")
(self.excluded_range_end(op_span), "..")
} else {
panic!("impossible case: we already matched on a range-operator token")
};

View file

@ -404,8 +404,9 @@ impl<'a> Parser<'a> {
// Parse lifetime argument.
args.push(GenericArg::Lifetime(self.expect_lifetime()));
misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
} else if self.check_ident() && self.look_ahead(1,
|t| t == &token::Eq || t == &token::Colon) {
} else if self.check_ident()
&& self.look_ahead(1, |t| t == &token::Eq || t == &token::Colon)
{
// Parse associated type constraint.
let lo = self.token.span;
let ident = self.parse_ident()?;
@ -420,7 +421,14 @@ impl<'a> Parser<'a> {
} else {
unreachable!();
};
let span = lo.to(self.prev_span);
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
if let AssocTyConstraintKind::Bound { .. } = kind {
self.sess.gated_spans.associated_type_bounds.borrow_mut().push(span);
}
constraints.push(AssocTyConstraint {
id: ast::DUMMY_NODE_ID,
ident,

View file

@ -30,6 +30,28 @@ crate struct GatedSpans {
crate or_patterns: Lock<Vec<Span>>,
/// Spans collected for gating `const_extern_fn`, e.g. `const extern fn foo`.
crate const_extern_fn: Lock<Vec<Span>>,
/// Spans collected for gating `trait_alias`, e.g. `trait Foo = Ord + Eq;`.
pub trait_alias: Lock<Vec<Span>>,
/// Spans collected for gating `associated_type_bounds`, e.g. `Iterator<Item: Ord>`.
pub associated_type_bounds: Lock<Vec<Span>>,
/// Spans collected for gating `crate_visibility_modifier`, e.g. `crate fn`.
pub crate_visibility_modifier: Lock<Vec<Span>>,
/// Spans collected for gating `const_generics`, e.g. `const N: usize`.
pub const_generics: Lock<Vec<Span>>,
/// Spans collected for gating `decl_macro`, e.g. `macro m() {}`.
pub decl_macro: Lock<Vec<Span>>,
/// Spans collected for gating `box_patterns`, e.g. `box 0`.
pub box_patterns: Lock<Vec<Span>>,
/// Spans collected for gating `exclusive_range_pattern`, e.g. `0..2`.
pub exclusive_range_pattern: Lock<Vec<Span>>,
/// Spans collected for gating `try_blocks`, e.g. `try { a? + b? }`.
pub try_blocks: Lock<Vec<Span>>,
/// Spans collected for gating `label_break_value`, e.g. `'label: { ... }`.
pub label_break_value: Lock<Vec<Span>>,
/// Spans collected for gating `box_syntax`, e.g. `box $expr`.
pub box_syntax: Lock<Vec<Span>>,
/// Spans collected for gating `type_ascription`, e.g. `42: usize`.
pub type_ascription: Lock<Vec<Span>>,
}
/// Info about a parsing session.

View file

@ -1,8 +1,8 @@
error[E0658]: const generics are unstable
--> $DIR/const-param-in-trait-ungated.rs:1:19
--> $DIR/const-param-in-trait-ungated.rs:1:13
|
LL | trait Trait<const T: ()> {}
| ^
| ^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
= help: add `#![feature(const_generics)]` to the crate attributes to enable

View file

@ -1,8 +1,8 @@
error[E0658]: const generics are unstable
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:19
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:13
|
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
| ^
| ^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
= help: add `#![feature(const_generics)]` to the crate attributes to enable

View file

@ -1,8 +1,8 @@
error[E0658]: const generics are unstable
--> $DIR/issue-60263.rs:1:16
--> $DIR/issue-60263.rs:1:10
|
LL | struct B<const I: u8>;
| ^
| ^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
= help: add `#![feature(const_generics)]` to the crate attributes to enable

View file

@ -70,3 +70,7 @@ fn main() {
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
// let _: &dyn Tr1<As1: Copy> = &S1;
}
macro_rules! accept_path { ($p:path) => {} }
accept_path!(Iterator<Item: Ord>);
//~^ ERROR associated type bounds are unstable

View file

@ -115,6 +115,15 @@ LL | let _: impl Tr1<As1: Copy> = S1;
= note: for more information, see https://github.com/rust-lang/rust/issues/52662
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
error[E0658]: associated type bounds are unstable
--> $DIR/feature-gate-associated_type_bounds.rs:75:23
|
LL | accept_path!(Iterator<Item: Ord>);
| ^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/52662
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> $DIR/feature-gate-associated_type_bounds.rs:54:14
|
@ -139,7 +148,7 @@ LL | let _: impl Tr1<As1: Copy> = S1;
|
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
error: aborting due to 16 previous errors
error: aborting due to 17 previous errors
Some errors have detailed explanations: E0562, E0658.
For more information about an error, try `rustc --explain E0562`.

View file

@ -2,3 +2,6 @@ fn main() {
let box x = Box::new('c'); //~ ERROR box pattern syntax is experimental
println!("x: {}", x);
}
macro_rules! accept_pat { ($p:pat) => {} }
accept_pat!(box 0); //~ ERROR box pattern syntax is experimental

View file

@ -7,6 +7,15 @@ LL | let box x = Box::new('c');
= note: for more information, see https://github.com/rust-lang/rust/issues/29641
= help: add `#![feature(box_patterns)]` to the crate attributes to enable
error: aborting due to previous error
error[E0658]: box pattern syntax is experimental
--> $DIR/feature-gate-box_patterns.rs:7:13
|
LL | accept_pat!(box 0);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29641
= help: add `#![feature(box_patterns)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,6 +1,9 @@
// Test that the use of the box syntax is gated by `box_syntax` feature gate.
fn main() {
#[cfg(FALSE)]
fn foo() {
let x = box 3;
//~^ ERROR box expression syntax is experimental; you can call `Box::new` instead
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0658]: box expression syntax is experimental; you can call `Box::new` instead
--> $DIR/feature-gate-box_syntax.rs:4:13
--> $DIR/feature-gate-box_syntax.rs:5:13
|
LL | let x = box 3;
| ^^^^^

View file

@ -1,17 +1,17 @@
error[E0658]: const generics are unstable
--> $DIR/feature-gate-const_generics-ptr.rs:1:22
--> $DIR/feature-gate-const_generics-ptr.rs:1:16
|
LL | struct ConstFn<const F: fn()>;
| ^
| ^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: const generics are unstable
--> $DIR/feature-gate-const_generics-ptr.rs:5:23
--> $DIR/feature-gate-const_generics-ptr.rs:5:17
|
LL | struct ConstPtr<const P: *const u32>;
| ^
| ^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
= help: add `#![feature(const_generics)]` to the crate attributes to enable

View file

@ -2,4 +2,9 @@ fn foo<const X: ()>() {} //~ ERROR const generics are unstable
struct Foo<const X: usize>([(); X]); //~ ERROR const generics are unstable
macro_rules! accept_item { ($i:item) => {} }
accept_item! {
impl<const X: ()> A {} //~ ERROR const generics are unstable
}
fn main() {}

View file

@ -1,21 +1,30 @@
error[E0658]: const generics are unstable
--> $DIR/feature-gate-const_generics.rs:1:14
--> $DIR/feature-gate-const_generics.rs:1:8
|
LL | fn foo<const X: ()>() {}
| ^
| ^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: const generics are unstable
--> $DIR/feature-gate-const_generics.rs:3:18
--> $DIR/feature-gate-const_generics.rs:3:12
|
LL | struct Foo<const X: usize>([(); X]);
| ^
| ^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error: aborting due to 2 previous errors
error[E0658]: const generics are unstable
--> $DIR/feature-gate-const_generics.rs:7:10
|
LL | impl<const X: ()> A {}
| ^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -5,4 +5,7 @@ crate struct Bender { //~ ERROR `crate` visibility modifier is experimental
water: bool,
}
macro_rules! accept_vis { ($v:vis) => {} }
accept_vis!(crate); //~ ERROR `crate` visibility modifier is experimental
fn main() {}

View file

@ -7,6 +7,15 @@ LL | crate struct Bender {
= note: for more information, see https://github.com/rust-lang/rust/issues/53120
= help: add `#![feature(crate_visibility_modifier)]` to the crate attributes to enable
error: aborting due to previous error
error[E0658]: `crate` visibility modifier is experimental
--> $DIR/feature-gate-crate_visibility_modifier.rs:9:13
|
LL | accept_vis!(crate);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/53120
= help: add `#![feature(crate_visibility_modifier)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -2,4 +2,8 @@
macro m() {} //~ ERROR `macro` is experimental
macro_rules! accept_item { ($i:item) => {} }
accept_item! {
macro m() {} //~ ERROR `macro` is experimental
}
fn main() {}

View file

@ -7,6 +7,15 @@ LL | macro m() {}
= note: for more information, see https://github.com/rust-lang/rust/issues/39412
= help: add `#![feature(decl_macro)]` to the crate attributes to enable
error: aborting due to previous error
error[E0658]: `macro` is experimental
--> $DIR/feature-gate-decl_macro.rs:7:5
|
LL | macro m() {}
| ^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/39412
= help: add `#![feature(decl_macro)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,6 +1,10 @@
pub fn main() {
#[cfg(FALSE)]
fn foo() {
match 22 {
0 .. 3 => {} //~ ERROR exclusive range pattern syntax is experimental
PATH .. 3 => {} //~ ERROR exclusive range pattern syntax is experimental
_ => {}
}
}
fn main() {}

View file

@ -1,12 +1,21 @@
error[E0658]: exclusive range pattern syntax is experimental
--> $DIR/feature-gate-exclusive-range-pattern.rs:3:9
--> $DIR/feature-gate-exclusive-range-pattern.rs:4:11
|
LL | 0 .. 3 => {}
| ^^^^^^
| ^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/37854
= help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
error: aborting due to previous error
error[E0658]: exclusive range pattern syntax is experimental
--> $DIR/feature-gate-exclusive-range-pattern.rs:5:14
|
LL | PATH .. 3 => {}
| ^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/37854
= help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,5 +1,8 @@
pub fn main() {
#[cfg(FALSE)]
pub fn foo() {
'a: { //~ ERROR labels on blocks are unstable
break 'a;
}
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0658]: labels on blocks are unstable
--> $DIR/feature-gate-label_break_value.rs:2:5
--> $DIR/feature-gate-label_break_value.rs:3:5
|
LL | 'a: {
| ^^

View file

@ -1,4 +1,13 @@
trait Foo = Default;
//~^ ERROR trait aliases are experimental
macro_rules! accept_item {
($i:item) => {}
}
accept_item! {
trait Foo = Ord + Eq;
//~^ ERROR trait aliases are experimental
}
fn main() {}

View file

@ -7,6 +7,15 @@ LL | trait Foo = Default;
= note: for more information, see https://github.com/rust-lang/rust/issues/41517
= help: add `#![feature(trait_alias)]` to the crate attributes to enable
error: aborting due to previous error
error[E0658]: trait aliases are experimental
--> $DIR/feature-gate-trait-alias.rs:9:5
|
LL | trait Foo = Ord + Eq;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/41517
= help: add `#![feature(trait_alias)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,9 +1,12 @@
// compile-flags: --edition 2018
pub fn main() {
let try_result: Option<_> = try { //~ ERROR `try` expression is experimental
#[cfg(FALSE)]
fn foo() {
let try_result: Option<_> = try { //~ ERROR `try` blocks are unstable
let x = 5;
x
};
assert_eq!(try_result, Some(5));
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0658]: `try` expression is experimental
--> $DIR/feature-gate-try_blocks.rs:4:33
error[E0658]: `try` blocks are unstable
--> $DIR/feature-gate-try_blocks.rs:5:33
|
LL | let try_result: Option<_> = try {
| _________________________________^

View file

@ -1,5 +1,8 @@
// Type ascription is unstable
fn main() {
#[cfg(FALSE)]
fn foo() {
let a = 10: u8; //~ ERROR type ascription is experimental
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0658]: type ascription is experimental
--> $DIR/feature-gate-type_ascription.rs:4:13
--> $DIR/feature-gate-type_ascription.rs:5:13
|
LL | let a = 10: u8;
| ^^^^^^

View file

@ -4,6 +4,7 @@
// check-pass
#![feature(or_patterns)]
#![feature(box_patterns)]
fn main() {}

View file

@ -4,7 +4,6 @@ fn main() {
match 0 {
(.. PAT) => {}
//~^ ERROR `..X` range patterns are not supported
//~| ERROR exclusive range pattern syntax is experimental
}
}

View file

@ -4,17 +4,8 @@ error: `..X` range patterns are not supported
LL | (.. PAT) => {}
| ^^^^^^ help: try using the minimum value for the type: `MIN..PAT`
error[E0658]: exclusive range pattern syntax is experimental
--> $DIR/pat-tuple-4.rs:5:10
|
LL | (.. PAT) => {}
| ^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/37854
= help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
error[E0308]: mismatched types
--> $DIR/pat-tuple-4.rs:11:30
--> $DIR/pat-tuple-4.rs:10:30
|
LL | const RECOVERY_WITNESS: () = 0;
| ^ expected (), found integer
@ -22,7 +13,6 @@ LL | const RECOVERY_WITNESS: () = 0;
= note: expected type `()`
found type `{integer}`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0308, E0658.
For more information about an error, try `rustc --explain E0308`.
For more information about this error, try `rustc --explain E0308`.

View file

@ -5,10 +5,10 @@ LL | (PAT ..) => {}
| ^^^^^^ help: try using the maximum value for the type: `PAT..MAX`
error[E0658]: exclusive range pattern syntax is experimental
--> $DIR/pat-tuple-5.rs:5:10
--> $DIR/pat-tuple-5.rs:5:14
|
LL | (PAT ..) => {}
| ^^^^^^
| ^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/37854
= help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable

View file

@ -3,6 +3,8 @@
// check-pass
#![feature(box_patterns)]
fn main() {}
macro_rules! accept_pat {

View file

@ -4,4 +4,7 @@ trait Foo {}
auto trait A = Foo; //~ ERROR trait aliases cannot be `auto`
unsafe trait B = Foo; //~ ERROR trait aliases cannot be `unsafe`
trait C: Ord = Eq; //~ ERROR bounds are not allowed on trait aliases
trait D: = Eq; //~ ERROR bounds are not allowed on trait aliases
fn main() {}

View file

@ -1,14 +1,26 @@
error: trait aliases cannot be `auto`
--> $DIR/trait-alias-syntax-fail.rs:4:19
--> $DIR/trait-alias-syntax-fail.rs:4:1
|
LL | auto trait A = Foo;
| ^ trait aliases cannot be `auto`
| ^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto`
error: trait aliases cannot be `unsafe`
--> $DIR/trait-alias-syntax-fail.rs:5:21
--> $DIR/trait-alias-syntax-fail.rs:5:1
|
LL | unsafe trait B = Foo;
| ^ trait aliases cannot be `unsafe`
| ^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe`
error: aborting due to 2 previous errors
error: bounds are not allowed on trait aliases
--> $DIR/trait-alias-syntax-fail.rs:7:8
|
LL | trait C: Ord = Eq;
| ^^^^^
error: bounds are not allowed on trait aliases
--> $DIR/trait-alias-syntax-fail.rs:8:8
|
LL | trait D: = Eq;
| ^
error: aborting due to 4 previous errors