From 72d629caa50fa482dd4165cb43b9fb02ac24c8d8 Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 23 Aug 2016 18:23:31 +1200 Subject: Improve error message when failing to parse a block We want to catch this error: ``` if (foo) bar; ``` as it's valid syntax in other languages, and say how to fix it. Unfortunately it didn't care if the suggestion made sense and just highlighted the unexpected token. Now it attempts to parse a statement, and if it succeeds, it shows the help message. Fixes #35907 --- src/libsyntax/parse/parser.rs | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9443df6321b..1646246069e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4087,9 +4087,30 @@ impl<'a> Parser<'a> { if !self.eat(&token::OpenDelim(token::Brace)) { let sp = self.span; let tok = self.this_token_to_string(); - return Err(self.span_fatal_help(sp, - &format!("expected `{{`, found `{}`", tok), - "place this code inside a block")); + let mut e = self.span_fatal(sp, &format!("expected `{{`, found `{}`", tok)); + + // Check to see if the user has written something like + // + // if (cond) + // bar; + // + // Which is valid in other languages, but not Rust. + match self.parse_stmt_without_recovery(false) { + Ok(Some(stmt)) => { + let mut stmt_span = stmt.span; + // expand the span to include the semicolon, if it exists + if self.eat(&token::Semi) { + stmt_span.hi = self.last_span.hi; + } + e.span_help(stmt_span, "try placing this code inside a block"); + } + Err(mut e) => { + self.recover_stmt_(SemiColonMode::Break); + e.cancel(); + } + _ => () + } + return Err(e); } self.parse_block_tail(lo, BlockCheckMode::Default) -- cgit 1.4.1-3-g733a5 From ee055a1ff37bb47f32ed460ca7d249d91f8cbe7d Mon Sep 17 00:00:00 2001 From: Daniele Baracchi Date: Wed, 24 Aug 2016 13:07:43 +0200 Subject: Stabilize type-macros Closes #27245 --- src/libsyntax/ext/expand.rs | 13 +------------ src/libsyntax/feature_gate.rs | 5 ++--- src/test/compile-fail/issue-30007.rs | 2 -- src/test/compile-fail/issue-32950.rs | 2 +- src/test/compile-fail/macro-context.rs | 2 -- src/test/compile-fail/macro-error.rs | 2 -- .../privacy/restricted/tuple-struct-fields/test.rs | 2 +- .../restricted/tuple-struct-fields/test2.rs | 2 +- .../restricted/tuple-struct-fields/test3.rs | 2 +- src/test/compile-fail/syntax-extension-minor.rs | 2 +- src/test/compile-fail/type-macros-fail.rs | 22 ---------------------- src/test/run-pass/simd-intrinsic-generic-cast.rs | 3 +-- src/test/run-pass/type-macros-hlist.rs | 2 -- src/test/run-pass/type-macros-simple.rs | 2 -- 14 files changed, 9 insertions(+), 54 deletions(-) delete mode 100644 src/test/compile-fail/type-macros-fail.rs (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 031d9a2d3f4..26599208ec0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -491,18 +491,7 @@ fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander) pub fn expand_type(t: P, fld: &mut MacroExpander) -> P { let t = match t.node.clone() { ast::TyKind::Mac(mac) => { - if fld.cx.ecfg.features.unwrap().type_macros { - expand_mac_invoc(mac, None, Vec::new(), t.span, fld) - } else { - feature_gate::emit_feature_err( - &fld.cx.parse_sess.span_diagnostic, - "type_macros", - t.span, - feature_gate::GateIssue::Language, - "type macros are experimental"); - - DummyResult::raw_ty(t.span) - } + expand_mac_invoc(mac, None, Vec::new(), t.span, fld) } _ => t }; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index d746f8e2114..dc68e064634 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -213,9 +213,6 @@ declare_features! ( // Allows associated type defaults (active, associated_type_defaults, "1.2.0", Some(29661)), - // Allows macros to appear in the type position. - (active, type_macros, "1.3.0", Some(27245)), - // allow `repr(simd)`, and importing the various simd intrinsics (active, repr_simd, "1.4.0", Some(27731)), @@ -321,6 +318,8 @@ declare_features! ( // mean anything (accepted, test_accepted_feature, "1.0.0", None), (accepted, tuple_indexing, "1.0.0", None), + // Allows macros to appear in the type position. + (accepted, type_macros, "1.13.0", Some(27245)), (accepted, while_let, "1.0.0", None), // Allows `#[deprecated]` attribute (accepted, deprecated, "1.9.0", Some(29935)) diff --git a/src/test/compile-fail/issue-30007.rs b/src/test/compile-fail/issue-30007.rs index 95a52cb232a..fa0b75da999 100644 --- a/src/test/compile-fail/issue-30007.rs +++ b/src/test/compile-fail/issue-30007.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(type_macros)] - macro_rules! t { () => ( String ; ); //~ ERROR macro expansion ignores token `;` } diff --git a/src/test/compile-fail/issue-32950.rs b/src/test/compile-fail/issue-32950.rs index e8ca1c1fa98..20e5b1d72d3 100644 --- a/src/test/compile-fail/issue-32950.rs +++ b/src/test/compile-fail/issue-32950.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(type_macros, concat_idents)] +#![feature(concat_idents)] #[derive(Debug)] //~ NOTE in this expansion struct Baz( diff --git a/src/test/compile-fail/macro-context.rs b/src/test/compile-fail/macro-context.rs index 5d07f0747ff..4aa0a3023bb 100644 --- a/src/test/compile-fail/macro-context.rs +++ b/src/test/compile-fail/macro-context.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(type_macros)] - // (typeof used because it's surprisingly hard to find an unparsed token after a stmt) macro_rules! m { () => ( i ; typeof ); //~ ERROR expected expression, found reserved keyword `typeof` diff --git a/src/test/compile-fail/macro-error.rs b/src/test/compile-fail/macro-error.rs index a69188da58d..4a6dbf014a1 100644 --- a/src/test/compile-fail/macro-error.rs +++ b/src/test/compile-fail/macro-error.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(type_macros)] - macro_rules! foo { ($a:expr) => $a; //~ ERROR macro rhs must be delimited } diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs b/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs index 9cc53386d46..f3dcf405a68 100644 --- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs +++ b/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(pub_restricted, type_macros)] +#![feature(pub_restricted)] mod foo { type T = (); diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs b/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs index 01466c6a85a..3bf8ca30a6c 100644 --- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs +++ b/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(pub_restricted, type_macros)] +#![feature(pub_restricted)] macro_rules! define_struct { ($t:ty) => { diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs b/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs index ef187a1daed..febe224fb84 100644 --- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs +++ b/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(pub_restricted, type_macros)] +#![feature(pub_restricted)] macro_rules! define_struct { ($t:ty) => { diff --git a/src/test/compile-fail/syntax-extension-minor.rs b/src/test/compile-fail/syntax-extension-minor.rs index 3e36b126523..f06e3544e57 100644 --- a/src/test/compile-fail/syntax-extension-minor.rs +++ b/src/test/compile-fail/syntax-extension-minor.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(concat_idents, type_macros)] +#![feature(concat_idents)] pub fn main() { struct Foo; diff --git a/src/test/compile-fail/type-macros-fail.rs b/src/test/compile-fail/type-macros-fail.rs deleted file mode 100644 index 4712e2b65e1..00000000000 --- a/src/test/compile-fail/type-macros-fail.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -macro_rules! Id { - ($T:tt) => ($T); -} - -struct Foo { - x: Id!(T) - //~^ ERROR: type macros are experimental (see issue #27245) -} - -fn main() { - let foo = Foo { x: i32 }; -} diff --git a/src/test/run-pass/simd-intrinsic-generic-cast.rs b/src/test/run-pass/simd-intrinsic-generic-cast.rs index a20dd3ef72a..2efd9333999 100644 --- a/src/test/run-pass/simd-intrinsic-generic-cast.rs +++ b/src/test/run-pass/simd-intrinsic-generic-cast.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(repr_simd, platform_intrinsics, concat_idents, - type_macros, test)] +#![feature(repr_simd, platform_intrinsics, concat_idents, test)] #![allow(non_camel_case_types)] extern crate test; diff --git a/src/test/run-pass/type-macros-hlist.rs b/src/test/run-pass/type-macros-hlist.rs index 803b0eae99e..84c0983de80 100644 --- a/src/test/run-pass/type-macros-hlist.rs +++ b/src/test/run-pass/type-macros-hlist.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(type_macros)] - use std::ops::*; #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] diff --git a/src/test/run-pass/type-macros-simple.rs b/src/test/run-pass/type-macros-simple.rs index 22dfd507f7e..7d1045cf3f1 100644 --- a/src/test/run-pass/type-macros-simple.rs +++ b/src/test/run-pass/type-macros-simple.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(type_macros)] - macro_rules! Tuple { { $A:ty,$B:ty } => { ($A, $B) } } -- cgit 1.4.1-3-g733a5