diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2015-01-28 23:03:36 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-01-28 23:31:03 +0530 |
| commit | c709ed2faf4ea28df1395a924453b5298b87fa57 (patch) | |
| tree | 9567cea197e37b96607f471b18dd1c77908c8965 /src/libsyntax | |
| parent | 249c29fe2746d251dc8aab63cd8730df9ff8434c (diff) | |
| parent | a45e117733b866302fa99390553d1c548508dcca (diff) | |
| download | rust-c709ed2faf4ea28df1395a924453b5298b87fa57.tar.gz rust-c709ed2faf4ea28df1395a924453b5298b87fa57.zip | |
Merge remote-tracking branch 'origin/master' into rollup
Conflicts: src/libcollections/slice.rs src/libcore/nonzero.rs src/libcore/ops.rs
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/attr.rs | 156 | ||||
| -rw-r--r-- | src/libsyntax/diagnostic.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 183 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 95 | ||||
| -rw-r--r-- | src/libsyntax/util/small_vector.rs | 3 |
14 files changed, 363 insertions, 139 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 4f6cd8ad356..4dada5bc81e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -347,6 +347,9 @@ impl AngleBracketedParameterData { /// A path like `Foo(A,B) -> C` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)] pub struct ParenthesizedParameterData { + /// Overall span + pub span: Span, + /// `(A,B)` pub inputs: Vec<P<Ty>>, diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 59471488af9..061600d9420 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -21,7 +21,7 @@ use codemap::{Span, Spanned, spanned, dummy_spanned}; use codemap::BytePos; use diagnostic::SpanHandler; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; -use parse::token::InternedString; +use parse::token::{InternedString, intern_and_get_ident}; use parse::token; use ptr::P; @@ -56,6 +56,8 @@ pub trait AttrMetaMethods { fn value_str(&self) -> Option<InternedString>; /// Gets a list of inner meta items from a list MetaItem type. fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]>; + + fn span(&self) -> Span; } impl AttrMetaMethods for Attribute { @@ -73,6 +75,7 @@ impl AttrMetaMethods for Attribute { fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> { self.node.value.meta_item_list() } + fn span(&self) -> Span { self.meta().span } } impl AttrMetaMethods for MetaItem { @@ -102,6 +105,7 @@ impl AttrMetaMethods for MetaItem { _ => None } } + fn span(&self) -> Span { self.span } } // Annoying, but required to get test_cfg to work @@ -111,6 +115,7 @@ impl AttrMetaMethods for P<MetaItem> { fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> { (**self).meta_item_list() } + fn span(&self) -> Span { (**self).span() } } @@ -340,22 +345,23 @@ pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], cfg: &ast::Me } } -/// Represents the #[deprecated="foo"] and friends attributes. +/// Represents the #[deprecated] and friends attributes. #[derive(RustcEncodable,RustcDecodable,Clone,Show)] pub struct Stability { pub level: StabilityLevel, - pub text: Option<InternedString> + pub feature: InternedString, + pub since: Option<InternedString>, + pub deprecated_since: Option<InternedString>, + // The reason for the current stability level. If deprecated, the + // reason for deprecation. + pub reason: Option<InternedString>, } /// The available stability levels. #[derive(RustcEncodable,RustcDecodable,PartialEq,PartialOrd,Clone,Show,Copy)] pub enum StabilityLevel { - Deprecated, - Experimental, Unstable, Stable, - Frozen, - Locked } impl fmt::Display for StabilityLevel { @@ -364,36 +370,128 @@ impl fmt::Display for StabilityLevel { } } -pub fn find_stability_generic<'a, +fn find_stability_generic<'a, AM: AttrMetaMethods, I: Iterator<Item=&'a AM>> - (mut attrs: I) - -> Option<(Stability, &'a AM)> { - for attr in attrs { - let level = match attr.name().get() { - "deprecated" => Deprecated, - "experimental" => Experimental, - "unstable" => Unstable, - "stable" => Stable, - "frozen" => Frozen, - "locked" => Locked, - _ => continue // not a stability level + (diagnostic: &SpanHandler, mut attrs: I, item_sp: Span) + -> (Option<Stability>, Vec<&'a AM>) { + + let mut stab: Option<Stability> = None; + let mut deprecated: Option<(InternedString, Option<InternedString>)> = None; + let mut used_attrs: Vec<&'a AM> = vec![]; + + 'outer: for attr in attrs { + let tag = attr.name(); + let tag = tag.get(); + if tag != "deprecated" && tag != "unstable" && tag != "stable" { + continue // not a stability level + } + + used_attrs.push(attr); + + let (feature, since, reason) = match attr.meta_item_list() { + Some(metas) => { + let mut feature = None; + let mut since = None; + let mut reason = None; + for meta in metas.iter() { + if meta.name().get() == "feature" { + match meta.value_str() { + Some(v) => feature = Some(v), + None => { + diagnostic.span_err(meta.span, "incorrect meta item"); + continue 'outer; + } + } + } + if meta.name().get() == "since" { + match meta.value_str() { + Some(v) => since = Some(v), + None => { + diagnostic.span_err(meta.span, "incorrect meta item"); + continue 'outer; + } + } + } + if meta.name().get() == "reason" { + match meta.value_str() { + Some(v) => reason = Some(v), + None => { + diagnostic.span_err(meta.span, "incorrect meta item"); + continue 'outer; + } + } + } + } + (feature, since, reason) + } + None => { + diagnostic.span_err(attr.span(), "incorrect stability attribute type"); + continue + } }; - return Some((Stability { - level: level, - text: attr.value_str() - }, attr)); + // Deprecated tags don't require feature names + if feature == None && tag != "deprecated" { + diagnostic.span_err(attr.span(), "missing 'feature'"); + } + + // Unstable tags don't require a version + if since == None && tag != "unstable" { + diagnostic.span_err(attr.span(), "missing 'since'"); + } + + if tag == "unstable" || tag == "stable" { + if stab.is_some() { + diagnostic.span_err(item_sp, "multiple stability levels"); + } + + let level = match tag { + "unstable" => Unstable, + "stable" => Stable, + _ => unreachable!() + }; + + stab = Some(Stability { + level: level, + feature: feature.unwrap_or(intern_and_get_ident("bogus")), + since: since, + deprecated_since: None, + reason: reason + }); + } else { // "deprecated" + if deprecated.is_some() { + diagnostic.span_err(item_sp, "multiple deprecated attributes"); + } + + deprecated = Some((since.unwrap_or(intern_and_get_ident("bogus")), reason)); + } } - None + + // Merge the deprecation info into the stability info + if deprecated.is_some() { + match stab { + Some(ref mut s) => { + let (since, reason) = deprecated.unwrap(); + s.deprecated_since = Some(since); + s.reason = reason; + } + None => { + diagnostic.span_err(item_sp, "deprecated attribute must be paired with \ + either stable or unstable attribute"); + } + } + } + + (stab, used_attrs) } /// Find the first stability attribute. `None` if none exists. -pub fn find_stability(attrs: &[Attribute]) -> Option<Stability> { - find_stability_generic(attrs.iter()).map(|(s, attr)| { - mark_used(attr); - s - }) +pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute], + item_sp: Span) -> Option<Stability> { + let (s, used) = find_stability_generic(diagnostic, attrs.iter(), item_sp); + for used in used.into_iter() { mark_used(used) } + return s; } pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) { diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 5b79cb7b5dd..f3e66897316 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -143,6 +143,7 @@ impl SpanHandler { pub struct Handler { err_count: Cell<usize>, emit: RefCell<Box<Emitter + Send>>, + pub can_emit_warnings: bool } impl Handler { @@ -195,6 +196,7 @@ impl Handler { cmsp: Option<(&codemap::CodeMap, Span)>, msg: &str, lvl: Level) { + if lvl == Warning && !self.can_emit_warnings { return } self.emit.borrow_mut().emit(cmsp, msg, None, lvl); } pub fn emit_with_code(&self, @@ -202,10 +204,12 @@ impl Handler { msg: &str, code: &str, lvl: Level) { + if lvl == Warning && !self.can_emit_warnings { return } self.emit.borrow_mut().emit(cmsp, msg, Some(code), lvl); } pub fn custom_emit(&self, cm: &codemap::CodeMap, sp: RenderSpan, msg: &str, lvl: Level) { + if lvl == Warning && !self.can_emit_warnings { return } self.emit.borrow_mut().custom_emit(cm, sp, msg, lvl); } } @@ -218,14 +222,16 @@ pub fn mk_span_handler(handler: Handler, cm: codemap::CodeMap) -> SpanHandler { } pub fn default_handler(color_config: ColorConfig, - registry: Option<diagnostics::registry::Registry>) -> Handler { - mk_handler(box EmitterWriter::stderr(color_config, registry)) + registry: Option<diagnostics::registry::Registry>, + can_emit_warnings: bool) -> Handler { + mk_handler(can_emit_warnings, box EmitterWriter::stderr(color_config, registry)) } -pub fn mk_handler(e: Box<Emitter + Send>) -> Handler { +pub fn mk_handler(can_emit_warnings: bool, e: Box<Emitter + Send>) -> Handler { Handler { err_count: Cell::new(0), emit: RefCell::new(e), + can_emit_warnings: can_emit_warnings } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index ef8010927dc..dd89153d497 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -570,7 +570,9 @@ impl<'a> ExtCtxt<'a> { } } - #[deprecated = "Replaced with `expander().fold_expr()`"] + #[unstable(feature = "rustc_private")] + #[deprecated(since = "1.0.0", + reason = "Replaced with `expander().fold_expr()`")] pub fn expand_expr(&mut self, e: P<ast::Expr>) -> P<ast::Expr> { self.expander().fold_expr(e) } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index d115f2ed620..9d5be3fff61 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -83,7 +83,7 @@ use self::TokenTreeOrTokenTreeVec::*; use ast; use ast::{TokenTree, Ident}; use ast::{TtDelimited, TtSequence, TtToken}; -use codemap::{BytePos, mk_sp}; +use codemap::{BytePos, mk_sp, Span}; use codemap; use parse::lexer::*; //resolve bug? use parse::ParseSess; @@ -483,11 +483,11 @@ pub fn parse(sess: &ParseSess, let mut ei = bb_eis.pop().unwrap(); match ei.top_elts.get_tt(ei.idx) { - TtToken(_, MatchNt(_, name, _, _)) => { + TtToken(span, MatchNt(_, name, _, _)) => { let name_string = token::get_ident(name); let match_cur = ei.match_cur; (&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal( - parse_nt(&mut rust_parser, name_string.get())))); + parse_nt(&mut rust_parser, span, name_string.get())))); ei.idx += 1us; ei.match_cur += 1; } @@ -505,7 +505,7 @@ pub fn parse(sess: &ParseSess, } } -pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal { +pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { match name { "tt" => { p.quote_depth += 1us; //but in theory, non-quoted tts might be useful @@ -541,7 +541,11 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal { } "meta" => token::NtMeta(p.parse_meta_item()), _ => { - p.fatal(&format!("unsupported builtin nonterminal parser: {}", name)[]) + p.span_fatal_help(sp, + &format!("invalid fragment specifier `{}`", name)[], + "valid fragment specifiers are `ident`, `block`, \ + `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \ + and `item`") } } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 8350e0222ef..666281ac6b6 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -457,7 +457,7 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> { // harmless Ok(true) }, - _ => Err(format!("unrecognized builtin nonterminal `{}`", frag)) + _ => Err(format!("invalid fragment specifier `{}`", frag)) } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 762a1dcbfc3..6e797844c18 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -17,6 +17,10 @@ //! //! Features are enabled in programs via the crate-level attributes of //! `#![feature(...)]` with a comma-separated list of features. +//! +//! For the purpose of future feature-tracking, once code for detection of feature +//! gate usage is added, *do not remove it again* even once the feature +//! becomes stable. use self::Status::*; use abi::RustIntrinsic; @@ -28,82 +32,90 @@ use codemap::{CodeMap, Span}; use diagnostic::SpanHandler; use visit; use visit::Visitor; -use parse::token; +use parse::token::{self, InternedString}; use std::slice; use std::ascii::AsciiExt; - -// if you change this list without updating src/doc/reference.md, @cmr will be sad -static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ - ("globs", Accepted), - ("macro_rules", Accepted), - ("struct_variant", Accepted), - ("asm", Active), - ("managed_boxes", Removed), - ("non_ascii_idents", Active), - ("thread_local", Active), - ("link_args", Active), - ("phase", Removed), - ("plugin_registrar", Active), - ("log_syntax", Active), - ("trace_macros", Active), - ("concat_idents", Active), - ("unsafe_destructor", Active), - ("intrinsics", Active), - ("lang_items", Active), - - ("simd", Active), - ("default_type_params", Accepted), - ("quote", Active), - ("link_llvm_intrinsics", Active), - ("linkage", Active), - ("struct_inherit", Removed), - - ("quad_precision_float", Removed), - - ("rustc_diagnostic_macros", Active), - ("unboxed_closures", Active), - ("import_shadowing", Removed), - ("advanced_slice_patterns", Active), - ("tuple_indexing", Accepted), - ("associated_types", Accepted), - ("visible_private_types", Active), - ("slicing_syntax", Active), - ("box_syntax", Active), - ("on_unimplemented", Active), - ("simd_ffi", Active), - - ("if_let", Accepted), - ("while_let", Accepted), - - ("plugin", Active), - ("start", Active), - ("main", Active), +// If you change this list without updating src/doc/reference.md, @cmr will be sad +// Don't ever remove anything from this list; set them to 'Removed'. +// The version numbers here correspond to the version in which the current status +// was set. This is most important for knowing when a particular feature became +// stable (active). +// NB: The featureck.py script parses this information directly out of the source +// so take care when modifying it. +static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ + ("globs", "1.0.0", Accepted), + ("macro_rules", "1.0.0", Accepted), + ("struct_variant", "1.0.0", Accepted), + ("asm", "1.0.0", Active), + ("managed_boxes", "1.0.0", Removed), + ("non_ascii_idents", "1.0.0", Active), + ("thread_local", "1.0.0", Active), + ("link_args", "1.0.0", Active), + ("phase", "1.0.0", Removed), + ("plugin_registrar", "1.0.0", Active), + ("log_syntax", "1.0.0", Active), + ("trace_macros", "1.0.0", Active), + ("concat_idents", "1.0.0", Active), + ("unsafe_destructor", "1.0.0", Active), + ("intrinsics", "1.0.0", Active), + ("lang_items", "1.0.0", Active), + + ("simd", "1.0.0", Active), + ("default_type_params", "1.0.0", Accepted), + ("quote", "1.0.0", Active), + ("link_llvm_intrinsics", "1.0.0", Active), + ("linkage", "1.0.0", Active), + ("struct_inherit", "1.0.0", Removed), + + ("quad_precision_float", "1.0.0", Removed), + + ("rustc_diagnostic_macros", "1.0.0", Active), + ("unboxed_closures", "1.0.0", Active), + ("import_shadowing", "1.0.0", Removed), + ("advanced_slice_patterns", "1.0.0", Active), + ("tuple_indexing", "1.0.0", Accepted), + ("associated_types", "1.0.0", Accepted), + ("visible_private_types", "1.0.0", Active), + ("slicing_syntax", "1.0.0", Active), + ("box_syntax", "1.0.0", Active), + ("on_unimplemented", "1.0.0", Active), + ("simd_ffi", "1.0.0", Active), + + ("if_let", "1.0.0", Accepted), + ("while_let", "1.0.0", Accepted), + + ("plugin", "1.0.0", Active), + ("start", "1.0.0", Active), + ("main", "1.0.0", Active), // A temporary feature gate used to enable parser extensions needed // to bootstrap fix for #5723. - ("issue_5723_bootstrap", Accepted), + ("issue_5723_bootstrap", "1.0.0", Accepted), // A way to temporarily opt out of opt in copy. This will *never* be accepted. - ("opt_out_copy", Removed), + ("opt_out_copy", "1.0.0", Removed), // A way to temporarily opt out of the new orphan rules. This will *never* be accepted. - ("old_orphan_check", Deprecated), + ("old_orphan_check", "1.0.0", Deprecated), // A way to temporarily opt out of the new impl rules. This will *never* be accepted. - ("old_impl_check", Deprecated), + ("old_impl_check", "1.0.0", Deprecated), // OIBIT specific features - ("optin_builtin_traits", Active), + ("optin_builtin_traits", "1.0.0", Active), // int and uint are now deprecated - ("int_uint", Active), + ("int_uint", "1.0.0", Active), // These are used to test this portion of the compiler, they don't actually // mean anything - ("test_accepted_feature", Accepted), - ("test_removed_feature", Removed), + ("test_accepted_feature", "1.0.0", Accepted), + ("test_removed_feature", "1.0.0", Removed), + + // Allows use of #[staged_api] + ("staged_api", "1.0.0", Active), ]; enum Status { @@ -123,7 +135,6 @@ enum Status { } /// A set of features to be used by later passes. -#[derive(Copy)] pub struct Features { pub unboxed_closures: bool, pub rustc_diagnostic_macros: bool, @@ -131,6 +142,7 @@ pub struct Features { pub quote: bool, pub old_orphan_check: bool, pub simd_ffi: bool, + pub lib_features: Vec<(InternedString, Span)> } impl Features { @@ -142,6 +154,7 @@ impl Features { quote: false, old_orphan_check: false, simd_ffi: false, + lib_features: Vec::new() } } } @@ -155,19 +168,13 @@ struct Context<'a> { impl<'a> Context<'a> { fn gate_feature(&self, feature: &str, span: Span, explain: &str) { if !self.has_feature(feature) { - self.span_handler.span_err(span, explain); - self.span_handler.span_help(span, &format!("add #![feature({})] to the \ - crate attributes to enable", - feature)[]); + emit_feature_err(self.span_handler, feature, span, explain); } } fn warn_feature(&self, feature: &str, span: Span, explain: &str) { if !self.has_feature(feature) { - self.span_handler.span_warn(span, explain); - self.span_handler.span_help(span, &format!("add #![feature({})] to the \ - crate attributes to silence this warning", - feature)[]); + emit_feature_warn(self.span_handler, feature, span, explain); } } fn has_feature(&self, feature: &str) -> bool { @@ -175,6 +182,22 @@ impl<'a> Context<'a> { } } +pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain: &str) { + diag.span_err(span, explain); + diag.span_help(span, &format!("add #![feature({})] to the \ + crate attributes to enable", + feature)[]); +} + +pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) { + diag.span_warn(span, explain); + if diag.handler.can_emit_warnings { + diag.span_help(span, &format!("add #![feature({})] to the \ + crate attributes to silence this warning", + feature)[]); + } +} + struct MacroVisitor<'a> { context: &'a Context<'a> } @@ -416,6 +439,11 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } fn visit_attribute(&mut self, attr: &ast::Attribute) { + if attr.check_name("staged_api") { + self.gate_feature("staged_api", attr.span, + "staged_api is for use by rustc only"); + } + if attr::contains_name(slice::ref_slice(attr), "lang") { self.gate_feature("lang_items", attr.span, @@ -462,7 +490,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate, check: F) - -> (Features, Vec<Span>) + -> Features where F: FnOnce(&mut Context, &ast::Crate) { let mut cx = Context { @@ -495,26 +523,26 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C } }; match KNOWN_FEATURES.iter() - .find(|& &(n, _)| name == n) { - Some(&(name, Active)) => { + .find(|& &(n, _, _)| name == n) { + Some(&(name, _, Active)) => { cx.features.push(name); } - Some(&(name, Deprecated)) => { + Some(&(name, _, Deprecated)) => { cx.features.push(name); span_handler.span_warn( mi.span, "feature is deprecated and will only be available \ for a limited time, please rewrite code that relies on it"); } - Some(&(_, Removed)) => { + Some(&(_, _, Removed)) => { span_handler.span_err(mi.span, "feature has been removed"); } - Some(&(_, Accepted)) => { + Some(&(_, _, Accepted)) => { span_handler.span_warn(mi.span, "feature has been added to Rust, \ directive not necessary"); } None => { - unknown_features.push(mi.span); + unknown_features.push((name, mi.span)); } } } @@ -524,26 +552,27 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C check(&mut cx, krate); - (Features { + Features { unboxed_closures: cx.has_feature("unboxed_closures"), rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"), visible_private_types: cx.has_feature("visible_private_types"), quote: cx.has_feature("quote"), old_orphan_check: cx.has_feature("old_orphan_check"), simd_ffi: cx.has_feature("simd_ffi"), - }, - unknown_features) + lib_features: unknown_features + } } pub fn check_crate_macros(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate) --> (Features, Vec<Span>) { +-> Features { check_crate_inner(cm, span_handler, krate, |ctx, krate| visit::walk_crate(&mut MacroVisitor { context: ctx }, krate)) } pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate) --> (Features, Vec<Span>) { +-> Features { check_crate_inner(cm, span_handler, krate, |ctx, krate| visit::walk_crate(&mut PostExpansionVisitor { context: ctx }, krate)) } + diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index bf822599a88..a1362f5382c 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -536,9 +536,10 @@ pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedPara fld: &mut T) -> ParenthesizedParameterData { - let ParenthesizedParameterData { inputs, output } = data; + let ParenthesizedParameterData { inputs, output, span } = data; ParenthesizedParameterData { inputs: inputs.move_map(|ty| fld.fold_ty(ty)), - output: output.map(|ty| fld.fold_ty(ty)) } + output: output.map(|ty| fld.fold_ty(ty)), + span: fld.new_span(span) } } pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index fa675a9fcaa..ff4c7b565cb 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -15,7 +15,8 @@ //! This API is completely unstable and subject to change. #![crate_name = "syntax"] -#![unstable] +#![unstable(feature = "rustc_private")] +#![feature(staged_api)] #![staged_api] #![crate_type = "dylib"] #![crate_type = "rlib"] @@ -28,7 +29,16 @@ #![feature(box_syntax)] #![feature(quote, unsafe_destructor)] #![allow(unknown_features)] #![feature(int_uint)] -#![allow(unstable)] +#![feature(collections)] +#![feature(core)] +#![feature(hash)] +#![feature(io)] +#![feature(libc)] +#![feature(os)] +#![feature(path)] +#![feature(rustc_private)] +#![feature(std_misc)] +#![feature(unicode)] extern crate arena; extern crate fmt_macros; diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 92a89c17579..99be1b11b11 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1486,7 +1486,7 @@ mod test { fn mk_sh() -> diagnostic::SpanHandler { let emitter = diagnostic::EmitterWriter::new(box util::NullWriter, None); - let handler = diagnostic::mk_handler(box emitter); + let handler = diagnostic::mk_handler(true, box emitter); diagnostic::mk_span_handler(handler, CodeMap::new()) } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 2b4087dba58..4bd476885a0 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -45,7 +45,7 @@ pub struct ParseSess { pub fn new_parse_sess() -> ParseSess { ParseSess { - span_diagnostic: mk_span_handler(default_handler(Auto, None), CodeMap::new()), + span_diagnostic: mk_span_handler(default_handler(Auto, None, true), CodeMap::new()), included_mod_stack: RefCell::new(Vec::new()), node_id: Cell::new(1), } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fbea265597c..4c1ae532d13 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1796,6 +1796,8 @@ impl<'a> Parser<'a> { bindings: OwnedSlice::from_vec(bindings), }) } else if self.eat(&token::OpenDelim(token::Paren)) { + let lo = self.last_span.lo; + let inputs = self.parse_seq_to_end( &token::CloseDelim(token::Paren), seq_sep_trailing_allowed(token::Comma), @@ -1807,9 +1809,12 @@ impl<'a> Parser<'a> { None }; + let hi = self.last_span.hi; + ast::ParenthesizedParameters(ast::ParenthesizedParameterData { + span: mk_sp(lo, hi), inputs: inputs, - output: output_ty + output: output_ty, }) } else { ast::PathParameters::none() diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 8933d3a9669..a7679adca2e 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -279,6 +279,24 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate { }) } +/// Craft a span that will be ignored by the stability lint's +/// call to codemap's is_internal check. +/// The expanded code calls some unstable functions in the test crate. +fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { + let info = ExpnInfo { + call_site: DUMMY_SP, + callee: NameAndSpan { + name: "test".to_string(), + format: MacroAttribute, + span: None + } + }; + let expn_id = cx.sess.span_diagnostic.cm.record_expansion(info); + let mut sp = sp; + sp.expn_id = expn_id; + return sp; +} + #[derive(PartialEq)] enum HasTestSignature { Yes, @@ -407,6 +425,65 @@ fn mk_std(cx: &TestCtxt) -> P<ast::Item> { }) } +fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> { + // Writing this out by hand with 'ignored_span': + // pub fn main() { + // #![main] + // use std::slice::AsSlice; + // test::test_main_static(::std::os::args().as_slice(), TESTS); + // } + + let sp = ignored_span(cx, DUMMY_SP); + let ecx = &cx.ext_cx; + + // std::slice::AsSlice + let as_slice_path = ecx.path(sp, vec![token::str_to_ident("std"), + token::str_to_ident("slice"), + token::str_to_ident("AsSlice")]); + // test::test_main_static + let test_main_path = ecx.path(sp, vec![token::str_to_ident("test"), + token::str_to_ident("test_main_static")]); + // ::std::os::args + let os_args_path = ecx.path_global(sp, vec![token::str_to_ident("std"), + token::str_to_ident("os"), + token::str_to_ident("args")]); + // use std::slice::AsSlice + let as_slice_path = P(nospan(ast::ViewPathSimple(token::str_to_ident("AsSlice"), + as_slice_path))); + let use_as_slice = ecx.item_use(sp, ast::Inherited, as_slice_path); + let use_as_slice = ecx.stmt_item(sp, use_as_slice); + // ::std::os::args() + let os_args_path_expr = ecx.expr_path(os_args_path); + let call_os_args = ecx.expr_call(sp, os_args_path_expr, vec![]); + // ::std::os::args().as_slice() + let call_as_slice = ecx.expr_method_call(sp, call_os_args, + token::str_to_ident("as_slice"), vec![]); + // test::test_main_static(...) + let test_main_path_expr = ecx.expr_path(test_main_path); + let tests_ident_expr = ecx.expr_ident(sp, token::str_to_ident("TESTS")); + let call_test_main = ecx.expr_call(sp, test_main_path_expr, + vec![call_as_slice, tests_ident_expr]); + let call_test_main = ecx.stmt_expr(call_test_main); + // #![main] + let main_meta = ecx.meta_word(sp, token::intern_and_get_ident("main")); + let main_attr = ecx.attribute(sp, main_meta); + // pub fn main() { ... } + let main_ret_ty = ecx.ty(sp, ast::TyTup(vec![])); + let main_body = ecx.block_all(sp, vec![use_as_slice, call_test_main], None); + let main = ast::ItemFn(ecx.fn_decl(vec![], main_ret_ty), + ast::Unsafety::Normal, ::abi::Rust, empty_generics(), main_body); + let main = P(ast::Item { + ident: token::str_to_ident("main"), + attrs: vec![main_attr], + id: ast::DUMMY_NODE_ID, + node: main, + vis: ast::Public, + span: sp + }); + + return main; +} + fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) { // Link to test crate let import = mk_std(cx); @@ -416,13 +493,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) { // The synthesized main function which will call the console test runner // with our list of tests - let mainfn = (quote_item!(&mut cx.ext_cx, - pub fn main() { - #![main] - use std::slice::AsSlice; - test::test_main_static(::std::os::args().as_slice(), TESTS); - } - )).unwrap(); + let mainfn = mk_main(cx); let testmod = ast::Mod { inner: DUMMY_SP, @@ -431,16 +502,10 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) { let item_ = ast::ItemMod(testmod); let mod_ident = token::gensym_ident("__test"); - let allow_unstable = { - let unstable = P(nospan(ast::MetaWord(InternedString::new("unstable")))); - let allow = P(nospan(ast::MetaList(InternedString::new("allow"), - vec![unstable]))); - attr::mk_attr_inner(attr::mk_attr_id(), allow) - }; let item = P(ast::Item { id: ast::DUMMY_NODE_ID, ident: mod_ident, - attrs: vec![allow_unstable], + attrs: vec![], node: item_, vis: ast::Public, span: DUMMY_SP, @@ -537,7 +602,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> { // __test_reexports, causing it to be reinterned, losing the // gensym information. - let span = test.span; + let span = ignored_span(cx, test.span); let path = test.path.clone(); let ecx = &cx.ext_cx; let self_id = ecx.ident_of("self"); diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index d8bac19805b..21a7d680847 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -112,7 +112,8 @@ impl<T> SmallVector<T> { } /// Deprecated: use `into_iter`. - #[deprecated = "use into_iter"] + #[unstable(feature = "rustc_private")] + #[deprecated(since = "1.0.0", reason = "use into_iter")] pub fn move_iter(self) -> IntoIter<T> { self.into_iter() } |
