# 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'))
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”.)
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)
}
}
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> {
/// # 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üÃ\9fe, jürgen ❤", s);
+ /// assert_eq!("grÃ\9cÃ\9fe, jÃ\9crgen ❤", s);
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
pub fn make_ascii_lowercase(&mut self) {
}
}
+/// 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,
},
}
/// 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<DiagnosticId>,
message: &str)
+//! 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};
+//! 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)]
match decl {
ProcMacro::CustomDerive { trait_name, attributes, client } => {
let attrs = attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
- (trait_name, SyntaxExtension::ProcMacroDerive(
+ (trait_name, SyntaxExtension::Derive(
Box::new(ProcMacroDerive {
client,
attrs: attrs.clone(),
))
}
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,
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,
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()))
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;
/// 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,
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 {
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),
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<DefId> {
+ 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,
}
}
- 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_)
}
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<DefId> {
+ 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)
}
}
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) => {
}
LoadedMacro::ProcMacro(ext) => {
let helpers = match &*ext {
- &SyntaxExtension::ProcMacroDerive(_, ref syms, ..) => { syms.clean(cx) }
+ &SyntaxExtension::Derive(_, ref syms, ..) => { syms.clean(cx) }
_ => Vec::new(),
};
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")));
}
}
/// 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
///
/// 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
-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;
}
}
-// 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<F> 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 {
}
}
-pub trait IdentMacroExpander {
- fn expand<'cx>(&self,
- cx: &'cx mut ExtCtxt<'_>,
- sp: Span,
- ident: ast::Ident,
- token_tree: Vec<tokenstream::TokenTree>)
- -> Box<dyn MacResult+'cx>;
-}
-
-pub type IdentMacroExpanderFn =
- for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, Vec<tokenstream::TokenTree>)
- -> Box<dyn MacResult+'cx>;
-
-impl<F> IdentMacroExpander for F
- where F : for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident,
- Vec<tokenstream::TokenTree>) -> Box<dyn MacResult+'cx>
-{
- fn expand<'cx>(&self,
- cx: &'cx mut ExtCtxt<'_>,
- sp: Span,
- ident: ast::Ident,
- token_tree: Vec<tokenstream::TokenTree>)
- -> Box<dyn MacResult+'cx>
- {
- (*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) => {
}
}
-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 {
/// 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<dyn MultiItemDecorator + sync::Sync + sync::Send>),
-
- /// A syntax extension that is attached to an item and modifies it
- /// in-place. Also allows decoration, i.e., creating new items.
- MultiModifier(Box<dyn MultiItemModifier + sync::Sync + sync::Send>),
-
- /// A function-like procedural macro. TokenStream -> TokenStream.
- ProcMacro {
+ /// A token-based function-like macro.
+ Bang {
+ /// An expander with signature TokenStream -> TokenStream.
expander: Box<dyn ProcMacro + sync::Sync + sync::Send>,
- /// 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<Lrc<[Symbol]>>,
+ /// 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<dyn AttrProcMacro + sync::Sync + sync::Send>, 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<dyn TTMacroExpander + sync::Sync + sync::Send>,
+ /// 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<Lrc<[Symbol]>>,
- /// 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<dyn IdentMacroExpander + sync::Sync + sync::Send>,
- span: Option<Span>,
- allow_internal_unstable: Option<Lrc<[Symbol]>>,
+ /// 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<dyn AttrProcMacro + sync::Sync + sync::Send>,
+ /// 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<dyn MultiItemModifier + sync::Sync + sync::Send>,
+ ),
+
+ /// 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<dyn MultiItemModifier + sync::Sync + sync::Send>,
- Vec<Symbol> /* 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<dyn TTMacroExpander + sync::Sync + sync::Send>,
- 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<dyn MultiItemModifier + sync::Sync + sync::Send>,
+ /// Names of helper attributes registered by this macro.
+ Vec<Symbol>,
+ /// 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<dyn MultiItemModifier + sync::Sync + sync::Send>,
+ ),
}
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,
}
}
}
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(),
_ => 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);
});
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),
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)
};
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,
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(),
}
}
- 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);
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))
}
_ => {
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};
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::<Vec<Symbol>>().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::<Vec<Symbol>>().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,
}
}
//! 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;
#[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<Annotatable> {
+ 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 {
$(
resolver.add_builtin(
ast::Ident::with_empty_ctxt(Symbol::intern($name)),
- Lrc::new(SyntaxExtension::BuiltinDerive($func))
+ Lrc::new(SyntaxExtension::LegacyDerive(Box::new(BuiltinDerive($func))))
);
)*
}
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};
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,
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,
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,
+++ /dev/null
-// 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)
-}
--- /dev/null
+// 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)
+}
--- /dev/null
+// 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<i32> {
+ 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<i32> {
+ unsafe {
+ // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false)
+ if unlikely(x == y) {
+ None
+ } else {
+ Some(x + y)
+ }
+ }
+}
--- /dev/null
+// 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());
+}
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+#![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)
+}
+++ /dev/null
-// 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<i32> {
- 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<i32> {
- unsafe {
- // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false)
- if unlikely(x == y) {
- None
- } else {
- Some(x + y)
- }
- }
-}
+++ /dev/null
-// 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());
-}
+++ /dev/null
-// 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);
- }
-}
+++ /dev/null
-// 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);
- }
-}
+++ /dev/null
-#![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)
-}
+++ /dev/null
-// 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<Expr> {
- 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)
-}
+++ /dev/null
-// 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<ast::Expr> {
- 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()))
- }
- })
-}
+++ /dev/null
-// 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)
-}
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;
ecx: &'cx mut ExtCtxt,
sp: Span,
_: TokenStream,
- _: Option<Span>) -> Box<MacResult+'cx> {
+ _: Option<Span>) -> Box<dyn MacResult+'cx> {
let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i))
.collect::<Vec<_>>().join(", ");
MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args)))
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,
+++ /dev/null
-// 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() {}
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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);
-}
+++ /dev/null
-#![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() {}
--- /dev/null
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
+ [x; N]
+ //~^ ERROR array lengths can't depend on generic parameters
+}
+
+fn main() {
+ let x: [u32; 5] = f::<u32, 5>(3);
+ assert_eq!(x, [3u32; 5]);
+}
--- /dev/null
+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
+
--- /dev/null
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
+ [x; N]
+}
+
+fn g<T, const N: usize>(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::<u32, 5>(3);
+ assert_eq!(x, [3u32; 5]);
+}
--- /dev/null
+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`.
= 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 } }
= 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 { } }
= 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 }
= 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 }
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
= 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 } }
= 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 { } }
= 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 }
= 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 }
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
}
}
}
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,
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
...