diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md index 133174268ef93..00c81f03ba173 100644 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/slice-patterns.md @@ -1,8 +1,8 @@ # `slice_patterns` -The tracking issue for this feature is: [#23121] +The tracking issue for this feature is: [#62254] -[#23121]: https://github.com/rust-lang/rust/issues/23121 +[#62254]: https://github.com/rust-lang/rust/issues/62254 ------------------------ diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9109a730cce2d..19b0f82db4335 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -367,12 +367,19 @@ impl Clone for Box { /// ``` /// let x = Box::new(5); /// let y = x.clone(); + /// + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // But they are unique objects + /// assert_ne!(&*x as *const i32, &*y as *const i32); /// ``` #[rustfmt::skip] #[inline] fn clone(&self) -> Box { box { (**self).clone() } } + /// Copies `source`'s contents into `self` without creating a new allocation. /// /// # Examples @@ -380,10 +387,15 @@ impl Clone for Box { /// ``` /// let x = Box::new(5); /// let mut y = Box::new(10); + /// let yp: *const i32 = &*y; /// /// y.clone_from(&x); /// - /// assert_eq!(*y, 5); + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // And no allocation occurred + /// assert_eq!(yp, &*y); /// ``` #[inline] fn clone_from(&mut self, source: &Box) { diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index a697b7bd6e589..c0de8e2ceb3f3 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -251,12 +251,12 @@ pub trait AsMut { /// /// # Examples /// -/// [`String`] implements `Into>`: +/// [`String`] implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>`: /// /// In order to express that we want a generic function to take all arguments that can be /// converted to a specified type `T`, we can use a trait bound of [`Into`]``. /// For example: The function `is_hello` takes all arguments that can be converted into a -/// `Vec`. +/// [`Vec`]`<`[`u8`]`>`. /// /// ``` /// fn is_hello>>(s: T) { @@ -274,6 +274,7 @@ pub trait AsMut { /// [`String`]: ../../std/string/struct.String.html /// [`From`]: trait.From.html /// [`Into`]: trait.Into.html +/// [`Vec`]: ../../std/vec/struct.Vec.html #[stable(feature = "rust1", since = "1.0.0")] pub trait Into: Sized { /// Performs the conversion. @@ -410,12 +411,12 @@ pub trait TryInto: Sized { /// /// This is useful when you are doing a type conversion that may /// trivially succeed but may also need special handling. -/// For example, there is no way to convert an `i64` into an `i32` -/// using the [`From`] trait, because an `i64` may contain a value -/// that an `i32` cannot represent and so the conversion would lose data. -/// This might be handled by truncating the `i64` to an `i32` (essentially -/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning -/// `i32::MAX`, or by some other method. The `From` trait is intended +/// For example, there is no way to convert an [`i64`] into an [`i32`] +/// using the [`From`] trait, because an [`i64`] may contain a value +/// that an [`i32`] cannot represent and so the conversion would lose data. +/// This might be handled by truncating the [`i64`] to an [`i32`] (essentially +/// giving the [`i64`]'s value modulo [`i32::MAX`]) or by simply returning +/// [`i32::MAX`], or by some other method. The [`From`] trait is intended /// for perfect conversions, so the `TryFrom` trait informs the /// programmer when a type conversion could go bad and lets them /// decide how to handle it. @@ -425,8 +426,8 @@ pub trait TryInto: Sized { /// - `TryFrom for U` implies [`TryInto`]` for T` /// - [`try_from`] is reflexive, which means that `TryFrom for T` /// is implemented and cannot fail -- the associated `Error` type for -/// calling `T::try_from()` on a value of type `T` is `Infallible`. -/// When the `!` type is stablized `Infallible` and `!` will be +/// calling `T::try_from()` on a value of type `T` is [`Infallible`]. +/// When the [`!`] type is stablized [`Infallible`] and [`!`] will be /// equivalent. /// /// `TryFrom` can be implemented as follows: @@ -451,7 +452,7 @@ pub trait TryInto: Sized { /// /// # Examples /// -/// As described, [`i32`] implements `TryFrom`: +/// As described, [`i32`] implements `TryFrom<`[`i64`]`>`: /// /// ``` /// use std::convert::TryFrom; @@ -474,6 +475,8 @@ pub trait TryInto: Sized { /// /// [`try_from`]: trait.TryFrom.html#tymethod.try_from /// [`TryInto`]: trait.TryInto.html +/// [`i32::MAX`]: ../../std/i32/constant.MAX.html +/// [`!`]: ../../std/primitive.never.html #[stable(feature = "try_from", since = "1.34.0")] pub trait TryFrom: Sized { /// The type returned in the event of a conversion error. diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 04c50329de3d0..1f31b65b3603b 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -74,6 +74,7 @@ #![feature(concat_idents)] #![feature(const_fn)] #![feature(const_fn_union)] +#![feature(custom_inner_attributes)] #![feature(doc_cfg)] #![feature(doc_spotlight)] #![feature(extern_types)] diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index e110e93a95412..b31522db474b7 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -552,6 +552,12 @@ pub fn swap(x: &mut T, y: &mut T) { /// mem::take(&mut self.buf) /// } /// } +/// +/// let mut buffer = Buffer { buf: vec![0, 1] }; +/// assert_eq!(buffer.buf.len(), 2); +/// +/// assert_eq!(buffer.get_and_reset(), vec![0, 1]); +/// assert_eq!(buffer.buf.len(), 0); /// ``` /// /// [`Clone`]: ../../std/clone/trait.Clone.html @@ -586,17 +592,17 @@ pub fn take(dest: &mut T) -> T { /// struct Buffer { buf: Vec } /// /// impl Buffer { -/// fn get_and_reset(&mut self) -> Vec { +/// fn replace_index(&mut self, i: usize, v: T) -> T { /// // error: cannot move out of dereference of `&mut`-pointer -/// let buf = self.buf; -/// self.buf = Vec::new(); -/// buf +/// let t = self.buf[i]; +/// self.buf[i] = v; +/// t /// } /// } /// ``` /// -/// Note that `T` does not necessarily implement [`Clone`], so it can't even clone and reset -/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from +/// Note that `T` does not necessarily implement [`Clone`], so we can't even clone `self.buf[i]` to +/// avoid the move. But `replace` can be used to disassociate the original value at that index from /// `self`, allowing it to be returned: /// /// ``` @@ -605,10 +611,16 @@ pub fn take(dest: &mut T) -> T { /// /// # struct Buffer { buf: Vec } /// impl Buffer { -/// fn get_and_reset(&mut self) -> Vec { -/// mem::replace(&mut self.buf, Vec::new()) +/// fn replace_index(&mut self, i: usize, v: T) -> T { +/// mem::replace(&mut self.buf[i], v) /// } /// } +/// +/// let mut buffer = Buffer { buf: vec![0, 1] }; +/// assert_eq!(buffer.buf[0], 0); +/// +/// assert_eq!(buffer.replace_index(0, 2), 0); +/// assert_eq!(buffer.buf[0], 2); /// ``` /// /// [`Clone`]: ../../std/clone/trait.Clone.html diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 618e8b8699fcc..0455643167735 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -653,10 +653,14 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, linker_error.emit(); if sess.target.target.options.is_like_msvc && linker_not_found { - sess.note_without_error("the msvc targets depend on the msvc linker \ - but `link.exe` was not found"); - sess.note_without_error("please ensure that VS 2013, VS 2015 or VS 2017 \ - was installed with the Visual C++ option"); + sess.note_without_error( + "the msvc targets depend on the msvc linker \ + but `link.exe` was not found", + ); + sess.note_without_error( + "please ensure that VS 2013, VS 2015, VS 2017 or VS 2019 \ + was installed with the Visual C++ option", + ); } sess.abort_if_errors(); } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index a86d3cc43948d..6ae5e94b11af3 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -642,14 +642,14 @@ pub fn build_output_filenames( ); None } else { + if !sess.opts.cg.extra_filename.is_empty() { + sess.warn("ignoring -C extra-filename flag due to -o flag"); + } Some(out_file.clone()) }; if *odir != None { sess.warn("ignoring --out-dir flag due to -o flag"); } - if !sess.opts.cg.extra_filename.is_empty() { - sess.warn("ignoring -C extra-filename flag due to -o flag"); - } OutputFilenames { out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index fbacdf6cd93bb..e6c9d9f5c79d8 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -1,7 +1,7 @@ use rustc::ty::{self, Ty, TypeAndMut}; use rustc::ty::layout::{self, TyLayout, Size}; use rustc::ty::adjustment::{PointerCast}; -use syntax::ast::{FloatTy, IntTy, UintTy}; +use syntax::ast::FloatTy; use syntax::symbol::sym; use rustc_apfloat::ieee::{Single, Double}; @@ -151,7 +151,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { "Unexpected cast from type {:?}", src_layout.ty ); match val.to_bits_or_ptr(src_layout.size, self) { - Err(ptr) => self.cast_from_ptr(ptr, dest_layout.ty), + Err(ptr) => self.cast_from_ptr(ptr, src_layout, dest_layout), Ok(data) => self.cast_from_int(data, src_layout, dest_layout), } } @@ -239,17 +239,25 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { fn cast_from_ptr( &self, ptr: Pointer, - ty: Ty<'tcx> + src_layout: TyLayout<'tcx>, + dest_layout: TyLayout<'tcx>, ) -> InterpResult<'tcx, Scalar> { use rustc::ty::TyKind::*; - match ty.sty { + + match dest_layout.ty.sty { // Casting to a reference or fn pointer is not permitted by rustc, // no need to support it here. - RawPtr(_) | - Int(IntTy::Isize) | - Uint(UintTy::Usize) => Ok(ptr.into()), - Int(_) | Uint(_) => err!(ReadPointerAsBytes), - _ => err!(Unimplemented(format!("ptr to {:?} cast", ty))), + RawPtr(_) => Ok(ptr.into()), + Int(_) | Uint(_) => { + let size = self.memory.pointer_size(); + + match self.force_bits(Scalar::Ptr(ptr), size) { + Ok(bits) => self.cast_from_int(bits, src_layout, dest_layout), + Err(_) if dest_layout.size == size => Ok(ptr.into()), + Err(e) => Err(e), + } + } + _ => bug!("invalid MIR: ptr to {:?} cast", dest_layout.ty) } } diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 16d484e2a98f2..640662d7733e7 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -6,7 +6,7 @@ use rustc::util::nodemap::FxHashMap; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension}; use syntax::ext::base::MacroExpanderFn; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::Symbol; use syntax::ast; use syntax::feature_gate::AttributeType; use syntax_pos::Span; @@ -85,9 +85,6 @@ impl<'a> Registry<'a> { /// /// This is the most general hook into `libsyntax`'s expansion behavior. pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) { - if name == sym::macro_rules { - panic!("user-defined macros may not be named `macro_rules`"); - } if extension.def_info.is_none() { extension.def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 392a46a262f50..cec3e89215409 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -19,9 +19,8 @@ use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; -use syntax::feature_gate::{ - feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES, -}; +use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name}; +use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES}; use syntax::symbol::{Symbol, kw, sym}; use syntax::visit::Visitor; use syntax::util::lev_distance::find_best_match_for_name; @@ -298,12 +297,25 @@ impl<'a> Resolver<'a> { let res = self.resolve_macro_to_res_inner(path, kind, parent_scope, trace, force); // Report errors and enforce feature gates for the resolved macro. + let features = self.session.features_untracked(); if res != Err(Determinacy::Undetermined) { // Do not report duplicated errors on every undetermined resolution. for segment in &path.segments { if let Some(args) = &segment.args { self.session.span_err(args.span(), "generic arguments in macro path"); } + if kind == MacroKind::Attr && !features.rustc_attrs && + segment.ident.as_str().starts_with("rustc") { + let msg = "attributes starting with `rustc` are \ + reserved for use by the `rustc` compiler"; + emit_feature_err( + &self.session.parse_sess, + sym::rustc_attrs, + segment.ident.span, + GateIssue::Language, + msg, + ); + } } } @@ -320,24 +332,15 @@ impl<'a> Resolver<'a> { } Res::NonMacroAttr(attr_kind) => { if kind == MacroKind::Attr { - let features = self.session.features_untracked(); if attr_kind == NonMacroAttrKind::Custom { assert!(path.segments.len() == 1); - let name = path.segments[0].ident.as_str(); - if name.starts_with("rustc_") { - if !features.rustc_attrs { - let msg = "unless otherwise specified, attributes with the prefix \ - `rustc_` are reserved for internal compiler diagnostics"; - self.report_unknown_attribute(path.span, &name, msg, - sym::rustc_attrs); - } - } else if !features.custom_attribute { + if !features.custom_attribute { let msg = format!("The attribute `{}` is currently unknown to the \ compiler and may have meaning added to it in the \ future", path); self.report_unknown_attribute( path.span, - &name, + &path.segments[0].ident.as_str(), &msg, sym::custom_attribute, ); @@ -1109,9 +1112,6 @@ impl<'a> Resolver<'a> { current_legacy_scope: &mut LegacyScope<'a>) { self.local_macro_def_scopes.insert(item.id, self.current_module); let ident = item.ident; - if ident.name == sym::macro_rules { - self.session.span_err(item.span, "user-defined macros may not be named `macro_rules`"); - } let def_id = self.definitions.local_def_id(item.id); let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess, diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs index fdd747cdb865a..b139083e99fc1 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -19,6 +19,10 @@ pub fn opts() -> TargetOptions { target_family: Some("windows".to_string()), is_like_windows: true, is_like_msvc: true, + // set VSLANG to 1033 can prevent link.exe from using + // language packs, and avoid generating Non-UTF-8 error + // messages if a link error occurred. + link_env: vec![("VSLANG".to_string(), "1033".to_string())], pre_link_args: args, crt_static_allows_dylibs: true, crt_static_respected: true, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index b435c99ad01f5..bcb66f1715942 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -458,7 +458,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match ty.sty { ty::Array(..) | ty::Slice(..) => { err.help("the semantics of slice patterns changed \ - recently; see issue #23121"); + recently; see issue #62254"); } _ => {} } diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 6088c03fc0681..0b04160522047 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -7,7 +7,6 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. -use rustc::dep_graph::DepKind; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; @@ -36,35 +35,11 @@ pub fn crate_inherent_impls<'tcx>( pub fn inherent_impls<'tcx>(tcx: TyCtxt<'tcx>, ty_def_id: DefId) -> &'tcx [DefId] { assert!(ty_def_id.is_local()); - // NB. Until we adopt the red-green dep-tracking algorithm (see - // [the plan] for details on that), we do some hackery here to get - // the dependencies correct. Basically, we use a `with_ignore` to - // read the result we want. If we didn't have the `with_ignore`, - // we would wind up with a dependency on the entire crate, which - // we don't want. Then we go and add dependencies on all the impls - // in the result (which is what we wanted). - // - // The result is a graph with an edge from `Hir(I)` for every impl - // `I` defined on some type `T` to `CoherentInherentImpls(T)`, - // thus ensuring that if any of those impls change, the set of - // inherent impls is considered dirty. - // - // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4 - - let result = tcx.dep_graph.with_ignore(|| { - let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); - match crate_map.inherent_impls.get(&ty_def_id) { - Some(v) => &v[..], - None => &[], - } - }); - - for &impl_def_id in &result[..] { - let def_path_hash = tcx.def_path_hash(impl_def_id); - tcx.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir)); + let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); + match crate_map.inherent_impls.get(&ty_def_id) { + Some(v) => &v[..], + None => &[], } - - result } struct InherentCollect<'tcx> { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5473f55aa3370..028b902177ff2 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -13,8 +13,7 @@ use crate::parse::{DirectoryOwnership, PResult, ParseSess}; use crate::parse::token; use crate::parse::parser::Parser; use crate::ptr::P; -use crate::symbol::Symbol; -use crate::symbol::{kw, sym}; +use crate::symbol::{sym, Symbol}; use crate::tokenstream::{TokenStream, TokenTree}; use crate::visit::{self, Visitor}; use crate::util::map_in_place::MapInPlace; @@ -197,7 +196,6 @@ pub struct Invocation { pub enum InvocationKind { Bang { mac: ast::Mac, - ident: Option, span: Span, }, Attr { @@ -664,13 +662,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ext: &SyntaxExtension) -> Option { let kind = invoc.fragment_kind; - let (mac, ident, span) = match invoc.kind { - InvocationKind::Bang { mac, ident, span } => (mac, ident, span), + let (mac, span) = match invoc.kind { + InvocationKind::Bang { mac, span } => (mac, span), _ => unreachable!(), }; let path = &mac.node.path; - let ident = ident.unwrap_or_else(|| Ident::invalid()); let validate = |this: &mut Self| { // feature-gate the macro invocation if let Some((feature, issue)) = ext.unstable_feature { @@ -690,12 +687,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - if ident.name != kw::Invalid { - let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); - this.cx.span_err(path.span, &msg); - this.cx.trace_macros_diag(); - return Err(kind.dummy(span)); - } Ok(()) }; @@ -729,19 +720,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } SyntaxExtensionKind::Bang(expander) => { - if ident.name != kw::Invalid { - let msg = - format!("macro {}! expects no ident argument, given '{}'", path, ident); - self.cx.span_err(path.span, &msg); - self.cx.trace_macros_diag(); - kind.dummy(span) - } else { - self.gate_proc_macro_expansion_kind(span, kind); - let tok_result = expander.expand(self.cx, span, mac.node.stream()); - let result = self.parse_ast_fragment(tok_result, kind, path, span); - self.gate_proc_macro_expansion(span, &result); - result - } + self.gate_proc_macro_expansion_kind(span, kind); + let tok_result = expander.expand(self.cx, span, mac.node.stream()); + let result = self.parse_ast_fragment(tok_result, kind, path, span); + self.gate_proc_macro_expansion(span, &result); + result } }; @@ -944,7 +927,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment { - self.collect(kind, InvocationKind::Bang { mac, ident: None, span }) + self.collect(kind, InvocationKind::Bang { mac, span }) } fn collect_attr(&mut self, @@ -1179,13 +1162,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { ast::ItemKind::Mac(..) => { self.check_attributes(&item.attrs); item.and_then(|item| match item.node { - ItemKind::Mac(mac) => { - self.collect(AstFragmentKind::Items, InvocationKind::Bang { - mac, - ident: Some(item.ident), - span: item.span, - }).make_items() - } + ItemKind::Mac(mac) => self.collect( + AstFragmentKind::Items, InvocationKind::Bang { mac, span: item.span } + ).make_items(), _ => unreachable!(), }) } @@ -1525,9 +1504,7 @@ impl<'feat> ExpansionConfig<'feat> { } fn enable_custom_inner_attributes(&self) -> bool { - self.features.map_or(false, |features| { - features.custom_inner_attributes || features.custom_attribute || features.rustc_attrs - }) + self.features.map_or(false, |features| features.custom_inner_attributes) } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f97e9d43854fc..c3c049a14acfc 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -323,7 +323,7 @@ declare_features! ( (active, nll, "1.0.0", Some(43234), None), // Allows using slice patterns. - (active, slice_patterns, "1.0.0", Some(23121), None), + (active, slice_patterns, "1.0.0", Some(62254), None), // Allows the definition of `const` functions with some advanced features. (active, const_fn, "1.2.0", Some(57563), None), @@ -607,7 +607,7 @@ declare_features! ( (removed, allocator, "1.0.0", None, None, None), (removed, simd, "1.0.0", Some(27731), None, Some("removed in favor of `#[repr(simd)]`")), - (removed, advanced_slice_patterns, "1.0.0", Some(23121), None, + (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, Some("merged into `#![feature(slice_patterns)]`")), (removed, macro_reexport, "1.0.0", Some(29638), None, Some("subsumed by `pub use`")), @@ -1289,6 +1289,18 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ attribute is just used for rustc unit \ tests and will never be stable", cfg_fn!(rustc_attrs))), + (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "the `#[rustc_dump_env_program_clauses]` \ + attribute is just used for rustc unit \ + tests and will never be stable", + cfg_fn!(rustc_attrs))), + (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "the `#[rustc_object_lifetime_default]` \ + attribute is just used for rustc unit \ + tests and will never be stable", + cfg_fn!(rustc_attrs))), (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable, sym::rustc_attrs, "the `#[rustc_test_marker]` attribute \ @@ -1350,6 +1362,26 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "internal implementation detail", cfg_fn!(rustc_attrs))), + (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "internal implementation detail", + cfg_fn!(rustc_attrs))), + + (sym::rustc_doc_only_macro, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "internal implementation detail", + cfg_fn!(rustc_attrs))), + + (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "internal implementation detail", + cfg_fn!(rustc_attrs))), + + (sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable, + sym::rustc_attrs, + "internal implementation detail", + cfg_fn!(rustc_attrs))), + (sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable, sym::rustc_attrs, "used by the test suite", @@ -1636,6 +1668,14 @@ impl<'a> Context<'a> { } debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); return; + } else { + for segment in &attr.path.segments { + if segment.ident.as_str().starts_with("rustc") { + let msg = "attributes starting with `rustc` are \ + reserved for use by the `rustc` compiler"; + gate_feature!(self, rustc_attrs, segment.ident.span, msg); + } + } } for &(n, ty) in self.plugin_attributes { if attr.path == n { @@ -1646,19 +1686,13 @@ impl<'a> Context<'a> { return; } } - if !attr::is_known(attr) { - if attr.name_or_empty().as_str().starts_with("rustc_") { - let msg = "unless otherwise specified, attributes with the prefix `rustc_` \ - are reserved for internal compiler diagnostics"; - gate_feature!(self, rustc_attrs, attr.span, msg); - } else if !is_macro { - // Only run the custom attribute lint during regular feature gate - // checking. Macro gating runs before the plugin attributes are - // registered, so we skip this in that case. - let msg = format!("The attribute `{}` is currently unknown to the compiler and \ - may have meaning added to it in the future", attr.path); - gate_feature!(self, custom_attribute, attr.span, &msg); - } + if !is_macro && !attr::is_known(attr) { + // Only run the custom attribute lint during regular feature gate + // checking. Macro gating runs before the plugin attributes are + // registered, so we skip this in that case. + let msg = format!("The attribute `{}` is currently unknown to the compiler and \ + may have meaning added to it in the future", attr.path); + gate_feature!(self, custom_attribute, attr.span, &msg); } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 696b5f48385e7..8b657697c832e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4324,51 +4324,49 @@ impl<'a> Parser<'a> { fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span) -> PResult<'a, Option>> { let token_lo = self.token.span; - let (ident, def) = match self.token.kind { - token::Ident(name, false) if name == kw::Macro => { - self.bump(); - let ident = self.parse_ident()?; - let tokens = if self.check(&token::OpenDelim(token::Brace)) { - match self.parse_token_tree() { - TokenTree::Delimited(_, _, tts) => tts, - _ => unreachable!(), - } - } else if self.check(&token::OpenDelim(token::Paren)) { - let args = self.parse_token_tree(); - let body = if self.check(&token::OpenDelim(token::Brace)) { - self.parse_token_tree() - } else { - self.unexpected()?; - unreachable!() - }; - TokenStream::new(vec![ - args.into(), - TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(), - body.into(), - ]) + let (ident, def) = if self.eat_keyword(kw::Macro) { + let ident = self.parse_ident()?; + let tokens = if self.check(&token::OpenDelim(token::Brace)) { + match self.parse_token_tree() { + TokenTree::Delimited(_, _, tts) => tts, + _ => unreachable!(), + } + } else if self.check(&token::OpenDelim(token::Paren)) { + let args = self.parse_token_tree(); + let body = if self.check(&token::OpenDelim(token::Brace)) { + self.parse_token_tree() } else { self.unexpected()?; unreachable!() }; + TokenStream::new(vec![ + args.into(), + TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(), + body.into(), + ]) + } else { + self.unexpected()?; + unreachable!() + }; - (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) - } - token::Ident(name, _) if name == sym::macro_rules && - self.look_ahead(1, |t| *t == token::Not) => { - let prev_span = self.prev_span; - self.complain_if_pub_macro(&vis.node, prev_span); - self.bump(); - self.bump(); - - let ident = self.parse_ident()?; - let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { - self.report_invalid_macro_expansion_item(); - } + (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) + } else if self.check_keyword(sym::macro_rules) && + self.look_ahead(1, |t| *t == token::Not) && + self.look_ahead(2, |t| t.is_ident()) { + let prev_span = self.prev_span; + self.complain_if_pub_macro(&vis.node, prev_span); + self.bump(); + self.bump(); - (ident, ast::MacroDef { tokens, legacy: true }) + let ident = self.parse_ident()?; + let (delim, tokens) = self.expect_delimited_token_tree()?; + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } - _ => return Ok(None), + + (ident, ast::MacroDef { tokens, legacy: true }) + } else { + return Ok(None); }; let span = lo.to(self.prev_span); @@ -4412,14 +4410,14 @@ impl<'a> Parser<'a> { !self.is_existential_type_decl() && !self.is_auto_trait_item() && !self.is_async_fn() { - let pth = self.parse_path(PathStyle::Expr)?; + let path = self.parse_path(PathStyle::Expr)?; if !self.eat(&token::Not) { let expr = if self.check(&token::OpenDelim(token::Brace)) { - self.parse_struct_expr(lo, pth, ThinVec::new())? + self.parse_struct_expr(lo, path, ThinVec::new())? } else { let hi = self.prev_span; - self.mk_expr(lo.to(hi), ExprKind::Path(None, pth), ThinVec::new()) + self.mk_expr(lo.to(hi), ExprKind::Path(None, path), ThinVec::new()) }; let expr = self.with_res(Restrictions::STMT_EXPR, |this| { @@ -4434,34 +4432,6 @@ impl<'a> Parser<'a> { })); } - // it's a macro invocation - let id = match self.token.kind { - token::OpenDelim(_) => Ident::invalid(), // no special identifier - _ => self.parse_ident()?, - }; - - // check that we're pointing at delimiters (need to check - // again after the `if`, because of `parse_ident` - // consuming more tokens). - match self.token.kind { - token::OpenDelim(_) => {} - _ => { - // we only expect an ident if we didn't parse one - // above. - let ident_str = if id.name == kw::Invalid { - "identifier, " - } else { - "" - }; - let tok_str = self.this_token_descr(); - let mut err = self.fatal(&format!("expected {}`(` or `{{`, found {}", - ident_str, - tok_str)); - err.span_label(self.token.span, format!("expected {}`(` or `{{`", ident_str)); - return Err(err) - }, - } - let (delim, tts) = self.expect_delimited_token_tree()?; let hi = self.prev_span; @@ -4471,59 +4441,38 @@ impl<'a> Parser<'a> { MacStmtStyle::NoBraces }; - if id.name == kw::Invalid { - let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim }); - let node = if delim == MacDelimiter::Brace || - self.token == token::Semi || self.token == token::Eof { - StmtKind::Mac(P((mac, style, attrs.into()))) - } - // We used to incorrectly stop parsing macro-expanded statements here. - // If the next token will be an error anyway but could have parsed with the - // earlier behavior, stop parsing here and emit a warning to avoid breakage. - else if macro_legacy_warnings && - self.token.can_begin_expr() && - match self.token.kind { - // These can continue an expression, so we can't stop parsing and warn. - token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) | - token::BinOp(token::Minus) | token::BinOp(token::Star) | - token::BinOp(token::And) | token::BinOp(token::Or) | - token::AndAnd | token::OrOr | - token::DotDot | token::DotDotDot | token::DotDotEq => false, - _ => true, - } { - self.warn_missing_semicolon(); - StmtKind::Mac(P((mac, style, attrs.into()))) - } else { - let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new()); - let e = self.maybe_recover_from_bad_qpath(e, true)?; - let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; - let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; - StmtKind::Expr(e) - }; - Stmt { - id: ast::DUMMY_NODE_ID, - span: lo.to(hi), - node, - } + let mac = respan(lo.to(hi), Mac_ { path, tts, delim }); + let node = if delim == MacDelimiter::Brace || + self.token == token::Semi || self.token == token::Eof { + StmtKind::Mac(P((mac, style, attrs.into()))) + } + // We used to incorrectly stop parsing macro-expanded statements here. + // If the next token will be an error anyway but could have parsed with the + // earlier behavior, stop parsing here and emit a warning to avoid breakage. + else if macro_legacy_warnings && + self.token.can_begin_expr() && + match self.token.kind { + // These can continue an expression, so we can't stop parsing and warn. + token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) | + token::BinOp(token::Minus) | token::BinOp(token::Star) | + token::BinOp(token::And) | token::BinOp(token::Or) | + token::AndAnd | token::OrOr | + token::DotDot | token::DotDotDot | token::DotDotEq => false, + _ => true, + } { + self.warn_missing_semicolon(); + StmtKind::Mac(P((mac, style, attrs.into()))) } else { - // if it has a special ident, it's definitely an item - // - // Require a semicolon or braces. - if style != MacStmtStyle::Braces && !self.eat(&token::Semi) { - self.report_invalid_macro_expansion_item(); - } - let span = lo.to(hi); - Stmt { - id: ast::DUMMY_NODE_ID, - span, - node: StmtKind::Item({ - self.mk_item( - span, id /*id is good here*/, - ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })), - respan(lo, VisibilityKind::Inherited), - attrs) - }), - } + let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new()); + let e = self.maybe_recover_from_bad_qpath(e, true)?; + let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; + let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; + StmtKind::Expr(e) + }; + Stmt { + id: ast::DUMMY_NODE_ID, + span: lo.to(hi), + node, } } else { // FIXME: Bad copy of attrs @@ -7619,26 +7568,17 @@ impl<'a> Parser<'a> { let mac_lo = self.token.span; // item macro. - let pth = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; self.expect(&token::Not)?; - - // a 'special' identifier (like what `macro_rules!` uses) - // is optional. We should eventually unify invoc syntax - // and remove this. - let id = if self.token.is_ident() { - self.parse_ident()? - } else { - Ident::invalid() // no special identifier - }; - // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item(); } let hi = self.prev_span; - let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim }); - let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs); + let mac = respan(mac_lo.to(hi), Mac_ { path, tts, delim }); + let item = + self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs); return Ok(Some(item)); } @@ -7664,9 +7604,9 @@ impl<'a> Parser<'a> { !(self.is_async_fn() && self.token.span.rust_2015()) { let prev_span = self.prev_span; let lo = self.token.span; - let pth = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; - if pth.segments.len() == 1 { + if path.segments.len() == 1 { if !self.eat(&token::Not) { return Err(self.missing_assoc_item_kind_err(item_kind, prev_span)); } @@ -7686,7 +7626,7 @@ impl<'a> Parser<'a> { self.expect(&token::Semi)?; } - Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim }))) + Ok(Some(respan(lo.to(self.prev_span), Mac_ { path, tts, delim }))) } else { Ok(None) } diff --git a/src/test/run-pass-fulldeps/issue-15778-pass.rs b/src/test/run-pass-fulldeps/issue-15778-pass.rs index 2add3ccbe36f2..35152e7f4babd 100644 --- a/src/test/run-pass-fulldeps/issue-15778-pass.rs +++ b/src/test/run-pass-fulldeps/issue-15778-pass.rs @@ -2,7 +2,8 @@ // ignore-stage1 // compile-flags: -D crate-not-okay -#![feature(plugin, rustc_attrs)] +#![feature(plugin, custom_attribute, custom_inner_attributes, rustc_attrs)] + #![plugin(lint_for_crate)] #![rustc_crate_okay] #![rustc_crate_blue] @@ -10,4 +11,4 @@ #![rustc_crate_grey] #![rustc_crate_green] -pub fn main() { } +fn main() {} diff --git a/src/test/run-pass/attr-on-generic-formals.rs b/src/test/run-pass/attr-on-generic-formals.rs deleted file mode 100644 index 9ebf0fcb1c192..0000000000000 --- a/src/test/run-pass/attr-on-generic-formals.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![allow(unused_attributes)] - -// This test ensures we can attach attributes to the formals in all -// places where generic parameter lists occur, assuming appropriate -// feature gates are enabled. -// -// (We are prefixing all tested features with `rustc_`, to ensure that -// the attributes themselves won't be rejected by the compiler when -// using `rustc_attrs` feature. There is a separate compile-fail/ test -// ensuring that the attribute feature-gating works in this context.) - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -struct StLt<#[rustc_lt_struct] 'a>(&'a u32); -struct StTy<#[rustc_ty_struct] I>(I); - -enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B } -enum EnTy<#[rustc_ty_enum] J> { A(J), B } - -trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } -trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); } - -type TyLt<#[rustc_lt_type] 'd> = &'d u32; -type TyTy<#[rustc_ty_type] L> = (L, ); - -impl<#[rustc_lt_inherent] 'e> StLt<'e> { } -impl<#[rustc_ty_inherent] M> StTy { } - -impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } -} -impl<#[rustc_ty_impl_for] N> TrTy for StTy { - fn foo(&self, _: N) { } -} - -fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } -fn f_ty<#[rustc_ty_fn] O>(_: O) { } - -impl StTy { - fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - fn m_ty<#[rustc_ty_meth] P>(_: P) { } -} - -fn hof_lt(_: Q) - where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 -{ -} - -fn main() { - -} diff --git a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs index 51a3b46d4619b..0ab7e17f87b5a 100644 --- a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs +++ b/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs @@ -1,7 +1,7 @@ // run-pass #![feature(decl_macro)] -r#macro_rules! r#struct { +macro_rules! r#struct { ($r#struct:expr) => { $r#struct } } diff --git a/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs b/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs index ca5fdd9da859b..df9c8d894652b 100644 --- a/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs +++ b/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs @@ -6,10 +6,8 @@ struct RefIntPair<'a, 'b>(&'a u32, &'b u32); -impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { +impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { //~^ ERROR trailing attribute after generic parameter } -fn main() { - -} +fn main() {} diff --git a/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr b/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr index 55e7a9877846f..5b4f5222a2b14 100644 --- a/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr +++ b/src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr @@ -1,8 +1,8 @@ error: trailing attribute after generic parameter - --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25 + --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:29 | -LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { - | ^^^^^^^ attributes must go before parameters +LL | impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs b/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs index c795612acf08c..d1d044035260b 100644 --- a/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs +++ b/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs @@ -6,7 +6,7 @@ struct RefAny<'a, T>(&'a T); -impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} +impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {} //~^ ERROR trailing attribute after generic parameter fn main() {} diff --git a/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr b/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr index acd0ae3678a7c..fce3ff7de78e8 100644 --- a/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr +++ b/src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr @@ -1,8 +1,8 @@ error: trailing attribute after generic parameter - --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35 + --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:43 | -LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} - | ^^^^^^^ attributes must go before parameters +LL | impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {} + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs index 0395795ef7bfe..0f9d37292958a 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs @@ -5,7 +5,7 @@ const fn error(_: fn()) {} #[stable(feature = "rust1", since = "1.0.0")] #[rustc_allow_const_fn_ptr] -//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved +//~^ ERROR internal implementation detail const fn compiles(_: fn()) {} fn main() {} diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr index c934307e918b9..d2ca0c8bc381b 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr @@ -1,8 +1,8 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics - --> $DIR/allow_const_fn_ptr_feature_gate.rs:7:3 +error[E0658]: internal implementation detail + --> $DIR/allow_const_fn_ptr_feature_gate.rs:7:1 | LL | #[rustc_allow_const_fn_ptr] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(rustc_attrs)] to the crate attributes to enable diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs index 5ec413cc71de0..d3a2e486416af 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -1,6 +1,23 @@ // Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate. -#[rustc_foo] -//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved +#![feature(decl_macro)] +mod rustc { pub macro unknown() {} } +mod unknown { pub macro rustc() {} } + +#[rustc::unknown] +//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~| ERROR macro `rustc::unknown` may not be used in attributes +fn f() {} + +#[unknown::rustc] +//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~| ERROR macro `unknown::rustc` may not be used in attributes +fn g() {} + +#[rustc_dummy] +//~^ ERROR used by the test suite +#[rustc_unknown] +//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~| ERROR attribute `rustc_unknown` is currently unknown fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr index 3c823c8d4e25f..cdc7b27a749e5 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -1,12 +1,60 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics - --> $DIR/feature-gate-rustc-attrs.rs:3:3 +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/feature-gate-rustc-attrs.rs:8:3 | -LL | #[rustc_foo] - | ^^^^^^^^^ +LL | #[rustc::unknown] + | ^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(rustc_attrs)] to the crate attributes to enable -error: aborting due to previous error +error: macro `rustc::unknown` may not be used in attributes + --> $DIR/feature-gate-rustc-attrs.rs:8:1 + | +LL | #[rustc::unknown] + | ^^^^^^^^^^^^^^^^^ + +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/feature-gate-rustc-attrs.rs:13:12 + | +LL | #[unknown::rustc] + | ^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(rustc_attrs)] to the crate attributes to enable + +error: macro `unknown::rustc` may not be used in attributes + --> $DIR/feature-gate-rustc-attrs.rs:13:1 + | +LL | #[unknown::rustc] + | ^^^^^^^^^^^^^^^^^ + +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/feature-gate-rustc-attrs.rs:20:3 + | +LL | #[rustc_unknown] + | ^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(rustc_attrs)] to the crate attributes to enable + +error[E0658]: The attribute `rustc_unknown` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/feature-gate-rustc-attrs.rs:20:3 + | +LL | #[rustc_unknown] + | ^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error[E0658]: used by the test suite + --> $DIR/feature-gate-rustc-attrs.rs:18:1 + | +LL | #[rustc_dummy] + | ^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(rustc_attrs)] to the crate attributes to enable + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr index fe3c1e0afdd6b..03bf933cd084d 100644 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr @@ -4,7 +4,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [1, 2, ..] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -13,7 +13,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [1, .., 5] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -22,7 +22,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [.., 4, 5] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -31,7 +31,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [ xs.., 4, 5 ] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -40,7 +40,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [ 1, xs.., 5 ] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -49,7 +49,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [ 1, 2, xs.. ] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error: aborting due to 6 previous errors diff --git a/src/test/ui/generic/generic-param-attrs.rs b/src/test/ui/generic/generic-param-attrs.rs index 601d2a9e0a31f..6c628914f1f8d 100644 --- a/src/test/ui/generic/generic-param-attrs.rs +++ b/src/test/ui/generic/generic-param-attrs.rs @@ -1,44 +1,38 @@ // This test previously ensured that attributes on formals in generic parameter // lists are rejected without a feature gate. -// -// (We are prefixing all tested features with `rustc_`, to ensure that -// the attributes themselves won't be rejected by the compiler when -// using `rustc_attrs` feature. There is a separate compile-fail/ test -// ensuring that the attribute feature-gating works in this context.) // compile-pass #![feature(rustc_attrs)] -#![allow(dead_code)] - -struct StLt<#[rustc_lt_struct] 'a>(&'a u32); -struct StTy<#[rustc_ty_struct] I>(I); -enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B } -enum EnTy<#[rustc_ty_enum] J> { A(J), B } -trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } -trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); } -type TyLt<#[rustc_lt_type] 'd> = &'d u32; -type TyTy<#[rustc_ty_type] L> = (L, ); - -impl<#[rustc_lt_inherent] 'e> StLt<'e> { } -impl<#[rustc_ty_inherent] M> StTy { } -impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> { + +struct StLt<#[rustc_dummy] 'a>(&'a u32); +struct StTy<#[rustc_dummy] I>(I); +enum EnLt<#[rustc_dummy] 'b> { A(&'b u32), B } +enum EnTy<#[rustc_dummy] J> { A(J), B } +trait TrLt<#[rustc_dummy] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } +trait TrTy<#[rustc_dummy] K> { fn foo(&self, _: K); } +type TyLt<#[rustc_dummy] 'd> = &'d u32; +type TyTy<#[rustc_dummy] L> = (L, ); + +impl<#[rustc_dummy] 'e> StLt<'e> { } +impl<#[rustc_dummy] M> StTy { } +impl<#[rustc_dummy] 'f> TrLt<'f> for StLt<'f> { fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } } -impl<#[rustc_ty_impl_for] N> TrTy for StTy { +impl<#[rustc_dummy] N> TrTy for StTy { fn foo(&self, _: N) { } } -fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } -fn f_ty<#[rustc_ty_fn] O>(_: O) { } +fn f_lt<#[rustc_dummy] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } +fn f_ty<#[rustc_dummy] O>(_: O) { } impl StTy { - fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - fn m_ty<#[rustc_ty_meth] P>(_: P) { } + fn m_lt<#[rustc_dummy] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } + fn m_ty<#[rustc_dummy] P>(_: P) { } } fn hof_lt(_: Q) - where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 + where Q: for <#[rustc_dummy] 'i> Fn(&'i [u32]) -> &'i u32 {} fn main() {} diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs index ceb44ecf7f583..111078abb3700 100644 --- a/src/test/ui/issues/issue-10536.rs +++ b/src/test/ui/issues/issue-10536.rs @@ -11,13 +11,9 @@ macro_rules! foo{ pub fn main() { foo!(); - assert!({one! two()}); - //~^ ERROR macros that expand to items - //~| ERROR cannot find macro `one!` in this scope - //~| ERROR mismatched types + assert!({one! two()}); //~ ERROR expected open delimiter // regardless of whether nested macro_rules works, the following should at // least throw a conventional error. - assert!({one! two}); - //~^ ERROR expected `(` or `{`, found `}` + assert!({one! two}); //~ ERROR expected open delimiter } diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index 584cdf43a8f4b..73f948107f185 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -1,38 +1,14 @@ -error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-10536.rs:14:22 +error: expected open delimiter + --> $DIR/issue-10536.rs:14:19 | LL | assert!({one! two()}); - | ^^ -help: change the delimiters to curly braces - | -LL | assert!({one! two {}}); - | ^^ -help: add a semicolon - | -LL | assert!({one! two();}); - | ^ + | ^^^ expected open delimiter -error: expected `(` or `{`, found `}` - --> $DIR/issue-10536.rs:21:22 +error: expected open delimiter + --> $DIR/issue-10536.rs:18:19 | LL | assert!({one! two}); - | ^ expected `(` or `{` - -error: cannot find macro `one!` in this scope - --> $DIR/issue-10536.rs:14:14 - | -LL | assert!({one! two()}); - | ^^^ - -error[E0308]: mismatched types - --> $DIR/issue-10536.rs:14:13 - | -LL | assert!({one! two()}); - | ^^^^^^^^^^^^ expected bool, found () - | - = note: expected type `bool` - found type `()` + | ^^^ expected open delimiter -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs b/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs index 1245ce8583e29..fb50dce1af616 100644 --- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs +++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs @@ -1,10 +1,7 @@ -// compile-flags:-Zborrowck=mir -Zverbose - // Test that we can deduce when projections like `T::Item` outlive the // function body. Test that this does not imply that `T: 'a` holds. -#![allow(warnings)] -#![feature(rustc_attrs)] +// compile-flags:-Zborrowck=mir -Zverbose use std::cell::Cell; @@ -18,7 +15,6 @@ where f(&value, Cell::new(&n)); } -#[rustc_errors] fn generic1(value: T) { // No error here: twice(value, |value_ref, item| invoke1(item)); @@ -30,7 +26,6 @@ where { } -#[rustc_errors] fn generic2(value: T) { twice(value, |value_ref, item| invoke2(value_ref, item)); //~^ ERROR the parameter type `T` may not live long enough diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr index 9cdb78a10281c..9f0c60c1e1705 100644 --- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr +++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr @@ -1,5 +1,5 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/projection-implied-bounds.rs:35:18 + --> $DIR/projection-implied-bounds.rs:30:18 | LL | twice(value, |value_ref, item| invoke2(value_ref, item)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs index f61f54f80a78b..6a9ef3b5ce07f 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs +++ b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs @@ -4,9 +4,6 @@ // Test that we assume that universal types like `T` outlive the // function body. -#![allow(warnings)] -#![feature(rustc_attrs)] - use std::cell::Cell; fn twice(value: T, mut f: F) @@ -17,7 +14,6 @@ where f(Cell::new(&value)); } -#[rustc_errors] fn generic(value: T) { // No error here: twice(value, |r| invoke(r)); diff --git a/src/test/ui/object-lifetime/object-lifetime-default.stderr b/src/test/ui/object-lifetime/object-lifetime-default.stderr index 2642cdff2bf6a..f71c8cd0e0c39 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default.stderr @@ -1,20 +1,20 @@ -error: 'a,Ambiguous - --> $DIR/object-lifetime-default.rs:24:1 +error: BaseDefault + --> $DIR/object-lifetime-default.rs:6:1 | -LL | struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct A(T); + | ^^^^^^^^^^^^^^^ -error: 'a,'b - --> $DIR/object-lifetime-default.rs:21:1 +error: BaseDefault + --> $DIR/object-lifetime-default.rs:9:1 | -LL | struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct B<'a,T>(&'a (), T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: 'b - --> $DIR/object-lifetime-default.rs:18:1 +error: 'a + --> $DIR/object-lifetime-default.rs:12:1 | -LL | struct E<'a,'b:'a,T:'b>(&'a T, &'b T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct C<'a,T:'a>(&'a T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: Ambiguous --> $DIR/object-lifetime-default.rs:15:1 @@ -22,23 +22,23 @@ error: Ambiguous LL | struct D<'a,'b,T:'a+'b>(&'a T, &'b T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: 'a - --> $DIR/object-lifetime-default.rs:12:1 +error: 'b + --> $DIR/object-lifetime-default.rs:18:1 | -LL | struct C<'a,T:'a>(&'a T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct E<'a,'b:'a,T:'b>(&'a T, &'b T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: BaseDefault - --> $DIR/object-lifetime-default.rs:9:1 +error: 'a,'b + --> $DIR/object-lifetime-default.rs:21:1 | -LL | struct B<'a,T>(&'a (), T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: BaseDefault - --> $DIR/object-lifetime-default.rs:6:1 +error: 'a,Ambiguous + --> $DIR/object-lifetime-default.rs:24:1 | -LL | struct A(T); - | ^^^^^^^^^^^^^^^ +LL | struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 7 previous errors diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.rs b/src/test/ui/parser/macro-bad-delimiter-ident.rs index 987c955d1dc38..13dec95435be0 100644 --- a/src/test/ui/parser/macro-bad-delimiter-ident.rs +++ b/src/test/ui/parser/macro-bad-delimiter-ident.rs @@ -1,3 +1,3 @@ fn main() { - foo! bar < //~ ERROR expected `(` or `{`, found `<` + foo! bar < //~ ERROR expected open delimiter } diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.stderr b/src/test/ui/parser/macro-bad-delimiter-ident.stderr index 6a17d39e8bfec..e97839a4f4a52 100644 --- a/src/test/ui/parser/macro-bad-delimiter-ident.stderr +++ b/src/test/ui/parser/macro-bad-delimiter-ident.stderr @@ -1,8 +1,8 @@ -error: expected `(` or `{`, found `<` - --> $DIR/macro-bad-delimiter-ident.rs:2:14 +error: expected open delimiter + --> $DIR/macro-bad-delimiter-ident.rs:2:10 | LL | foo! bar < - | ^ expected `(` or `{` + | ^^^ expected open delimiter error: aborting due to previous error diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.rs b/src/test/ui/proc-macro/expand-to-unstable-2.rs index 4b4ba52ecd726..437ae93093470 100644 --- a/src/test/ui/proc-macro/expand-to-unstable-2.rs +++ b/src/test/ui/proc-macro/expand-to-unstable-2.rs @@ -1,12 +1,12 @@ // aux-build:derive-unstable-2.rs -#![allow(warnings)] - #[macro_use] extern crate derive_unstable_2; #[derive(Unstable)] -//~^ ERROR: reserved for internal compiler +//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler +//~| ERROR attribute `rustc_foo` is currently unknown to the compiler + struct A; fn main() { diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.stderr b/src/test/ui/proc-macro/expand-to-unstable-2.stderr index e2f51dd3d5dd2..803773db88e96 100644 --- a/src/test/ui/proc-macro/expand-to-unstable-2.stderr +++ b/src/test/ui/proc-macro/expand-to-unstable-2.stderr @@ -1,5 +1,5 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics - --> $DIR/expand-to-unstable-2.rs:8:10 +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/expand-to-unstable-2.rs:6:10 | LL | #[derive(Unstable)] | ^^^^^^^^ @@ -7,6 +7,15 @@ LL | #[derive(Unstable)] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(rustc_attrs)] to the crate attributes to enable -error: aborting due to previous error +error[E0658]: The attribute `rustc_foo` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/expand-to-unstable-2.rs:6:10 + | +LL | #[derive(Unstable)] + | ^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/reserved/reserved-attr-on-macro.rs b/src/test/ui/reserved/reserved-attr-on-macro.rs index 96c63ba4db8c9..cb535362266c0 100644 --- a/src/test/ui/reserved/reserved-attr-on-macro.rs +++ b/src/test/ui/reserved/reserved-attr-on-macro.rs @@ -1,5 +1,7 @@ #[rustc_attribute_should_be_reserved] -//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved +//~^ ERROR attribute `rustc_attribute_should_be_reserved` is currently unknown +//~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler + macro_rules! foo { () => (()); } diff --git a/src/test/ui/reserved/reserved-attr-on-macro.stderr b/src/test/ui/reserved/reserved-attr-on-macro.stderr index c8738d1ed3429..0c62c82017e18 100644 --- a/src/test/ui/reserved/reserved-attr-on-macro.stderr +++ b/src/test/ui/reserved/reserved-attr-on-macro.stderr @@ -1,4 +1,4 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler --> $DIR/reserved-attr-on-macro.rs:1:3 | LL | #[rustc_attribute_should_be_reserved] @@ -7,14 +7,23 @@ LL | #[rustc_attribute_should_be_reserved] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(rustc_attrs)] to the crate attributes to enable +error[E0658]: The attribute `rustc_attribute_should_be_reserved` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/reserved-attr-on-macro.rs:1:3 + | +LL | #[rustc_attribute_should_be_reserved] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(custom_attribute)] to the crate attributes to enable + error: cannot determine resolution for the macro `foo` - --> $DIR/reserved-attr-on-macro.rs:8:5 + --> $DIR/reserved-attr-on-macro.rs:10:5 | LL | foo!(); | ^^^ | = note: import resolution is stuck, try simplifying macro imports -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs index 13c6308b97e85..0e10131ce8d1f 100644 --- a/src/test/ui/suggestions/attribute-typos.rs +++ b/src/test/ui/suggestions/attribute-typos.rs @@ -1,13 +1,11 @@ -#[deprcated] //~ ERROR E0658 -fn foo() {} //~| HELP a built-in attribute with a similar name exists - //~| SUGGESTION deprecated - //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable +#[deprcated] //~ ERROR attribute `deprcated` is currently unknown +fn foo() {} -#[tests] //~ ERROR E0658 -fn bar() {} //~| HELP a built-in attribute with a similar name exists - //~| SUGGESTION test - //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable +#[tests] //~ ERROR attribute `tests` is currently unknown to the compiler +fn bar() {} -#[rustc_err] //~ ERROR E0658 -fn main() {} //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable - // don't suggest rustc attributes +#[rustc_err] +//~^ ERROR attribute `rustc_err` is currently unknown +//~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler + +fn main() {} diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr index 8367ff20aa408..958688b4d3906 100644 --- a/src/test/ui/suggestions/attribute-typos.stderr +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -1,5 +1,5 @@ -error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics - --> $DIR/attribute-typos.rs:11:3 +error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler + --> $DIR/attribute-typos.rs:7:3 | LL | #[rustc_err] | ^^^^^^^^^ @@ -7,8 +7,17 @@ LL | #[rustc_err] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(rustc_attrs)] to the crate attributes to enable +error[E0658]: The attribute `rustc_err` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/attribute-typos.rs:7:3 + | +LL | #[rustc_err] + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(custom_attribute)] to the crate attributes to enable + error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/attribute-typos.rs:6:3 + --> $DIR/attribute-typos.rs:4:3 | LL | #[tests] | ^^^^^ help: a built-in attribute with a similar name exists: `test` @@ -25,6 +34,6 @@ LL | #[deprcated] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/user-defined-macro-rules.rs b/src/test/ui/user-defined-macro-rules.rs index 31bfdd025d99d..09e071ec45420 100644 --- a/src/test/ui/user-defined-macro-rules.rs +++ b/src/test/ui/user-defined-macro-rules.rs @@ -1,5 +1,9 @@ -#![allow(unused_macros)] +// check-pass -macro_rules! macro_rules { () => {} } //~ ERROR user-defined macros may not be named `macro_rules` +macro_rules! macro_rules { () => { struct S; } } // OK -fn main() {} +macro_rules! {} // OK, calls the macro defined above + +fn main() { + let s = S; +} diff --git a/src/test/ui/user-defined-macro-rules.stderr b/src/test/ui/user-defined-macro-rules.stderr deleted file mode 100644 index 057515228e0d1..0000000000000 --- a/src/test/ui/user-defined-macro-rules.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: user-defined macros may not be named `macro_rules` - --> $DIR/user-defined-macro-rules.rs:3:1 - | -LL | macro_rules! macro_rules { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/tools/rls b/src/tools/rls index 597c9be8c75be..124483dd2f10f 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 597c9be8c75be3e664f189c4325c96cf9b464dc3 +Subproject commit 124483dd2f10fe3ba32f7f5b75f32224c77f9010