From: bors Date: Tue, 11 Jun 2019 23:29:20 +0000 (+0000) Subject: Auto merge of #61741 - Centril:rollup-fgro5kz, r=Centril X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=961a9d6e97a37ff1bb33578721dfa8687054c7b8;hp=5f3656ce9a2212fad872605b7a4ee103a155e9f3;p=rust.git Auto merge of #61741 - Centril:rollup-fgro5kz, r=Centril Rollup of 11 pull requests Successful merges: - #61518 (Add loops to doc list of things not stable in const fn) - #61526 (move some tests into subfolders) - #61550 (Windows 10 SDK is also required now.) - #61606 (Remove some legacy proc macro flavors) - #61652 (Mention slice patterns in array) - #61686 (librustc_errors: Add some more documentation) - #61698 (typeck: Fix const generic in repeat param ICE.) - #61707 (Azure: retry failed awscli installs) - #61715 (make sure make_ascii_lowercase actually leaves upper-case non-ASCII characters alone) - #61724 (core: use memcmp optimization for 128 bit integer slices) - #61726 (Use `for_each` in `Iterator::partition`) Failed merges: r? @ghost --- diff --git a/.azure-pipelines/steps/run.yml b/.azure-pipelines/steps/run.yml index a646b34fe7d..49bac629e72 100644 --- a/.azure-pipelines/steps/run.yml +++ b/.azure-pipelines/steps/run.yml @@ -74,8 +74,9 @@ steps: # images, etc. - bash: | set -e + source src/ci/shared.sh sudo apt-get install -y python3-setuptools - pip3 install awscli --upgrade --user + retry pip3 install awscli --upgrade --user echo "##vso[task.prependpath]$HOME/.local/bin" displayName: Install awscli (Linux) condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) diff --git a/README.md b/README.md index b522b161ecf..15d09f4aada 100644 --- a/README.md +++ b/README.md @@ -130,9 +130,9 @@ build. MSVC builds of Rust additionally require an installation of Visual Studio 2017 (or later) so `rustc` can use its linker. The simplest way is to get the -[Visual Studio Build Tools] and check the “C++ build tools” workload. +[Visual Studio], check the “C++ build tools” and “Windows 10 SDK” workload. -[Visual Studio Build Tools]: https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019 +[Visual Studio]: https://visualstudio.microsoft.com/downloads/ (If you're installing cmake yourself, be careful that “C++ CMake tools for Windows” doesn't get included under “Individual components”.) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index d0fdd79473e..30923c74145 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1495,13 +1495,13 @@ fn partition(self, mut f: F) -> (B, B) where let mut left: B = Default::default(); let mut right: B = Default::default(); - for x in self { + self.for_each(|x| { if f(&x) { left.extend(Some(x)) } else { right.extend(Some(x)) } - } + }); (left, right) } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 0e782bef39d..c9c73f4d66e 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -5420,7 +5420,7 @@ impl $traitname for $ty { } } impl_marker_for!(BytewiseEquality, - u8 i8 u16 i16 u32 i32 u64 i64 usize isize char bool); + u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 usize isize char bool); #[doc(hidden)] unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 8a128b0d5e7..34f2d8917ea 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -4000,11 +4000,11 @@ pub fn make_ascii_uppercase(&mut self) { /// # Examples /// /// ``` - /// let mut s = String::from("Grüße, Jürgen ❤"); + /// let mut s = String::from("GRÜßE, JÜRGEN ❤"); /// /// s.make_ascii_lowercase(); /// - /// assert_eq!("grüße, jürgen ❤", s); + /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_lowercase(&mut self) { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 6a03aa64d26..f4d523b9233 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -227,13 +227,17 @@ pub fn extension(&self) -> &'static str { } } +/// The type of diagnostics output to generate. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ErrorOutputType { + /// Output meant for the consumption of humans. HumanReadable(HumanReadableErrorType), + /// Output that's consumed by other tools such as `rustfix` or the `RLS`. Json { - /// Render the json in a human readable way (with indents and newlines) + /// Render the JSON in a human readable way (with indents and newlines). pretty: bool, - /// The way the `rendered` field is created + /// The JSON output includes a `rendered` field that includes the rendered + /// human output. json_rendered: HumanReadableErrorType, }, } diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 31f697a724a..fc74e43ff57 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -348,7 +348,7 @@ pub fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuild /// Convenience function for internal use, clients should use one of the /// struct_* methods on Handler. - pub fn new_with_code(handler: &'a Handler, + crate fn new_with_code(handler: &'a Handler, level: Level, code: Option, message: &str) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 3bf477efe35..fca8298409a 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1,3 +1,12 @@ +//! The current rustc diagnostics emitter. +//! +//! An `Emitter` takes care of generating the output from a `DiagnosticBuilder` struct. +//! +//! There are various `Emitter` implementations that generate different output formats such as +//! JSON and human readable output. +//! +//! The output types are defined in `librustc::session::config::ErrorOutputType`. + use Destination::*; use syntax_pos::{SourceFile, Span, MultiSpan}; diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 27bd30e8afd..05cee6dff23 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -1,5 +1,10 @@ +//! Diagnostics creation and emission for `rustc`. +//! +//! This module contains the code for creating and emitting diagnostics. + #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(crate_visibility_modifier)] #![allow(unused_attributes)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 991bebc647d..7ffba41e256 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -614,7 +614,7 @@ fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option, s match decl { ProcMacro::CustomDerive { trait_name, attributes, client } => { let attrs = attributes.iter().cloned().map(Symbol::intern).collect::>(); - (trait_name, SyntaxExtension::ProcMacroDerive( + (trait_name, SyntaxExtension::Derive( Box::new(ProcMacroDerive { client, attrs: attrs.clone(), @@ -624,13 +624,13 @@ fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option, s )) } ProcMacro::Attr { name, client } => { - (name, SyntaxExtension::AttrProcMacro( + (name, SyntaxExtension::Attr( Box::new(AttrProcMacro { client }), root.edition, )) } ProcMacro::Bang { name, client } => { - (name, SyntaxExtension::ProcMacro { + (name, SyntaxExtension::Bang { expander: Box::new(BangProcMacro { client }), allow_internal_unstable: None, edition: root.edition, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index db452bb4ac7..35faa1df82b 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -430,7 +430,7 @@ pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro { use syntax_ext::proc_macro_impl::BangProcMacro; let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); - let ext = SyntaxExtension::ProcMacro { + let ext = SyntaxExtension::Bang { expander: Box::new(BangProcMacro { client }), allow_internal_unstable: Some(vec![sym::proc_macro_def_site].into()), edition: data.root.edition, diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index f9667586456..7bafef79acd 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -299,7 +299,7 @@ fn check_terminator( TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } => Err(( span, - "`if`, `match`, `&&` and `||` are not stable in const fn".into(), + "loops and conditional expressions are not stable in const fn".into(), )), | TerminatorKind::Abort | TerminatorKind::Unreachable => { Err((span, "const fn with unreachable code is not stable".into())) diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 2ed6f868fa1..dd5e42684c4 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -4,8 +4,9 @@ use rustc::session::Session; use rustc::util::nodemap::FxHashMap; -use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT}; +use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension}; use syntax::ext::base::MacroExpanderFn; +use syntax::ext::hygiene::Transparency; use syntax::symbol::{Symbol, sym}; use syntax::ast; use syntax::feature_gate::AttributeType; @@ -84,47 +85,26 @@ pub fn args<'b>(&'b self) -> &'b [ast::NestedMetaItem] { /// Register a syntax extension of any kind. /// /// This is the most general hook into `libsyntax`'s expansion behavior. - pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { + 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`"); } - self.syntax_exts.push((name, match extension { - NormalTT { - expander, - def_info: _, - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, - } => { - let nid = ast::CRATE_NODE_ID; - NormalTT { - expander, - def_info: Some((nid, self.krate_span)), - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, - } - } - IdentTT { expander, span: _, allow_internal_unstable } => { - IdentTT { expander, span: Some(self.krate_span), allow_internal_unstable } - } - _ => extension, - })); + if let SyntaxExtension::LegacyBang { def_info: ref mut def_info @ None, .. } = extension { + *def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); + } + self.syntax_exts.push((name, extension)); } /// Register a macro of the usual kind. /// /// This is a convenience wrapper for `register_syntax_extension`. - /// It builds for you a `NormalTT` that calls `expander`, + /// It builds for you a `SyntaxExtension::LegacyBang` that calls `expander`, /// and also takes care of interning the macro's name. pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) { - self.register_syntax_extension(Symbol::intern(name), NormalTT { + self.register_syntax_extension(Symbol::intern(name), SyntaxExtension::LegacyBang { expander: Box::new(expander), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 08ab5b85325..2369bddf4f7 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -242,8 +242,7 @@ fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, invoc_id: Ma fn check_unused_macros(&self) { for did in self.unused_macros.iter() { let id_span = match *self.macro_map[did] { - SyntaxExtension::NormalTT { def_info, .. } | - SyntaxExtension::DeclMacro { def_info, .. } => def_info, + SyntaxExtension::LegacyBang { def_info, .. } => def_info, _ => None, }; if let Some((id, span)) = id_span { @@ -587,7 +586,7 @@ struct Flags: u8 { match self.resolve_macro_to_res(derive, MacroKind::Derive, &parent_scope, true, force) { Ok((_, ext)) => { - if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext { + if let SyntaxExtension::Derive(_, helpers, _) = &*ext { if helpers.contains(&ident.name) { let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 63d9f0920cc..5a46c9d440b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2155,6 +2155,17 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> { result_ty } + /// Returns the `DefId` of the constant parameter that the provided expression is a path to. + pub fn const_param_def_id(&self, expr: &hir::Expr) -> Option { + match &expr.node { + ExprKind::Path(hir::QPath::Resolved(_, path)) => match path.res { + Res::Def(DefKind::ConstParam, did) => Some(did), + _ => None, + }, + _ => None, + } + } + pub fn ast_const_to_const( &self, ast_const: &hir::AnonConst, @@ -2185,19 +2196,17 @@ pub fn ast_const_to_const( } } - if let ExprKind::Path(ref qpath) = expr.node { - if let hir::QPath::Resolved(_, ref path) = qpath { - if let Res::Def(DefKind::ConstParam, def_id) = path.res { - let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); - let item_id = tcx.hir().get_parent_node(node_id); - let item_def_id = tcx.hir().local_def_id(item_id); - let generics = tcx.generics_of(item_def_id); - let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)]; - let name = tcx.hir().name(node_id).as_interned_str(); - const_.val = ConstValue::Param(ty::ParamConst::new(index, name)); - } - } - }; + if let Some(def_id) = self.const_param_def_id(expr) { + // Find the name and index of the const parameter by indexing the generics of the + // parent item and construct a `ParamConst`. + let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); + let item_id = tcx.hir().get_parent_node(node_id); + let item_def_id = tcx.hir().local_def_id(item_id); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)]; + let name = tcx.hir().name(node_id).as_interned_str(); + const_.val = ConstValue::Param(ty::ParamConst::new(index, name)); + } tcx.mk_const(const_) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2e53b380cb7..e35df6cd494 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2504,6 +2504,11 @@ pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> { ty } + /// Returns the `DefId` of the constant parameter that the provided expression is a path to. + pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option { + AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value) + } + pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { AstConv::ast_const_to_const(self, ast_c, ty) } @@ -4479,19 +4484,24 @@ fn check_expr_kind( } ExprKind::Repeat(ref element, ref count) => { let count_def_id = tcx.hir().local_def_id_from_hir_id(count.hir_id); - let param_env = ty::ParamEnv::empty(); - let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id); - let instance = ty::Instance::resolve( - tcx.global_tcx(), - param_env, - count_def_id, - substs, - ).unwrap(); - let global_id = GlobalId { - instance, - promoted: None + let count = if self.const_param_def_id(count).is_some() { + Ok(self.to_const(count, self.tcx.type_of(count_def_id))) + } else { + let param_env = ty::ParamEnv::empty(); + let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id); + let instance = ty::Instance::resolve( + tcx.global_tcx(), + param_env, + count_def_id, + substs, + ).unwrap(); + let global_id = GlobalId { + instance, + promoted: None + }; + + tcx.const_eval(param_env.and(global_id)) }; - let count = tcx.const_eval(param_env.and(global_id)); let uty = match expected { ExpectHasType(uty) => { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 15108a7dbb9..5a5540e7e38 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -471,7 +471,7 @@ fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemE } LoadedMacro::ProcMacro(ext) => { let helpers = match &*ext { - &SyntaxExtension::ProcMacroDerive(_, ref syms, ..) => { syms.clean(cx) } + &SyntaxExtension::Derive(_, ref syms, ..) => { syms.clean(cx) } _ => Vec::new(), }; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 860ea18a58a..7fbfc3e1fc0 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -433,7 +433,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { if let Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) = res { // skip proc-macro stubs, they'll cause `get_macro` to crash } else { - if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(res) { + if let SyntaxExtension::LegacyBang { .. } = *resolver.get_macro(res) { return Some(res.map_id(|_| panic!("unexpected id"))); } } diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 42b64d2b5a5..e78a5defdf3 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -482,8 +482,8 @@ mod prim_pointer { } /// an array. Indeed, this provides most of the API for working with arrays. /// Slices have a dynamic size and do not coerce to arrays. /// -/// There is no way to move elements out of an array. See [`mem::replace`][replace] -/// for an alternative. +/// You can move elements out of an array with a slice pattern. If you want +/// one element, see [`mem::replace`][replace]. /// /// # Examples /// @@ -525,6 +525,16 @@ mod prim_pointer { } /// for x in &array { } /// ``` /// +/// You can use a slice pattern to move elements out of an array: +/// +/// ``` +/// fn move_away(_: String) { /* Do interesting things. */ } +/// +/// let [john, roa] = ["John".to_string(), "Roa".to_string()]; +/// move_away(john); +/// move_away(roa); +/// ``` +/// /// [slice]: primitive.slice.html /// [copy]: marker/trait.Copy.html /// [clone]: clone/trait.Clone.html diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 61c736662c7..38b7dee40c4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,6 +1,4 @@ -pub use SyntaxExtension::*; - -use crate::ast::{self, Attribute, Name, PatKind, MetaItem}; +use crate::ast::{self, Attribute, Name, PatKind}; use crate::attr::HasAttrs; use crate::source_map::{SourceMap, Spanned, respan}; use crate::edition::Edition; @@ -137,29 +135,6 @@ pub fn derive_allowed(&self) -> bool { } } -// A more flexible ItemDecorator. -pub trait MultiItemDecorator { - fn expand(&self, - ecx: &mut ExtCtxt<'_>, - sp: Span, - meta_item: &ast::MetaItem, - item: &Annotatable, - push: &mut dyn FnMut(Annotatable)); -} - -impl MultiItemDecorator for F - where F : Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)) -{ - fn expand(&self, - ecx: &mut ExtCtxt<'_>, - sp: Span, - meta_item: &ast::MetaItem, - item: &Annotatable, - push: &mut dyn FnMut(Annotatable)) { - (*self)(ecx, sp, meta_item, item, push) - } -} - // `meta_item` is the annotation, and `item` is the item being modified. // FIXME Decorators should follow the same pattern too. pub trait MultiItemModifier { @@ -288,34 +263,6 @@ fn visit_mac(&mut self, mac: &mut ast::Mac) { } } -pub trait IdentMacroExpander { - fn expand<'cx>(&self, - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - ident: ast::Ident, - token_tree: Vec) - -> Box; -} - -pub type IdentMacroExpanderFn = - for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, Vec) - -> Box; - -impl IdentMacroExpander for F - where F : for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, - Vec) -> Box -{ - fn expand<'cx>(&self, - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - ident: ast::Ident, - token_tree: Vec) - -> Box - { - (*self)(cx, sp, ident, token_tree) - } -} - // Use a macro because forwarding to a simple function has type system issues macro_rules! make_stmts_default { ($me:expr) => { @@ -570,9 +517,6 @@ fn make_ty(self: Box) -> Option> { } } -pub type BuiltinDeriveFn = - for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)); - /// Represents different kinds of macro invocations that can be resolved. #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum MacroKind { @@ -606,129 +550,116 @@ pub fn article(self) -> &'static str { /// An enum representing the different kinds of syntax extensions. pub enum SyntaxExtension { - /// A trivial "extension" that does nothing, only keeps the attribute and marks it as known. - NonMacroAttr { mark_used: bool }, - - /// A syntax extension that is attached to an item and creates new items - /// based upon it. - /// - /// `#[derive(...)]` is a `MultiItemDecorator`. - /// - /// Prefer ProcMacro or MultiModifier since they are more flexible. - MultiDecorator(Box), - - /// A syntax extension that is attached to an item and modifies it - /// in-place. Also allows decoration, i.e., creating new items. - MultiModifier(Box), - - /// A function-like procedural macro. TokenStream -> TokenStream. - ProcMacro { + /// A token-based function-like macro. + Bang { + /// An expander with signature TokenStream -> TokenStream. expander: Box, - /// Whitelist of unstable features that are treated as stable inside this macro + /// Whitelist of unstable features that are treated as stable inside this macro. allow_internal_unstable: Option>, + /// Edition of the crate in which this macro is defined. edition: Edition, }, - /// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream. - /// The first TokenSteam is the attribute, the second is the annotated item. - /// Allows modification of the input items and adding new items, similar to - /// MultiModifier, but uses TokenStreams, rather than AST nodes. - AttrProcMacro(Box, Edition), - - /// A normal, function-like syntax extension. - /// - /// `bytes!` is a `NormalTT`. - NormalTT { + /// An AST-based function-like macro. + LegacyBang { + /// An expander with signature TokenStream -> AST. expander: Box, + /// Some info about the macro's definition point. def_info: Option<(ast::NodeId, Span)>, - /// Whether the contents of the macro can - /// directly use `#[unstable]` things. - /// - /// Only allows things that require a feature gate in the given whitelist + /// Hygienic properties of identifiers produced by this macro. + transparency: Transparency, + /// Whitelist of unstable features that are treated as stable inside this macro. allow_internal_unstable: Option>, - /// Whether the contents of the macro can use `unsafe` - /// without triggering the `unsafe_code` lint. + /// Suppresses the `unsafe_code` lint for code produced by this macro. allow_internal_unsafe: bool, - /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) - /// for a given macro. + /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. local_inner_macros: bool, - /// The macro's feature name if it is unstable, and the stability feature + /// The macro's feature name and tracking issue number if it is unstable. unstable_feature: Option<(Symbol, u32)>, - /// Edition of the crate in which the macro is defined + /// Edition of the crate in which this macro is defined. edition: Edition, }, - /// A function-like syntax extension that has an extra ident before - /// the block. - IdentTT { - expander: Box, - span: Option, - allow_internal_unstable: Option>, + /// A token-based attribute macro. + Attr( + /// An expander with signature (TokenStream, TokenStream) -> TokenStream. + /// The first TokenSteam is the attribute itself, the second is the annotated item. + /// The produced TokenSteam replaces the input TokenSteam. + Box, + /// Edition of the crate in which this macro is defined. + Edition, + ), + + /// An AST-based attribute macro. + LegacyAttr( + /// An expander with signature (AST, AST) -> AST. + /// The first AST fragment is the attribute itself, the second is the annotated item. + /// The produced AST fragment replaces the input AST fragment. + Box, + ), + + /// A trivial attribute "macro" that does nothing, + /// only keeps the attribute and marks it as known. + NonMacroAttr { + /// Suppresses the `unused_attributes` lint for this attribute. + mark_used: bool, }, - /// An attribute-like procedural macro. TokenStream -> TokenStream. - /// The input is the annotated item. - /// Allows generating code to implement a Trait for a given struct - /// or enum item. - ProcMacroDerive(Box, - Vec /* inert attribute names */, Edition), - - /// An attribute-like procedural macro that derives a builtin trait. - BuiltinDerive(BuiltinDeriveFn), - - /// A declarative macro, e.g., `macro m() {}`. - DeclMacro { - expander: Box, - def_info: Option<(ast::NodeId, Span)>, - is_transparent: bool, - edition: Edition, - } + /// A token-based derive macro. + Derive( + /// An expander with signature TokenStream -> TokenStream (not yet). + /// The produced TokenSteam is appended to the input TokenSteam. + Box, + /// Names of helper attributes registered by this macro. + Vec, + /// Edition of the crate in which this macro is defined. + Edition, + ), + + /// An AST-based derive macro. + LegacyDerive( + /// An expander with signature AST -> AST. + /// The produced AST fragment is appended to the input AST fragment. + Box, + ), } impl SyntaxExtension { /// Returns which kind of macro calls this syntax extension. pub fn kind(&self) -> MacroKind { match *self { - SyntaxExtension::DeclMacro { .. } | - SyntaxExtension::NormalTT { .. } | - SyntaxExtension::IdentTT { .. } | - SyntaxExtension::ProcMacro { .. } => - MacroKind::Bang, - SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::MultiDecorator(..) | - SyntaxExtension::MultiModifier(..) | - SyntaxExtension::AttrProcMacro(..) => - MacroKind::Attr, - SyntaxExtension::ProcMacroDerive(..) | - SyntaxExtension::BuiltinDerive(..) => - MacroKind::Derive, + SyntaxExtension::Bang { .. } | + SyntaxExtension::LegacyBang { .. } => MacroKind::Bang, + SyntaxExtension::Attr(..) | + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::NonMacroAttr { .. } => MacroKind::Attr, + SyntaxExtension::Derive(..) | + SyntaxExtension::LegacyDerive(..) => MacroKind::Derive, } } pub fn default_transparency(&self) -> Transparency { match *self { - SyntaxExtension::ProcMacro { .. } | - SyntaxExtension::AttrProcMacro(..) | - SyntaxExtension::ProcMacroDerive(..) | - SyntaxExtension::DeclMacro { is_transparent: false, .. } => Transparency::Opaque, - SyntaxExtension::DeclMacro { is_transparent: true, .. } => Transparency::Transparent, - _ => Transparency::SemiTransparent, + SyntaxExtension::LegacyBang { transparency, .. } => transparency, + SyntaxExtension::Bang { .. } | + SyntaxExtension::Attr(..) | + SyntaxExtension::Derive(..) | + SyntaxExtension::NonMacroAttr { .. } => Transparency::Opaque, + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::LegacyDerive(..) => Transparency::SemiTransparent, } } pub fn edition(&self, default_edition: Edition) -> Edition { match *self { - SyntaxExtension::NormalTT { edition, .. } | - SyntaxExtension::DeclMacro { edition, .. } | - SyntaxExtension::ProcMacro { edition, .. } | - SyntaxExtension::AttrProcMacro(.., edition) | - SyntaxExtension::ProcMacroDerive(.., edition) => edition, + SyntaxExtension::Bang { edition, .. } | + SyntaxExtension::LegacyBang { edition, .. } | + SyntaxExtension::Attr(.., edition) | + SyntaxExtension::Derive(.., edition) => edition, // Unstable legacy stuff SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::IdentTT { .. } | - SyntaxExtension::MultiDecorator(..) | - SyntaxExtension::MultiModifier(..) | - SyntaxExtension::BuiltinDerive(..) => default_edition, + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::LegacyDerive(..) => default_edition, } } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 99605395553..084d4fd3820 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -389,7 +389,7 @@ fn expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment { let item = match self.cx.resolver.resolve_macro_path( path, MacroKind::Derive, Mark::root(), Vec::new(), false) { Ok(ext) => match *ext { - BuiltinDerive(..) => item_with_markers.clone(), + SyntaxExtension::LegacyDerive(..) => item_with_markers.clone(), _ => item.clone(), }, _ => item.clone(), @@ -548,7 +548,7 @@ fn expand_attr_invoc(&mut self, _ => unreachable!(), }; - if let NonMacroAttr { mark_used: false } = *ext {} else { + if let SyntaxExtension::NonMacroAttr { mark_used: false } = *ext {} else { // Macro attrs are always used when expanded, // non-macro attrs are considered used when the field says so. attr::mark_used(&attr); @@ -564,26 +564,18 @@ fn expand_attr_invoc(&mut self, }); match *ext { - NonMacroAttr { .. } => { + SyntaxExtension::NonMacroAttr { .. } => { attr::mark_known(&attr); item.visit_attrs(|attrs| attrs.push(attr)); Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item))) } - MultiModifier(ref mac) => { + SyntaxExtension::LegacyAttr(ref mac) => { let meta = attr.parse_meta(self.cx.parse_sess) .map_err(|mut e| { e.emit(); }).ok()?; let item = mac.expand(self.cx, attr.span, &meta, item); Some(invoc.fragment_kind.expect_from_annotatables(item)) } - MultiDecorator(ref mac) => { - let mut items = Vec::new(); - let meta = attr.parse_meta(self.cx.parse_sess) - .expect("derive meta should already have been parsed"); - mac.expand(self.cx, attr.span, &meta, &item, &mut |item| items.push(item)); - items.push(item); - Some(invoc.fragment_kind.expect_from_annotatables(items)) - } - AttrProcMacro(ref mac, ..) => { + SyntaxExtension::Attr(ref mac, ..) => { self.gate_proc_macro_attr_item(attr.span, &item); let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { Annotatable::Item(item) => token::NtItem(item), @@ -600,7 +592,7 @@ fn expand_attr_invoc(&mut self, self.gate_proc_macro_expansion(attr.span, &res); res } - ProcMacroDerive(..) | BuiltinDerive(..) => { + SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => { self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path)); self.cx.trace_macros_diag(); invoc.fragment_kind.dummy(attr.span) @@ -755,17 +747,7 @@ fn expand_bang_invoc(&mut self, }; let opt_expanded = match *ext { - DeclMacro { ref expander, def_info, edition, .. } => { - if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), - None, false, false, None, - edition) { - dummy_span - } else { - kind.make_from(expander.expand(self.cx, span, mac.node.stream(), None)) - } - } - - NormalTT { + SyntaxExtension::LegacyBang { ref expander, def_info, ref allow_internal_unstable, @@ -773,6 +755,7 @@ fn expand_bang_invoc(&mut self, local_inner_macros, unstable_feature, edition, + .. } => { if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), allow_internal_unstable.clone(), @@ -791,43 +774,22 @@ fn expand_bang_invoc(&mut self, } } - IdentTT { ref expander, span: tt_span, ref allow_internal_unstable } => { - if ident.name == kw::Invalid { - self.cx.span_err(path.span, - &format!("macro {}! expects an ident argument", path)); - self.cx.trace_macros_diag(); - kind.dummy(span) - } else { - invoc.expansion_data.mark.set_expn_info(ExpnInfo { - call_site: span, - def_site: tt_span, - format: macro_bang_format(path), - allow_internal_unstable: allow_internal_unstable.clone(), - allow_internal_unsafe: false, - local_inner_macros: false, - edition: self.cx.parse_sess.edition, - }); - - let input: Vec<_> = mac.node.stream().into_trees().collect(); - kind.make_from(expander.expand(self.cx, span, ident, input)) - } - } - - MultiDecorator(..) | MultiModifier(..) | - AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => { + SyntaxExtension::Attr(..) | + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::NonMacroAttr { .. } => { self.cx.span_err(path.span, &format!("`{}` can only be used in attributes", path)); self.cx.trace_macros_diag(); kind.dummy(span) } - ProcMacroDerive(..) | BuiltinDerive(..) => { + SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => { self.cx.span_err(path.span, &format!("`{}` is a derive macro", path)); self.cx.trace_macros_diag(); kind.dummy(span) } - SyntaxExtension::ProcMacro { ref expander, ref allow_internal_unstable, edition } => { + SyntaxExtension::Bang { ref expander, ref allow_internal_unstable, edition } => { if ident.name != kw::Invalid { let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); @@ -924,29 +886,29 @@ fn expand_derive_invoc(&mut self, edition: ext.edition(self.cx.parse_sess.edition), }; - match *ext { - ProcMacroDerive(ref ext, ..) => { - invoc.expansion_data.mark.set_expn_info(expn_info); - let span = span.with_ctxt(self.cx.backtrace()); - let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this - path: Path::from_ident(Ident::invalid()), - span: DUMMY_SP, - node: ast::MetaItemKind::Word, + match ext { + SyntaxExtension::Derive(expander, ..) | SyntaxExtension::LegacyDerive(expander) => { + let meta = match ext { + SyntaxExtension::Derive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this + path: Path::from_ident(Ident::invalid()), + span: DUMMY_SP, + node: ast::MetaItemKind::Word, + }, + _ => { + expn_info.allow_internal_unstable = Some(vec![ + sym::rustc_attrs, + Symbol::intern("derive_clone_copy"), + Symbol::intern("derive_eq"), + // RustcDeserialize and RustcSerialize + Symbol::intern("libstd_sys_internals"), + ].into()); + attr.meta()? + } }; - let items = ext.expand(self.cx, span, &dummy, item); - Some(invoc.fragment_kind.expect_from_annotatables(items)) - } - BuiltinDerive(func) => { - expn_info.allow_internal_unstable = Some(vec![ - sym::rustc_attrs, - Symbol::intern("derive_clone_copy"), - Symbol::intern("derive_eq"), - Symbol::intern("libstd_sys_internals"), // RustcDeserialize and RustcSerialize - ].into()); + invoc.expansion_data.mark.set_expn_info(expn_info); let span = span.with_ctxt(self.cx.backtrace()); - let mut items = Vec::new(); - func(self.cx, span, &attr.meta()?, &item, &mut |a| items.push(a)); + let items = expander.expand(self.cx, span, &meta, item); Some(invoc.fragment_kind.expect_from_annotatables(items)) } _ => { diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 6f82f509465..5dbf21867af 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -1,8 +1,8 @@ use crate::{ast, attr}; use crate::edition::Edition; -use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension}; -use crate::ext::base::{NormalTT, TTMacroExpander}; +use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension, TTMacroExpander}; use crate::ext::expand::{AstFragment, AstFragmentKind}; +use crate::ext::hygiene::Transparency; use crate::ext::tt::macro_parser::{Success, Error, Failure}; use crate::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; use crate::ext::tt::macro_parser::{parse, parse_failure_msg}; @@ -374,65 +374,65 @@ pub fn compile( valid, }); - if body.legacy { - let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable) - .map(|attr| attr - .meta_item_list() - .map(|list| list.iter() - .filter_map(|it| { - let name = it.ident().map(|ident| ident.name); - if name.is_none() { - sess.span_diagnostic.span_err(it.span(), - "allow internal unstable expects feature names") - } - name - }) - .collect::>().into() - ) - .unwrap_or_else(|| { - sess.span_diagnostic.span_warn( - attr.span, "allow_internal_unstable expects list of feature names. In the \ - future this will become a hard error. Please use `allow_internal_unstable(\ - foo, bar)` to only allow the `foo` and `bar` features", - ); - vec![sym::allow_internal_unstable_backcompat_hack].into() + let transparency = if attr::contains_name(&def.attrs, sym::rustc_transparent_macro) { + Transparency::Transparent + } else if body.legacy { + Transparency::SemiTransparent + } else { + Transparency::Opaque + }; + + let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable) + .map(|attr| attr + .meta_item_list() + .map(|list| list.iter() + .filter_map(|it| { + let name = it.ident().map(|ident| ident.name); + if name.is_none() { + sess.span_diagnostic.span_err(it.span(), + "allow internal unstable expects feature names") + } + name }) - ); - let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); - let mut local_inner_macros = false; - if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { - if let Some(l) = macro_export.meta_item_list() { - local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); - } - } + .collect::>().into() + ) + .unwrap_or_else(|| { + sess.span_diagnostic.span_warn( + attr.span, "allow_internal_unstable expects list of feature names. In the \ + future this will become a hard error. Please use `allow_internal_unstable(\ + foo, bar)` to only allow the `foo` and `bar` features", + ); + vec![sym::allow_internal_unstable_backcompat_hack].into() + }) + ); - let unstable_feature = attr::find_stability(&sess, - &def.attrs, def.span).and_then(|stability| { - if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { - Some((stability.feature, issue)) - } else { - None - } - }); - - NormalTT { - expander, - def_info: Some((def.id, def.span)), - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, + let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); + + let mut local_inner_macros = false; + if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { + if let Some(l) = macro_export.meta_item_list() { + local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); } - } else { - let is_transparent = attr::contains_name(&def.attrs, sym::rustc_transparent_macro); + } - SyntaxExtension::DeclMacro { - expander, - def_info: Some((def.id, def.span)), - is_transparent, - edition, + let unstable_feature = attr::find_stability(&sess, + &def.attrs, def.span).and_then(|stability| { + if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { + Some((stability.feature, issue)) + } else { + None } + }); + + SyntaxExtension::LegacyBang { + expander, + def_info: Some((def.id, def.span)), + transparency, + allow_internal_unstable, + allow_internal_unsafe, + local_inner_macros, + unstable_feature, + edition, } } diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index ac41f30e6b3..cf54eacc3d4 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -1,8 +1,8 @@ //! The compiler code necessary to implement the `#[derive]` extensions. use rustc_data_structures::sync::Lrc; -use syntax::ast; -use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver}; +use syntax::ast::{self, MetaItem}; +use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver, MultiItemModifier}; use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::ptr::P; @@ -39,9 +39,25 @@ #[path="cmp/ord.rs"] pub mod ord; - pub mod generic; +struct BuiltinDerive( + fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)) +); + +impl MultiItemModifier for BuiltinDerive { + fn expand(&self, + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &MetaItem, + item: Annotatable) + -> Vec { + let mut items = Vec::new(); + (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a)); + items + } +} + macro_rules! derive_traits { ($( $name:expr => $func:path, )+) => { pub fn is_builtin_trait(name: ast::Name) -> bool { @@ -55,7 +71,7 @@ pub fn register_builtin_derives(resolver: &mut dyn Resolver) { $( resolver.add_builtin( ast::Ident::with_empty_ctxt(Symbol::intern($name)), - Lrc::new(SyntaxExtension::BuiltinDerive($func)) + Lrc::new(SyntaxExtension::LegacyDerive(Box::new(BuiltinDerive($func)))) ); )* } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 1627f99f616..3dd17207cb8 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -42,7 +42,9 @@ use rustc_data_structures::sync::Lrc; use syntax::ast; -use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier}; + +use syntax::ext::base::{MacroExpanderFn, NamedSyntaxExtension, SyntaxExtension}; +use syntax::ext::hygiene::Transparency; use syntax::edition::Edition; use syntax::symbol::{sym, Symbol}; @@ -57,9 +59,10 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, macro_rules! register { ($( $name:ident: $f:expr, )*) => { $( register(Symbol::intern(stringify!($name)), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new($f as MacroExpanderFn), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, @@ -94,15 +97,16 @@ macro_rules! register { assert: assert::expand_assert, } - register(sym::test_case, MultiModifier(Box::new(test_case::expand))); - register(sym::test, MultiModifier(Box::new(test::expand_test))); - register(sym::bench, MultiModifier(Box::new(test::expand_bench))); + register(sym::test_case, SyntaxExtension::LegacyAttr(Box::new(test_case::expand))); + register(sym::test, SyntaxExtension::LegacyAttr(Box::new(test::expand_test))); + register(sym::bench, SyntaxExtension::LegacyAttr(Box::new(test::expand_bench))); // format_args uses `unstable` things internally. register(Symbol::intern("format_args"), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(format::expand_format_args), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: Some(vec![sym::fmt_internals].into()), allow_internal_unsafe: false, local_inner_macros: false, @@ -110,9 +114,10 @@ macro_rules! register { edition, }); register(sym::format_args_nl, - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(format::expand_format_args_nl), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: Some(vec![sym::fmt_internals].into()), allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/test/codegen/exact_div.rs b/src/test/codegen/exact_div.rs deleted file mode 100644 index 6a55b492cb1..00000000000 --- a/src/test/codegen/exact_div.rs +++ /dev/null @@ -1,20 +0,0 @@ -// compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] -#![feature(core_intrinsics)] - -use std::intrinsics::exact_div; - -// CHECK-LABEL: @exact_sdiv -#[no_mangle] -pub unsafe fn exact_sdiv(x: i32, y: i32) -> i32 { -// CHECK: sdiv exact - exact_div(x, y) -} - -// CHECK-LABEL: @exact_udiv -#[no_mangle] -pub unsafe fn exact_udiv(x: u32, y: u32) -> u32 { -// CHECK: udiv exact - exact_div(x, y) -} diff --git a/src/test/codegen/intrinsics/exact_div.rs b/src/test/codegen/intrinsics/exact_div.rs new file mode 100644 index 00000000000..68eaa39997a --- /dev/null +++ b/src/test/codegen/intrinsics/exact_div.rs @@ -0,0 +1,20 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::exact_div; + +// CHECK-LABEL: @exact_sdiv +#[no_mangle] +pub unsafe fn exact_sdiv(x: i32, y: i32) -> i32 { + // CHECK: sdiv exact + exact_div(x, y) +} + +// CHECK-LABEL: @exact_udiv +#[no_mangle] +pub unsafe fn exact_udiv(x: u32, y: u32) -> u32 { + // CHECK: udiv exact + exact_div(x, y) +} diff --git a/src/test/codegen/intrinsics/likely.rs b/src/test/codegen/intrinsics/likely.rs new file mode 100644 index 00000000000..c5a0185bd48 --- /dev/null +++ b/src/test/codegen/intrinsics/likely.rs @@ -0,0 +1,30 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::{likely,unlikely}; + +#[no_mangle] +pub fn check_likely(x: i32, y: i32) -> Option { + unsafe { + // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 true) + if likely(x == y) { + None + } else { + Some(x + y) + } + } +} + +#[no_mangle] +pub fn check_unlikely(x: i32, y: i32) -> Option { + unsafe { + // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false) + if unlikely(x == y) { + None + } else { + Some(x + y) + } + } +} diff --git a/src/test/codegen/intrinsics/move-val-init.rs b/src/test/codegen/intrinsics/move-val-init.rs new file mode 100644 index 00000000000..6222536b506 --- /dev/null +++ b/src/test/codegen/intrinsics/move-val-init.rs @@ -0,0 +1,19 @@ +// compile-flags: -C no-prepopulate-passes + +#![feature(core_intrinsics)] +#![crate_type = "lib"] + +// test that `move_val_init` actually avoids big allocas + +use std::intrinsics::move_val_init; + +pub struct Big { + pub data: [u8; 65536] +} + +// CHECK-LABEL: @test_mvi +#[no_mangle] +pub unsafe fn test_mvi(target: *mut Big, make_big: fn() -> Big) { + // CHECK: call void %make_big(%Big*{{[^%]*}} %target) + move_val_init(target, make_big()); +} diff --git a/src/test/codegen/intrinsics/nontemporal.rs b/src/test/codegen/intrinsics/nontemporal.rs new file mode 100644 index 00000000000..3a41fb4fab3 --- /dev/null +++ b/src/test/codegen/intrinsics/nontemporal.rs @@ -0,0 +1,13 @@ +// compile-flags: -O + +#![feature(core_intrinsics)] +#![crate_type = "lib"] + +#[no_mangle] +pub fn a(a: &mut u32, b: u32) { + // CHECK-LABEL: define void @a + // CHECK: store i32 %b, i32* %a, align 4, !nontemporal + unsafe { + std::intrinsics::nontemporal_store(a, b); + } +} diff --git a/src/test/codegen/intrinsics/prefetch.rs b/src/test/codegen/intrinsics/prefetch.rs new file mode 100644 index 00000000000..4cd38e14282 --- /dev/null +++ b/src/test/codegen/intrinsics/prefetch.rs @@ -0,0 +1,63 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::{prefetch_read_data, prefetch_write_data, + prefetch_read_instruction, prefetch_write_instruction}; + +#[no_mangle] +pub fn check_prefetch_read_data(data: &[i8]) { + unsafe { + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 1) + prefetch_read_data(data.as_ptr(), 0); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 1) + prefetch_read_data(data.as_ptr(), 1); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 1) + prefetch_read_data(data.as_ptr(), 2); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 1) + prefetch_read_data(data.as_ptr(), 3); + } +} + +#[no_mangle] +pub fn check_prefetch_write_data(data: &[i8]) { + unsafe { + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 1) + prefetch_write_data(data.as_ptr(), 0); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 1) + prefetch_write_data(data.as_ptr(), 1); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 1) + prefetch_write_data(data.as_ptr(), 2); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 1) + prefetch_write_data(data.as_ptr(), 3); + } +} + +#[no_mangle] +pub fn check_prefetch_read_instruction(data: &[i8]) { + unsafe { + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 0) + prefetch_read_instruction(data.as_ptr(), 0); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 0) + prefetch_read_instruction(data.as_ptr(), 1); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 0) + prefetch_read_instruction(data.as_ptr(), 2); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 0) + prefetch_read_instruction(data.as_ptr(), 3); + } +} + +#[no_mangle] +pub fn check_prefetch_write_instruction(data: &[i8]) { + unsafe { + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 0) + prefetch_write_instruction(data.as_ptr(), 0); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 0) + prefetch_write_instruction(data.as_ptr(), 1); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 0) + prefetch_write_instruction(data.as_ptr(), 2); + // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 0) + prefetch_write_instruction(data.as_ptr(), 3); + } +} diff --git a/src/test/codegen/intrinsics/unchecked_math.rs b/src/test/codegen/intrinsics/unchecked_math.rs new file mode 100644 index 00000000000..419c120ede9 --- /dev/null +++ b/src/test/codegen/intrinsics/unchecked_math.rs @@ -0,0 +1,46 @@ +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::*; + +// CHECK-LABEL: @unchecked_add_signed +#[no_mangle] +pub unsafe fn unchecked_add_signed(a: i32, b: i32) -> i32 { + // CHECK: add nsw + unchecked_add(a, b) +} + +// CHECK-LABEL: @unchecked_add_unsigned +#[no_mangle] +pub unsafe fn unchecked_add_unsigned(a: u32, b: u32) -> u32 { + // CHECK: add nuw + unchecked_add(a, b) +} + +// CHECK-LABEL: @unchecked_sub_signed +#[no_mangle] +pub unsafe fn unchecked_sub_signed(a: i32, b: i32) -> i32 { + // CHECK: sub nsw + unchecked_sub(a, b) +} + +// CHECK-LABEL: @unchecked_sub_unsigned +#[no_mangle] +pub unsafe fn unchecked_sub_unsigned(a: u32, b: u32) -> u32 { + // CHECK: sub nuw + unchecked_sub(a, b) +} + +// CHECK-LABEL: @unchecked_mul_signed +#[no_mangle] +pub unsafe fn unchecked_mul_signed(a: i32, b: i32) -> i32 { + // CHECK: mul nsw + unchecked_mul(a, b) +} + +// CHECK-LABEL: @unchecked_mul_unsigned +#[no_mangle] +pub unsafe fn unchecked_mul_unsigned(a: u32, b: u32) -> u32 { + // CHECK: mul nuw + unchecked_mul(a, b) +} diff --git a/src/test/codegen/likely.rs b/src/test/codegen/likely.rs deleted file mode 100644 index c5a0185bd48..00000000000 --- a/src/test/codegen/likely.rs +++ /dev/null @@ -1,30 +0,0 @@ -// compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] -#![feature(core_intrinsics)] - -use std::intrinsics::{likely,unlikely}; - -#[no_mangle] -pub fn check_likely(x: i32, y: i32) -> Option { - unsafe { - // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 true) - if likely(x == y) { - None - } else { - Some(x + y) - } - } -} - -#[no_mangle] -pub fn check_unlikely(x: i32, y: i32) -> Option { - unsafe { - // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false) - if unlikely(x == y) { - None - } else { - Some(x + y) - } - } -} diff --git a/src/test/codegen/move-val-init.rs b/src/test/codegen/move-val-init.rs deleted file mode 100644 index 6222536b506..00000000000 --- a/src/test/codegen/move-val-init.rs +++ /dev/null @@ -1,19 +0,0 @@ -// compile-flags: -C no-prepopulate-passes - -#![feature(core_intrinsics)] -#![crate_type = "lib"] - -// test that `move_val_init` actually avoids big allocas - -use std::intrinsics::move_val_init; - -pub struct Big { - pub data: [u8; 65536] -} - -// CHECK-LABEL: @test_mvi -#[no_mangle] -pub unsafe fn test_mvi(target: *mut Big, make_big: fn() -> Big) { - // CHECK: call void %make_big(%Big*{{[^%]*}} %target) - move_val_init(target, make_big()); -} diff --git a/src/test/codegen/nontemporal.rs b/src/test/codegen/nontemporal.rs deleted file mode 100644 index 3a41fb4fab3..00000000000 --- a/src/test/codegen/nontemporal.rs +++ /dev/null @@ -1,13 +0,0 @@ -// compile-flags: -O - -#![feature(core_intrinsics)] -#![crate_type = "lib"] - -#[no_mangle] -pub fn a(a: &mut u32, b: u32) { - // CHECK-LABEL: define void @a - // CHECK: store i32 %b, i32* %a, align 4, !nontemporal - unsafe { - std::intrinsics::nontemporal_store(a, b); - } -} diff --git a/src/test/codegen/prefetch.rs b/src/test/codegen/prefetch.rs deleted file mode 100644 index 4cd38e14282..00000000000 --- a/src/test/codegen/prefetch.rs +++ /dev/null @@ -1,63 +0,0 @@ -// compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] -#![feature(core_intrinsics)] - -use std::intrinsics::{prefetch_read_data, prefetch_write_data, - prefetch_read_instruction, prefetch_write_instruction}; - -#[no_mangle] -pub fn check_prefetch_read_data(data: &[i8]) { - unsafe { - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 1) - prefetch_read_data(data.as_ptr(), 0); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 1) - prefetch_read_data(data.as_ptr(), 1); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 1) - prefetch_read_data(data.as_ptr(), 2); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 1) - prefetch_read_data(data.as_ptr(), 3); - } -} - -#[no_mangle] -pub fn check_prefetch_write_data(data: &[i8]) { - unsafe { - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 1) - prefetch_write_data(data.as_ptr(), 0); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 1) - prefetch_write_data(data.as_ptr(), 1); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 1) - prefetch_write_data(data.as_ptr(), 2); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 1) - prefetch_write_data(data.as_ptr(), 3); - } -} - -#[no_mangle] -pub fn check_prefetch_read_instruction(data: &[i8]) { - unsafe { - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 0) - prefetch_read_instruction(data.as_ptr(), 0); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 0) - prefetch_read_instruction(data.as_ptr(), 1); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 0) - prefetch_read_instruction(data.as_ptr(), 2); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 0) - prefetch_read_instruction(data.as_ptr(), 3); - } -} - -#[no_mangle] -pub fn check_prefetch_write_instruction(data: &[i8]) { - unsafe { - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 0) - prefetch_write_instruction(data.as_ptr(), 0); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 0) - prefetch_write_instruction(data.as_ptr(), 1); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 0) - prefetch_write_instruction(data.as_ptr(), 2); - // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 0) - prefetch_write_instruction(data.as_ptr(), 3); - } -} diff --git a/src/test/codegen/unchecked_math.rs b/src/test/codegen/unchecked_math.rs deleted file mode 100644 index 419c120ede9..00000000000 --- a/src/test/codegen/unchecked_math.rs +++ /dev/null @@ -1,46 +0,0 @@ -#![crate_type = "lib"] -#![feature(core_intrinsics)] - -use std::intrinsics::*; - -// CHECK-LABEL: @unchecked_add_signed -#[no_mangle] -pub unsafe fn unchecked_add_signed(a: i32, b: i32) -> i32 { - // CHECK: add nsw - unchecked_add(a, b) -} - -// CHECK-LABEL: @unchecked_add_unsigned -#[no_mangle] -pub unsafe fn unchecked_add_unsigned(a: u32, b: u32) -> u32 { - // CHECK: add nuw - unchecked_add(a, b) -} - -// CHECK-LABEL: @unchecked_sub_signed -#[no_mangle] -pub unsafe fn unchecked_sub_signed(a: i32, b: i32) -> i32 { - // CHECK: sub nsw - unchecked_sub(a, b) -} - -// CHECK-LABEL: @unchecked_sub_unsigned -#[no_mangle] -pub unsafe fn unchecked_sub_unsigned(a: u32, b: u32) -> u32 { - // CHECK: sub nuw - unchecked_sub(a, b) -} - -// CHECK-LABEL: @unchecked_mul_signed -#[no_mangle] -pub unsafe fn unchecked_mul_signed(a: i32, b: i32) -> i32 { - // CHECK: mul nsw - unchecked_mul(a, b) -} - -// CHECK-LABEL: @unchecked_mul_unsigned -#[no_mangle] -pub unsafe fn unchecked_mul_unsigned(a: u32, b: u32) -> u32 { - // CHECK: mul nuw - unchecked_mul(a, b) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs deleted file mode 100644 index 4d6ff47a3ee..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs +++ /dev/null @@ -1,71 +0,0 @@ -// force-host - -#![feature(plugin_registrar, rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate rustc_plugin; - -use syntax_ext::deriving; -use deriving::generic::*; -use deriving::generic::ty::*; - -use rustc_plugin::Registry; -use syntax::ast::*; -use syntax::source_map::Span; -use syntax::ext::base::*; -use syntax::ext::build::AstBuilder; -use syntax::symbol::Symbol; -use syntax::ptr::P; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension(Symbol::intern("derive_CustomPartialEq"), - MultiDecorator(Box::new(expand_deriving_partial_eq))); -} - -fn expand_deriving_partial_eq(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: &Annotatable, - push: &mut FnMut(Annotatable)) { - // structures are equal if all fields are equal, and non equal, if - // any fields are not equal or if the enum variants are different - fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { - cs_fold(true, - |cx, span, subexpr, self_f, other_fs| { - let other_f = (other_fs.len(), other_fs.get(0)).1.unwrap(); - let eq = cx.expr_binary(span, BinOpKind::Eq, self_f, other_f.clone()); - cx.expr_binary(span, BinOpKind::And, subexpr, eq) - }, - cx.expr_bool(span, true), - Box::new(|cx, span, _, _| cx.expr_bool(span, false)), - cx, - span, - substr) - } - - let inline = cx.meta_word(span, Symbol::intern("inline")); - let attrs = vec![cx.attribute(span, inline)]; - let methods = vec![MethodDef { - name: "eq", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), "other")], - ret_ty: Literal(deriving::generic::ty::Path::new_local("bool")), - attributes: attrs, - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(Box::new(cs_eq)), - }]; - - let trait_def = TraitDef { - span: span, - attributes: Vec::new(), - path: deriving::generic::ty::Path::new(vec!["cmp", "PartialEq"]), - additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), - is_unsafe: false, - supports_unions: false, - methods: methods, - associated_types: Vec::new(), - }; - trait_def.expand(cx, mitem, item, push) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs deleted file mode 100644 index c6b33fbc75e..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs +++ /dev/null @@ -1,84 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(box_syntax)] -#![feature(rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::ast; -use syntax::attr; -use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable}; -use syntax::ext::build::AstBuilder; -use syntax::symbol::{Symbol, sym}; -use syntax::ptr::P; -use syntax_ext::deriving::generic::{TraitDef, MethodDef, combine_substructure}; -use syntax_ext::deriving::generic::{Substructure, Struct, EnumMatching}; -use syntax_ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self}; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension( - Symbol::intern("rustc_derive_TotalSum"), - MultiDecorator(box expand)); -} - -fn expand(cx: &mut ExtCtxt, - span: Span, - mitem: &ast::MetaItem, - item: &Annotatable, - push: &mut FnMut(Annotatable)) { - let trait_def = TraitDef { - span: span, - attributes: vec![], - path: Path::new_local("TotalSum"), - additional_bounds: vec![], - generics: LifetimeBounds::empty(), - associated_types: vec![], - is_unsafe: false, - supports_unions: false, - methods: vec![ - MethodDef { - name: "total_sum", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![], - ret_ty: Literal(Path::new_local("isize")), - attributes: vec![], - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(Box::new(totalsum_substructure)), - }, - ], - }; - - trait_def.expand(cx, mitem, item, push) -} - -// Mostly copied from syntax::ext::deriving::hash -/// Defines how the implementation for `trace()` is to be generated -fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span, - substr: &Substructure) -> P { - let fields = match *substr.fields { - Struct(_, ref fs) | EnumMatching(.., ref fs) => fs, - _ => cx.span_bug(trait_span, "impossible substructure") - }; - - fields.iter().fold(cx.expr_isize(trait_span, 0), |acc, ref item| { - if attr::contains_name(&item.attrs, sym::ignore) { - acc - } else { - cx.expr_binary(item.span, ast::BinOpKind::Add, acc, - cx.expr_method_call(item.span, - item.self_.clone(), - substr.method_ident, - Vec::new())) - } - }) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs deleted file mode 100644 index 874a0ec7c13..00000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs +++ /dev/null @@ -1,76 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(box_syntax)] -#![feature(rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::ast; -use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable}; -use syntax::ext::build::AstBuilder; -use syntax::symbol::Symbol; -use syntax_ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_substructure}; -use syntax_ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self}; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension( - Symbol::intern("derive_TotalSum"), - MultiDecorator(box expand)); - - reg.register_syntax_extension( - Symbol::intern("derive_Nothing"), - MultiDecorator(box noop)); -} - -fn noop(_: &mut ExtCtxt, _: Span, _: &ast::MetaItem, _: &Annotatable, _: &mut FnMut(Annotatable)) {} - -fn expand(cx: &mut ExtCtxt, - span: Span, - mitem: &ast::MetaItem, - item: &Annotatable, - push: &mut FnMut(Annotatable)) { - let trait_def = TraitDef { - span: span, - attributes: vec![], - path: Path::new_local("TotalSum"), - additional_bounds: vec![], - generics: LifetimeBounds::empty(), - associated_types: vec![], - is_unsafe: false, - supports_unions: false, - methods: vec![ - MethodDef { - name: "total_sum", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![], - ret_ty: Literal(Path::new_local("isize")), - attributes: vec![], - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(box |cx, span, substr| { - let zero = cx.expr_isize(span, 0); - cs_fold(false, - |cx, span, subexpr, field, _| { - cx.expr_binary(span, ast::BinOpKind::Add, subexpr, - cx.expr_method_call(span, field, - ast::Ident::from_str("total_sum"), vec![])) - }, - zero, - box |cx, span, _, _| { cx.span_bug(span, "wtf??"); }, - cx, span, substr) - }), - }, - ], - }; - - trait_def.expand(cx, mitem, item, push) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs index 096701bd9b3..330459fc08f 100644 --- a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs +++ b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs @@ -10,11 +10,10 @@ use std::borrow::ToOwned; use syntax::ast; -use syntax::ext::hygiene; use syntax::ext::build::AstBuilder; -use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT}; +use syntax::ext::base::{SyntaxExtension, TTMacroExpander, ExtCtxt, MacResult, MacEager}; +use syntax::ext::hygiene::Transparency; use syntax::print::pprust; -use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; use syntax::tokenstream::TokenStream; @@ -29,7 +28,7 @@ fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, sp: Span, _: TokenStream, - _: Option) -> Box { + _: Option) -> Box { let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i)) .collect::>().join(", "); MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args))) @@ -40,9 +39,10 @@ fn expand<'cx>(&self, pub fn plugin_registrar(reg: &mut Registry) { let args = reg.args().to_owned(); reg.register_syntax_extension(Symbol::intern("plugin_args"), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(Expander { args: args, }), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs deleted file mode 100644 index ac8fff4f6bf..00000000000 --- a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs +++ /dev/null @@ -1,10 +0,0 @@ -// aux-build:custom-derive-partial-eq.rs -// ignore-stage1 -#![feature(plugin)] -#![plugin(custom_derive_partial_eq)] -#![allow(unused)] - -#[derive_CustomPartialEq] // Check that this is not a stability error. -enum E { V1, V2 } - -fn main() {} diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs deleted file mode 100644 index 38eaa71dd6a..00000000000 --- a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs +++ /dev/null @@ -1,64 +0,0 @@ -// aux-build:custom-derive-plugin-attr.rs -// ignore-stage1 - -#![feature(plugin, rustc_attrs)] -#![plugin(custom_derive_plugin_attr)] - -trait TotalSum { - fn total_sum(&self) -> isize; -} - -impl TotalSum for isize { - fn total_sum(&self) -> isize { - *self - } -} - -struct Seven; - -impl TotalSum for Seven { - fn total_sum(&self) -> isize { - 7 - } -} - -#[rustc_derive_TotalSum] -struct Foo { - seven: Seven, - bar: Bar, - baz: isize, - #[ignore] - nan: NaN, -} - -#[rustc_derive_TotalSum] -struct Bar { - quux: isize, - bleh: isize, - #[ignore] - nan: NaN2 -} - -struct NaN; - -impl TotalSum for NaN { - fn total_sum(&self) -> isize { - panic!(); - } -} - -struct NaN2; - -pub fn main() { - let v = Foo { - seven: Seven, - bar: Bar { - quux: 9, - bleh: 3, - nan: NaN2 - }, - baz: 80, - nan: NaN - }; - assert_eq!(v.total_sum(), 99); -} diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs deleted file mode 100644 index 2b0bb51d90a..00000000000 --- a/src/test/run-pass-fulldeps/derive-totalsum.rs +++ /dev/null @@ -1,49 +0,0 @@ -// aux-build:custom-derive-plugin.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(custom_derive_plugin)] - -trait TotalSum { - fn total_sum(&self) -> isize; -} - -impl TotalSum for isize { - fn total_sum(&self) -> isize { - *self - } -} - -struct Seven; - -impl TotalSum for Seven { - fn total_sum(&self) -> isize { - 7 - } -} - -#[derive_TotalSum] -struct Foo { - seven: Seven, - bar: Bar, - baz: isize, -} - -#[derive_TotalSum] -struct Bar { - quux: isize, - bleh: isize, -} - - -pub fn main() { - let v = Foo { - seven: Seven, - bar: Bar { - quux: 9, - bleh: 3, - }, - baz: 80, - }; - assert_eq!(v.total_sum(), 99); -} diff --git a/src/test/run-pass-fulldeps/issue-40663.rs b/src/test/run-pass-fulldeps/issue-40663.rs deleted file mode 100644 index 133f6302bde..00000000000 --- a/src/test/run-pass-fulldeps/issue-40663.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow(dead_code)] -// aux-build:custom-derive-plugin.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(custom_derive_plugin)] - -#[derive_Nothing] -#[derive_Nothing] -#[derive_Nothing] -struct S; - -fn main() {} diff --git a/src/test/ui/const-generics/issue-61336-1.rs b/src/test/ui/const-generics/issue-61336-1.rs new file mode 100644 index 00000000000..5b5e431bf2f --- /dev/null +++ b/src/test/ui/const-generics/issue-61336-1.rs @@ -0,0 +1,12 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn f(x: T) -> [T; N] { + [x; N] + //~^ ERROR array lengths can't depend on generic parameters +} + +fn main() { + let x: [u32; 5] = f::(3); + assert_eq!(x, [3u32; 5]); +} diff --git a/src/test/ui/const-generics/issue-61336-1.stderr b/src/test/ui/const-generics/issue-61336-1.stderr new file mode 100644 index 00000000000..1a5bb9f763b --- /dev/null +++ b/src/test/ui/const-generics/issue-61336-1.stderr @@ -0,0 +1,14 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue-61336-1.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error: array lengths can't depend on generic parameters + --> $DIR/issue-61336-1.rs:5:9 + | +LL | [x; N] + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issue-61336.rs b/src/test/ui/const-generics/issue-61336.rs new file mode 100644 index 00000000000..95930371d59 --- /dev/null +++ b/src/test/ui/const-generics/issue-61336.rs @@ -0,0 +1,16 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn f(x: T) -> [T; N] { + [x; N] +} + +fn g(x: T) -> [T; N] { + [x; N] + //~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied [E0277] +} + +fn main() { + let x: [u32; 5] = f::(3); + assert_eq!(x, [3u32; 5]); +} diff --git a/src/test/ui/const-generics/issue-61336.stderr b/src/test/ui/const-generics/issue-61336.stderr new file mode 100644 index 00000000000..9939a599834 --- /dev/null +++ b/src/test/ui/const-generics/issue-61336.stderr @@ -0,0 +1,18 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue-61336.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied + --> $DIR/issue-61336.rs:9:5 + | +LL | [x; N] + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | + = help: consider adding a `where T: std::marker::Copy` bound + = note: the `Copy` trait is required because the repeated element will be copied + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr index 7a10c469c51..abbdb4ab632 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr @@ -160,7 +160,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:100:38 | LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } @@ -169,7 +169,7 @@ LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:102:29 | LL | const fn foo30_5(b: bool) { while b { } } @@ -178,7 +178,7 @@ LL | const fn foo30_5(b: bool) { while b { } } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:104:44 | LL | const fn foo36(a: bool, b: bool) -> bool { a && b } @@ -187,7 +187,7 @@ LL | const fn foo36(a: bool, b: bool) -> bool { a && b } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:106:44 | LL | const fn foo37(a: bool, b: bool) -> bool { a || b } diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index 96b6057c8fd..40e7107e4a1 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -98,13 +98,13 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize } const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } //~^ ERROR casting pointers to ints is unstable const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } -//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn +//~^ ERROR loops and conditional expressions are not stable in const fn const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn const fn foo30_6() -> bool { let x = true; x } const fn foo36(a: bool, b: bool) -> bool { a && b } -//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn +//~^ ERROR loops and conditional expressions are not stable in const fn const fn foo37(a: bool, b: bool) -> bool { a || b } -//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn +//~^ ERROR loops and conditional expressions are not stable in const fn const fn inc(x: &mut i32) { *x += 1 } //~^ ERROR mutable references in const fn are unstable diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index e388b443d23..28a5ffb2015 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -160,7 +160,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:100:38 | LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } @@ -169,7 +169,7 @@ LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:102:29 | LL | const fn foo30_5(b: bool) { while b { } } @@ -178,7 +178,7 @@ LL | const fn foo30_5(b: bool) { while b { } } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:104:44 | LL | const fn foo36(a: bool, b: bool) -> bool { a && b } @@ -187,7 +187,7 @@ LL | const fn foo36(a: bool, b: bool) -> bool { a && b } = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/min_const_fn.rs:106:44 | LL | const fn foo37(a: bool, b: bool) -> bool { a || b } diff --git a/src/test/ui/consts/single_variant_match_ice.rs b/src/test/ui/consts/single_variant_match_ice.rs index 79dde3c18e8..6002506689e 100644 --- a/src/test/ui/consts/single_variant_match_ice.rs +++ b/src/test/ui/consts/single_variant_match_ice.rs @@ -15,7 +15,7 @@ pub const fn as_val(&self) -> u8 { use self::Foo::*; match *self { - Prob => 0x1, //~ ERROR `if`, `match`, `&&` and `||` are not stable in const fn + Prob => 0x1, //~ ERROR loops and conditional expressions are not stable in const fn } } } diff --git a/src/test/ui/consts/single_variant_match_ice.stderr b/src/test/ui/consts/single_variant_match_ice.stderr index b8ad775f1c3..1e092c8af99 100644 --- a/src/test/ui/consts/single_variant_match_ice.stderr +++ b/src/test/ui/consts/single_variant_match_ice.stderr @@ -10,7 +10,7 @@ error[E0019]: constant contains unimplemented expression type LL | x => 42, | ^ -error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn +error[E0723]: loops and conditional expressions are not stable in const fn --> $DIR/single_variant_match_ice.rs:18:13 | LL | Prob => 0x1, diff --git a/src/test/ui/macros/nonterminal-matching.stderr b/src/test/ui/macros/nonterminal-matching.stderr index 5fba8002e1c..93cc97d4583 100644 --- a/src/test/ui/macros/nonterminal-matching.stderr +++ b/src/test/ui/macros/nonterminal-matching.stderr @@ -1,6 +1,9 @@ error: no rules expected the token `enum E { }` --> $DIR/nonterminal-matching.rs:19:10 | +LL | macro n(a $nt_item b) { + | --------------------- when calling this macro +... LL | n!(a $nt_item b); | ^^^^^^^^ no rules expected this token in macro call ...