diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2017-04-07 07:19:44 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2017-04-07 14:55:45 -0700 |
| commit | 8c31412c2f84c7d76602b2598c5c1352da61d022 (patch) | |
| tree | cbc08b79f16f1533e27d84dee16e90f9f319a679 /src/libsyntax | |
| parent | b83352e44c36e81db7f00eb60e78ff3828c51c9e (diff) | |
| parent | 4c59c92bc4d4d6e5b2b66c4cc08dd1a058283a0d (diff) | |
| download | rust-8c31412c2f84c7d76602b2598c5c1352da61d022.tar.gz rust-8c31412c2f84c7d76602b2598c5c1352da61d022.zip | |
Merge branch 'master' into ty-placeholder
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/derive.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 116 | ||||
| -rw-r--r-- | src/libsyntax/ptr.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/util/rc_slice.rs | 13 |
5 files changed, 126 insertions, 38 deletions
diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index c79040424f6..e7c5d8278d9 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -26,7 +26,8 @@ pub fn collect_derives(cx: &mut ExtCtxt, attrs: &mut Vec<ast::Attribute>) -> Vec return true; } - match attr.parse_list(cx.parse_sess, |parser| parser.parse_path(PathStyle::Mod)) { + match attr.parse_list(cx.parse_sess, + |parser| parser.parse_path_allowing_meta(PathStyle::Mod)) { Ok(ref traits) if traits.is_empty() => { cx.span_warn(attr.span, "empty trait list in `derive`"); false diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 12d25ca4274..550f1160bed 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -292,9 +292,6 @@ declare_features! ( // Allows attributes on lifetime/type formal parameters in generics (RFC 1327) (active, generic_param_attrs, "1.11.0", Some(34761)), - // The #![windows_subsystem] attribute - (active, windows_subsystem, "1.14.0", Some(37499)), - // Allows #[link(..., cfg(..))] (active, link_cfg, "1.14.0", Some(37406)), @@ -337,11 +334,15 @@ declare_features! ( // `extern "x86-interrupt" fn()` (active, abi_x86_interrupt, "1.17.0", Some(40180)), + // Allows the `catch {...}` expression (active, catch_expr, "1.17.0", Some(31436)), // See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work. (active, rvalue_static_promotion, "1.15.1", Some(38865)), + + // Used to preserve symbols (see llvm.used) + (active, used, "1.18.0", Some(40289)), ); declare_features! ( @@ -408,7 +409,8 @@ declare_features! ( (accepted, static_recursion, "1.17.0", Some(29719)), // pub(restricted) visibilities (RFC 1422) (accepted, pub_restricted, "1.17.0", Some(32409)), - + // The #![windows_subsystem] attribute + (accepted, windows_subsystem, "1.18.0", Some(37499)), ); // If you change this, please modify src/doc/unstable-book as well. You must // move that documentation into the relevant place in the other docs, and @@ -748,6 +750,10 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "unwind_attributes", "#[unwind] is experimental", cfg_fn!(unwind_attributes))), + ("used", Whitelisted, Gated( + Stability::Unstable, "used", + "the `#[used]` attribute is an experimental feature", + cfg_fn!(used))), // used in resolve ("prelude_import", Whitelisted, Gated(Stability::Unstable, @@ -768,11 +774,7 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "unboxed_closures are still evolving", cfg_fn!(unboxed_closures))), - ("windows_subsystem", Whitelisted, Gated(Stability::Unstable, - "windows_subsystem", - "the windows subsystem attribute \ - is currently unstable", - cfg_fn!(windows_subsystem))), + ("windows_subsystem", Whitelisted, Ungated), ("proc_macro_attribute", Normal, Gated(Stability::Unstable, "proc_macro", diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 23fc1351426..43d21015a4f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -570,20 +570,33 @@ impl<'a> Parser<'a> { expected.dedup(); let expect = tokens_to_string(&expected[..]); let actual = self.this_token_to_string(); - Err(self.fatal( - &(if expected.len() > 1 { - (format!("expected one of {}, found `{}`", - expect, - actual)) - } else if expected.is_empty() { - (format!("unexpected token: `{}`", - actual)) + let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 { + let short_expect = if expected.len() > 6 { + format!("{} possible tokens", expected.len()) } else { - (format!("expected {}, found `{}`", - expect, - actual)) - })[..] - )) + expect.clone() + }; + (format!("expected one of {}, found `{}`", expect, actual), + (self.prev_span.next_point(), format!("expected one of {} here", short_expect))) + } else if expected.is_empty() { + (format!("unexpected token: `{}`", actual), + (self.prev_span, "unexpected token after this".to_string())) + } else { + (format!("expected {}, found `{}`", expect, actual), + (self.prev_span.next_point(), format!("expected {} here", expect))) + }; + let mut err = self.fatal(&msg_exp); + let sp = if self.token == token::Token::Eof { + // This is EOF, don't want to point at the following char, but rather the last token + self.prev_span + } else { + label_sp + }; + err.span_label(sp, &label_exp); + if !sp.source_equal(&self.span) { + err.span_label(self.span, &"unexpected token"); + } + Err(err) } } @@ -1773,6 +1786,26 @@ impl<'a> Parser<'a> { }) } + /// Like `parse_path`, but also supports parsing `Word` meta items into paths for back-compat. + /// This is used when parsing derive macro paths in `#[derive]` attributes. + pub fn parse_path_allowing_meta(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> { + let meta_ident = match self.token { + token::Interpolated(ref nt) => match **nt { + token::NtMeta(ref meta) => match meta.node { + ast::MetaItemKind::Word => Some(ast::Ident::with_empty_ctxt(meta.name)), + _ => None, + }, + _ => None, + }, + _ => None, + }; + if let Some(ident) = meta_ident { + self.bump(); + return Ok(ast::Path::from_ident(self.prev_span, ident)); + } + self.parse_path(mode) + } + /// Examples: /// - `a::b<T,U>::c<V,W>` /// - `a::b<T,U>::c(V) -> W` @@ -4667,25 +4700,30 @@ impl<'a> Parser<'a> { }) } - fn complain_if_pub_macro(&mut self, visa: &Visibility, span: Span) { - match *visa { - Visibility::Inherited => (), + fn complain_if_pub_macro(&mut self, vis: &Visibility, sp: Span) { + if let Err(mut err) = self.complain_if_pub_macro_diag(vis, sp) { + err.emit(); + } + } + + fn complain_if_pub_macro_diag(&mut self, vis: &Visibility, sp: Span) -> PResult<'a, ()> { + match *vis { + Visibility::Inherited => Ok(()), _ => { let is_macro_rules: bool = match self.token { token::Ident(sid) => sid.name == Symbol::intern("macro_rules"), _ => false, }; if is_macro_rules { - self.diagnostic().struct_span_err(span, "can't qualify macro_rules \ - invocation with `pub`") - .help("did you mean #[macro_export]?") - .emit(); + let mut err = self.diagnostic() + .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`"); + err.help("did you mean #[macro_export]?"); + Err(err) } else { - self.diagnostic().struct_span_err(span, "can't qualify macro \ - invocation with `pub`") - .help("try adjusting the macro to put `pub` \ - inside the invocation") - .emit(); + let mut err = self.diagnostic() + .struct_span_err(sp, "can't qualify macro invocation with `pub`"); + err.help("try adjusting the macro to put `pub` inside the invocation"); + Err(err) } } } @@ -4696,14 +4734,36 @@ impl<'a> Parser<'a> { -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::ImplItemKind)> { // code copied from parse_macro_use_or_failure... abstraction! if self.token.is_path_start() { - // method macro. + // Method macro. let prev_span = self.prev_span; - self.complain_if_pub_macro(&vis, prev_span); + // Before complaining about trying to set a macro as `pub`, + // check if `!` comes after the path. + let err = self.complain_if_pub_macro_diag(&vis, prev_span); let lo = self.span; let pth = self.parse_path(PathStyle::Mod)?; - self.expect(&token::Not)?; + let bang_err = self.expect(&token::Not); + if let Err(mut err) = err { + if let Err(mut bang_err) = bang_err { + // Given this code `pub path(`, it seems like this is not setting the + // visibility of a macro invocation, but rather a mistyped method declaration. + // Create a diagnostic pointing out that `fn` is missing. + // + // x | pub path(&self) { + // | ^ missing `fn` for method declaration + + err.cancel(); + bang_err.cancel(); + // pub path( + // ^^ `sp` below will point to this + let sp = prev_span.between(self.prev_span); + err = self.diagnostic() + .struct_span_err(sp, "missing `fn` for method declaration"); + err.span_label(sp, &"missing `fn`"); + } + return Err(err); + } // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 58750158931..15111bbba0a 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -43,6 +43,8 @@ use std::{mem, ptr, slice, vec}; use serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, + HashStable}; /// An owned smart pointer. #[derive(Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct P<T: ?Sized> { @@ -215,3 +217,13 @@ impl<T: Decodable> Decodable for P<[T]> { })) } } + +impl<CTX, T> HashStable<CTX> for P<T> + where T: ?Sized + HashStable<CTX> +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut CTX, + hasher: &mut StableHasher<W>) { + (**self).hash_stable(hcx, hasher); + } +} diff --git a/src/libsyntax/util/rc_slice.rs b/src/libsyntax/util/rc_slice.rs index 195fb23f9d8..2d9fd7aa875 100644 --- a/src/libsyntax/util/rc_slice.rs +++ b/src/libsyntax/util/rc_slice.rs @@ -12,6 +12,9 @@ use std::fmt; use std::ops::Deref; use std::rc::Rc; +use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, + HashStable}; + #[derive(Clone)] pub struct RcSlice<T> { data: Rc<Box<[T]>>, @@ -41,3 +44,13 @@ impl<T: fmt::Debug> fmt::Debug for RcSlice<T> { fmt::Debug::fmt(self.deref(), f) } } + +impl<CTX, T> HashStable<CTX> for RcSlice<T> + where T: HashStable<CTX> +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut CTX, + hasher: &mut StableHasher<W>) { + (**self).hash_stable(hcx, hasher); + } +} |
