Skip to content

Commit

Permalink
Rollup merge of rust-lang#65742 - Centril:gate-pre-expansion-subset, …
Browse files Browse the repository at this point in the history
…r=davidtwco

Pre-expansion gate most of the things

This is a subset of rust-lang#64672. A crater run has already been done and this PR implements conclusions according to rust-lang#64672 (comment).

r? @davidtwco
cc @petrochenkov
  • Loading branch information
Centril authored Oct 25, 2019
2 parents fb602c7 + 15a6c09 commit d6a18b6
Show file tree
Hide file tree
Showing 42 changed files with 295 additions and 182 deletions.
3 changes: 2 additions & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down Expand Up @@ -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)]
Expand Down
150 changes: 39 additions & 111 deletions src/libsyntax/feature_gate/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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";

Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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) => {
Expand All @@ -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
Expand All @@ -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) => {
Expand All @@ -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);
}
_ => {}
}
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}

Expand Down
13 changes: 11 additions & 2 deletions src/libsyntax/parse/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 didn’t have to handle `x..`/`x..=`, it would be pretty easy to
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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))
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax/parse/parser/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit d6a18b6

Please sign in to comment.