diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea9f2c1943005..21b14d011f911 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -405,7 +405,8 @@ before the PR is merged. [breaking-tools-built-with-the-compiler]: #breaking-tools-built-with-the-compiler Rust's build system builds a number of tools that make use of the -internals of the compiler. This includes clippy, +internals of the compiler. This includes +[Clippy](https://github.com/rust-lang-nursery/rust-clippy), [RLS](https://github.com/rust-lang-nursery/rls) and [rustfmt](https://github.com/rust-lang-nursery/rustfmt). If these tools break because of your changes, you may run into a sort of "chicken and egg" diff --git a/config.toml.example b/config.toml.example index 35f69cd05b607..0410770291663 100644 --- a/config.toml.example +++ b/config.toml.example @@ -68,7 +68,7 @@ # not built by default and the experimental Rust compilation targets that depend # on them will not work unless the user opts in to building them. By default the # `WebAssembly` and `RISCV` targets are enabled when compiling LLVM from scratch. -#experimental-targets = "WebAssembly;RISCV" +#experimental-targets = "AVR;WebAssembly;RISCV" # Cap the number of parallel linker invocations when compiling LLVM. # This can be useful when building LLVM with debug info, which significantly diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index a54e58665cceb..bb5a21e3e405f 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -37,6 +37,8 @@ fn main() { let mut dylib_path = bootstrap::util::dylib_path(); dylib_path.insert(0, PathBuf::from(libdir.clone())); + //FIXME(misdreavus): once stdsimd uses cfg(rustdoc) instead of cfg(dox), remove the `--cfg dox` + //arguments here let mut cmd = Command::new(rustdoc); cmd.args(&args) .arg("--cfg") diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index bf4d39c4947e5..6da2f2db2c52d 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -514,7 +514,7 @@ impl Config { set(&mut config.llvm_link_shared, llvm.link_shared); config.llvm_targets = llvm.targets.clone(); config.llvm_experimental_targets = llvm.experimental_targets.clone() - .unwrap_or("WebAssembly;RISCV".to_string()); + .unwrap_or("AVR;WebAssembly;RISCV".to_string()); config.llvm_link_jobs = llvm.link_jobs; config.llvm_clang_cl = llvm.clang_cl.clone(); } diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index a23dbd308244f..32fb8c2f7d58e 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -106,27 +106,25 @@ The `#[doc(cfg(...))]` attribute has another effect: When Rustdoc renders docume item, it will be accompanied by a banner explaining that the item is only available on certain platforms. -As mentioned earlier, getting the items to Rustdoc requires some extra preparation. The standard -library adds a `--cfg dox` flag to every Rustdoc command, but the same thing can be accomplished by -adding a feature to your Cargo.toml and adding `--feature dox` (or whatever you choose to name the -feature) to your `cargo doc` calls. +For Rustdoc to document an item, it needs to see it, regardless of what platform it's currently +running on. To aid this, Rustdoc sets the flag `#[cfg(rustdoc)]` when running on your crate. +Combining this with the target platform of a given item allows it to appear when building your crate +normally on that platform, as well as when building documentation anywhere. -Either way, once you create an environment for the documentation, you can start to augment your -`#[cfg]` attributes to allow both the target platform *and* the documentation configuration to leave -the item in. For example, `#[cfg(any(windows, feature = "dox"))]` will preserve the item either on -Windows or during the documentation process. Then, adding a new attribute `#[doc(cfg(windows))]` -will tell Rustdoc that the item is supposed to be used on Windows. For example: +For example, `#[cfg(any(windows, rustdoc))]` will preserve the item either on Windows or during the +documentation process. Then, adding a new attribute `#[doc(cfg(windows))]` will tell Rustdoc that +the item is supposed to be used on Windows. For example: ```rust #![feature(doc_cfg)] /// Token struct that can only be used on Windows. -#[cfg(any(windows, feature = "dox"))] +#[cfg(any(windows, rustdoc))] #[doc(cfg(windows))] pub struct WindowsToken; /// Token struct that can only be used on Unix. -#[cfg(any(unix, feature = "dox"))] +#[cfg(any(unix, rustdoc))] #[doc(cfg(unix))] pub struct UnixToken; ``` diff --git a/src/doc/unstable-book/src/language-features/doc-cfg.md b/src/doc/unstable-book/src/language-features/doc-cfg.md index ddc538e12144a..96c66a1515ed5 100644 --- a/src/doc/unstable-book/src/language-features/doc-cfg.md +++ b/src/doc/unstable-book/src/language-features/doc-cfg.md @@ -12,13 +12,17 @@ This attribute has two effects: 2. The item's doc-tests will only run on the specific platform. +In addition to allowing the use of the `#[doc(cfg)]` attribute, this feature enables the use of a +special conditional compilation flag, `#[cfg(rustdoc)]`, set whenever building documentation on your +crate. + This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the standard library be documented. ```rust #![feature(doc_cfg)] -#[cfg(any(windows, feature = "documentation"))] +#[cfg(any(windows, rustdoc))] #[doc(cfg(windows))] /// The application's icon in the notification area (a.k.a. system tray). /// @@ -39,4 +43,4 @@ pub struct Icon { ``` [#43781]: https://github.com/rust-lang/rust/issues/43781 -[#43348]: https://github.com/rust-lang/rust/issues/43348 \ No newline at end of file +[#43348]: https://github.com/rust-lang/rust/issues/43348 diff --git a/src/etc/rust-gdbgui b/src/etc/rust-gdbgui new file mode 100755 index 0000000000000..7e179ba927dff --- /dev/null +++ b/src/etc/rust-gdbgui @@ -0,0 +1,65 @@ +#!/bin/sh +# Copyright 2014 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +# Exit if anything fails +set -e + +if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ] || [ "$1" = "--help" ]; then + echo " +rust-gdbgui +=========== +gdbgui - https://gdbgui.com - is a graphical front-end to GDB +that runs in a browser. This script invokes gdbgui with the Rust +pretty printers loaded. + +Simple usage : rust-gdbgui target/debug/myprog +With arguments: rust-gdbgui 'target/debug/myprog arg1 arg2...' + (note the quotes) + + +Hints +===== +gdbgui won't be able to find the rust 'main' method automatically, so +in its options make sure to disable the 'Add breakpoint to main after +loading executable' setting to avoid a 'File not found: main' warning +on startup. + +Instead, type 'main' into gdbgui's file browser and you should get +auto-completion on the filename. Just pick 'main.rs', add a breakpoint +by clicking in the line number gutter, and type 'r' or hit the Restart +icon to start your program running. +" + exit 0 +fi + +# Find out where the pretty printer Python module is +RUSTC_SYSROOT=`rustc --print=sysroot` +GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc" + +# Set the environment variable `RUST_GDB` to overwrite the call to a +# different/specific command (defaults to `gdb`). +RUST_GDB="${RUST_GDB:-gdb}" + +# Set the environment variable `RUST_GDBGUI` to overwrite the call to a +# different/specific command (defaults to `gdbgui`). +RUST_GDBGUI="${RUST_GDBGUI:-gdbgui}" + +# These arguments get passed through to GDB and make it load the +# Rust pretty printers. +GDB_ARGS="--directory=\"$GDB_PYTHON_MODULE_DIRECTORY\" -iex \"add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY\"" + +# Finally we execute gdbgui. +PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" \ + exec ${RUST_GDBGUI} \ + --gdb ${RUST_GDB} \ + --gdb-args "${GDB_ARGS}" \ + "${@}" + diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 676c977514f32..452d2b1472ff4 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -88,7 +88,8 @@ #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] -#![feature(const_fn)] +#![cfg_attr(stage0, feature(const_fn))] +#![cfg_attr(not(stage0), feature(min_const_fn))] #![feature(core_intrinsics)] #![feature(custom_attribute)] #![feature(dropck_eyepatch)] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 2cd7898f4c781..db7a4044b267f 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -49,9 +49,10 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// /// The type `Arc` provides shared ownership of a value of type `T`, /// allocated in the heap. Invoking [`clone`][clone] on `Arc` produces -/// a new pointer to the same value in the heap. When the last `Arc` -/// pointer to a given value is destroyed, the pointed-to value is -/// also destroyed. +/// a new `Arc` instance, which points to the same value on the heap as the +/// source `Arc`, while increasing a reference count. When the last `Arc` +/// pointer to a given value is destroyed, the pointed-to value is also +/// destroyed. /// /// Shared references in Rust disallow mutation by default, and `Arc` is no /// exception: you cannot generally obtain a mutable reference to something @@ -107,7 +108,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// // The two syntaxes below are equivalent. /// let a = foo.clone(); /// let b = Arc::clone(&foo); -/// // a and b both point to the same memory location as foo. +/// // a, b, and foo are all Arcs that point to the same memory location /// ``` /// /// The [`Arc::clone(&from)`] syntax is the most idiomatic because it conveys more explicitly diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 3a84f9e7e47ba..710c659ac5396 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -11,7 +11,8 @@ #![feature(allocator_api)] #![feature(alloc_system)] #![feature(box_syntax)] -#![feature(const_fn)] +#![cfg_attr(stage0, feature(const_fn))] +#![cfg_attr(not(stage0), feature(min_const_fn))] #![feature(drain_filter)] #![feature(exact_size_is_empty)] #![feature(pattern)] diff --git a/src/libcore/benches/any.rs b/src/libcore/benches/any.rs index 67e02cf9509b6..f4f01eb1cf5d2 100644 --- a/src/libcore/benches/any.rs +++ b/src/libcore/benches/any.rs @@ -15,7 +15,7 @@ use test::{Bencher, black_box}; fn bench_downcast_ref(b: &mut Bencher) { b.iter(|| { let mut x = 0; - let mut y = &mut x as &mut Any; + let mut y = &mut x as &mut dyn Any; black_box(&mut y); black_box(y.downcast_ref::() == Some(&0)); }); diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 5b3b2d1635688..0032bedc7ed1d 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -541,7 +541,7 @@ macro_rules! unimplemented { /// into libsyntax itself. /// /// For more information, see documentation for `std`'s macros. -#[cfg(dox)] +#[cfg(rustdoc)] mod builtin { /// Unconditionally causes compilation to fail with the given error message when encountered. diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index f2852d98282b7..e00a22bf8b6c3 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -285,6 +285,15 @@ pub fn forget(t: T) { /// [alignment]: ./fn.align_of.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +pub const fn size_of() -> usize { + intrinsics::size_of::() +} + +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] +/// Ceci n'est pas la documentation pub const fn size_of() -> usize { unsafe { intrinsics::size_of::() } } @@ -334,6 +343,16 @@ pub fn size_of_val(val: &T) -> usize { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(reason = "use `align_of` instead", since = "1.2.0")] +#[cfg(not(stage0))] +pub fn min_align_of() -> usize { + intrinsics::min_align_of::() +} + +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_deprecated(reason = "use `align_of` instead", since = "1.2.0")] +#[cfg(stage0)] +/// Ceci n'est pas la documentation pub fn min_align_of() -> usize { unsafe { intrinsics::min_align_of::() } } @@ -376,6 +395,15 @@ pub fn min_align_of_val(val: &T) -> usize { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +pub const fn align_of() -> usize { + intrinsics::min_align_of::() +} + +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] +/// Ceci n'est pas la documentation pub const fn align_of() -> usize { unsafe { intrinsics::min_align_of::() } } diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 98cfa094c169a..1b97480920321 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -488,8 +488,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { // expression to target let guard_start = self.add_dummy_node(&[pat_exit]); // Visit the guard expression - let guard_exit = self.expr(&guard, guard_start); - + let guard_exit = match guard { + hir::Guard::If(ref e) => self.expr(e, guard_start), + }; // #47295: We used to have very special case code // here for when a pair of arms are both formed // solely from constants, and if so, not add these diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 90081d5b85ef9..dfe0a395ca140 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -75,7 +75,7 @@ use traits::query::{ CanonicalPredicateGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal, }; use ty::{TyCtxt, FnSig, Instance, InstanceDef, - ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty, self}; + ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty}; use ty::subst::Substs; // erase!() just makes tokens go away. It's used to specify which macro argument @@ -632,7 +632,6 @@ define_dep_nodes!( <'tcx> // queries). Making them anonymous avoids hashing the result, which // may save a bit of time. [anon] EraseRegionsTy { ty: Ty<'tcx> }, - [anon] ConstToAllocation { val: &'tcx ty::Const<'tcx> }, [input] Freevars(DefId), [input] MaybeUnusedTraitImport(DefId), diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index d853d3d9a7fb4..8129cc18d46c2 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -1102,7 +1102,11 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { walk_list!(visitor, visit_pat, &arm.pats); - walk_list!(visitor, visit_expr, &arm.guard); + if let Some(ref g) = arm.guard { + match g { + Guard::If(ref e) => visitor.visit_expr(e), + } + } visitor.visit_expr(&arm.body); walk_list!(visitor, visit_attribute, &arm.attrs); } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 8584b534ff240..34b3eb0a8c8bf 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1054,7 +1054,10 @@ impl<'a> LoweringContext<'a> { hir::Arm { attrs: self.lower_attrs(&arm.attrs), pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(), - guard: arm.guard.as_ref().map(|ref x| P(self.lower_expr(x))), + guard: match arm.guard { + Some(Guard::If(ref x)) => Some(hir::Guard::If(P(self.lower_expr(x)))), + _ => None, + }, body: P(self.lower_expr(&arm.body)), } } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7ac334d84a9bf..1b31035787371 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1204,10 +1204,15 @@ impl DeclKind { pub struct Arm { pub attrs: HirVec, pub pats: HirVec>, - pub guard: Option>, + pub guard: Option, pub body: P, } +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +pub enum Guard { + If(P), +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Field { pub id: NodeId, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 8b221f3463ed3..55357095fb759 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1949,10 +1949,14 @@ impl<'a> State<'a> { self.print_pat(&p)?; } self.s.space()?; - if let Some(ref e) = arm.guard { - self.word_space("if")?; - self.print_expr(&e)?; - self.s.space()?; + if let Some(ref g) = arm.guard { + match g { + hir::Guard::If(e) => { + self.word_space("if")?; + self.print_expr(&e)?; + self.s.space()?; + } + } } self.word_space("=>")?; diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 2ac195dca82c4..3f1899bc54fb4 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -493,6 +493,10 @@ impl_stable_hash_for!(struct hir::Arm { body }); +impl_stable_hash_for!(enum hir::Guard { + If(expr), +}); + impl_stable_hash_for!(struct hir::Field { id -> _, ident, diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 1c9387d02d5a3..f11e448796462 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -65,6 +65,7 @@ for mir::UnsafetyViolationKind { match *self { mir::UnsafetyViolationKind::General => {} + mir::UnsafetyViolationKind::MinConstFn => {} mir::UnsafetyViolationKind::ExternStatic(lint_node_id) | mir::UnsafetyViolationKind::BorrowPacked(lint_node_id) => { lint_node_id.hash_stable(hcx, hasher); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index ac5fdb2fe2797..d0513740a5766 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -116,6 +116,8 @@ impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi { Msp430Interrupt, X86Interrupt, AmdGpuKernel, + AvrInterrupt, + AvrNonBlockingInterrupt, Rust, C, System, @@ -130,7 +132,7 @@ impl_stable_hash_for!(struct ::syntax::attr::Stability { level, feature, rustc_depr, - rustc_const_unstable + const_stability }); impl<'a> HashStable> @@ -161,7 +163,6 @@ for ::syntax::attr::StabilityLevel { } impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason }); -impl_stable_hash_for!(struct ::syntax::attr::RustcConstUnstable { feature }); impl_stable_hash_for!(enum ::syntax::attr::IntType { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index d014f319564fe..d79281666d639 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -42,7 +42,8 @@ #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(const_fn)] +#![cfg_attr(stage0, feature(const_fn))] +#![cfg_attr(not(stage0), feature(min_const_fn))] #![feature(core_intrinsics)] #![feature(drain_filter)] #![cfg_attr(windows, feature(libc))] diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index d5247b4ce9de8..b823545aa9114 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -319,7 +319,15 @@ impl LintStore { CheckLintNameResult::NoLint => { Some(struct_err!(sess, E0602, "unknown lint: `{}`", lint_name)) } - CheckLintNameResult::Tool(_) => unreachable!(), + CheckLintNameResult::Tool(result) => match result { + Err((Some(_), new_name)) => Some(sess.struct_warn(&format!( + "lint name `{}` is deprecated \ + and does not have an effect anymore. \ + Use: {}", + lint_name, new_name + ))), + _ => None, + }, }; if let Some(mut db) = db { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 90692bcd30103..356992b22146d 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -792,7 +792,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } if let Some(ref guard) = arm.guard { - self.consume_expr(&guard); + match guard { + hir::Guard::If(ref e) => self.consume_expr(e), + } } self.consume_expr(&arm.body); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 2697d62cf467a..c34a0a654e6a9 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1030,7 +1030,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let body_succ = self.propagate_through_expr(&arm.body, succ); let guard_succ = - self.propagate_through_opt_expr(arm.guard.as_ref().map(|e| &**e), body_succ); + self.propagate_through_opt_expr( + arm.guard.as_ref().map(|g| + match g { + hir::Guard::If(e) => &**e, + }), + body_succ); // only consider the first pattern; any later patterns must have // the same bindings, and we also consider the first pattern to be // the "authoritative" set of ids diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 20ee5f0b04635..e281cbf948893 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -885,8 +885,10 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk: fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &'tcx hir::Arm) { visitor.terminating_scopes.insert(arm.body.hir_id.local_id); - if let Some(ref expr) = arm.guard { - visitor.terminating_scopes.insert(expr.hir_id.local_id); + if let Some(ref g) = arm.guard { + match g { + hir::Guard::If(ref expr) => visitor.terminating_scopes.insert(expr.hir_id.local_id), + }; } intravisit::walk_arm(visitor, arm); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 85195b0f62e7c..f237c5b397bd5 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -440,7 +440,7 @@ impl<'a, 'tcx> Index<'tcx> { }, feature: Symbol::intern("rustc_private"), rustc_depr: None, - rustc_const_unstable: None, + const_stability: None, }); annotator.parent_stab = Some(stability); } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 3ef8cdfd1044d..44730c19dd3e8 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2430,6 +2430,8 @@ impl Location { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum UnsafetyViolationKind { General, + /// unsafety is not allowed at all in min const fn + MinConstFn, ExternStatic(ast::NodeId), BorrowPacked(ast::NodeId), } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index de50598c42c9d..6981d92f05f00 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1099,6 +1099,37 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { local as usize == global as usize } + /// Returns true if this function must conform to `min_const_fn` + pub fn is_min_const_fn(self, def_id: DefId) -> bool { + if self.features().staged_api { + // some intrinsics are waved through if called inside the + // standard library. Users never need to call them directly + if let abi::Abi::RustIntrinsic = self.fn_sig(def_id).abi() { + assert!(!self.is_const_fn(def_id)); + match &self.item_name(def_id).as_str()[..] { + | "size_of" + | "min_align_of" + => return true, + _ => {}, + } + } + // in order for a libstd function to be considered min_const_fn + // it needs to be stable and have no `rustc_const_unstable` attribute + match self.lookup_stability(def_id) { + // stable functions with unstable const fn aren't `min_const_fn` + Some(&attr::Stability { const_stability: Some(_), .. }) => false, + // unstable functions don't need to conform + Some(&attr::Stability { ref level, .. }) if level.is_unstable() => false, + // everything else needs to conform, because it would be callable from + // other `min_const_fn` functions + _ => true, + } + } else { + // users enabling the `const_fn` can do what they want + !self.sess.features_untracked().const_fn + } + } + /// Create a type context and call the closure with a `TyCtxt` reference /// to the context. The closure enforces that the type context and any interned /// value (types, substs, etc.) can only be used while `ty::tls` has a valid diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index b5093d0a1fc95..d32580181f8dc 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -198,12 +198,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> { } } -impl<'tcx> QueryDescription<'tcx> for queries::const_to_allocation<'tcx> { - fn describe(_tcx: TyCtxt, val: &'tcx ty::Const<'tcx>) -> String { - format!("converting constant `{:?}` to an allocation", val) - } -} - impl<'tcx> QueryDescription<'tcx> for queries::erase_regions_ty<'tcx> { fn describe(_tcx: TyCtxt, ty: Ty<'tcx>) -> String { format!("erasing regions from `{:?}`", ty) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 6f61583e49b8e..88f599971c7da 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -30,7 +30,7 @@ use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol}; use mir::interpret::ConstEvalResult; use mir::mono::{CodegenUnit, Stats}; use mir; -use mir::interpret::{GlobalId, Allocation}; +use mir::interpret::GlobalId; use session::{CompileResult, CrateDisambiguator}; use session::config::OutputFilenames; use traits::{self, Vtable}; @@ -286,11 +286,6 @@ define_queries! { <'tcx> /// other items (such as enum variant explicit discriminants). [] fn const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalResult<'tcx>, - - /// Converts a constant value to a constant allocation - [] fn const_to_allocation: const_to_allocation( - &'tcx ty::Const<'tcx> - ) -> &'tcx Allocation, }, TypeChecking { @@ -706,12 +701,6 @@ fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> { DepConstructor::EraseRegionsTy { ty } } -fn const_to_allocation<'tcx>( - val: &'tcx ty::Const<'tcx>, -) -> DepConstructor<'tcx> { - DepConstructor::ConstToAllocation { val } -} - fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> { DepConstructor::TypeParamPredicates { item_id, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 0edb1aa79e745..215fba54499b7 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1062,7 +1062,6 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::FulfillObligation | DepKind::VtableMethods | DepKind::EraseRegionsTy | - DepKind::ConstToAllocation | DepKind::NormalizeProjectionTy | DepKind::NormalizeTyAfterErasingRegions | DepKind::ImpliedOutlivesBounds | diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 684f2b358858f..dcd1b68c5149f 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -19,7 +19,7 @@ use type_::Type; use type_of::{LayoutLlvmExt, PointerKind}; use value::Value; -use rustc_target::abi::{LayoutOf, Size, TyLayout}; +use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout}; use rustc::ty::{self, Ty}; use rustc::ty::layout; @@ -277,6 +277,7 @@ pub trait FnTypeExt<'tcx> { cx: &CodegenCx<'ll, 'tcx>, abi: Abi); fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; + fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn llvm_cconv(&self) -> llvm::CallConv; fn apply_attrs_llfn(&self, llfn: &'ll Value); fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value); @@ -354,6 +355,8 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { Msp430Interrupt => Conv::Msp430Intr, X86Interrupt => Conv::X86Intr, AmdGpuKernel => Conv::AmdGpuKernel, + AvrInterrupt => Conv::AvrInterrupt, + AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt, // These API constants ought to be more specific... Cdecl => Conv::C, @@ -629,10 +632,19 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { } } + fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type { + unsafe { + llvm::LLVMPointerType(self.llvm_type(cx), + cx.data_layout().instruction_address_space as c_uint) + } + } + fn llvm_cconv(&self) -> llvm::CallConv { match self.conv { Conv::C => llvm::CCallConv, Conv::AmdGpuKernel => llvm::AmdGpuKernel, + Conv::AvrInterrupt => llvm::AvrInterrupt, + Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt, Conv::ArmAapcs => llvm::ArmAapcsCallConv, Conv::Msp430Intr => llvm::Msp430Intr, Conv::PtxKernel => llvm::PtxKernel, diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 51b0299e63f46..490f659ddb104 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -59,6 +59,8 @@ pub enum CallConv { X86_64_Win64 = 79, X86_VectorCall = 80, X86_Intr = 83, + AvrNonBlockingInterrupt = 84, + AvrInterrupt = 85, AmdGpuKernel = 91, } diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs index 8a1159bc4773c..0164bcf9566e8 100644 --- a/src/librustc_codegen_llvm/meth.rs +++ b/src/librustc_codegen_llvm/meth.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> VirtualIndex { // Load the data pointer from the object. debug!("get_fn({:?}, {:?})", llvtable, self); - let llvtable = bx.pointercast(llvtable, fn_ty.llvm_type(bx.cx).ptr_to().ptr_to()); + let llvtable = bx.pointercast(llvtable, fn_ty.ptr_to_llvm_type(bx.cx).ptr_to()); let ptr_align = bx.tcx().data_layout.pointer_align; let ptr = bx.load(bx.inbounds_gep(llvtable, &[C_usize(bx.cx, self.0)]), ptr_align); bx.nonnull_metadata(ptr); diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index 51a233d791625..6fb78fe4aa5a4 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -234,6 +234,8 @@ impl Type { } pub fn ptr_to(&self) -> &Type { + assert_ne!(self.kind(), TypeKind::Function, + "don't call ptr_to on function types, use ptr_to_llvm_type on FnType instead"); unsafe { llvm::LLVMPointerType(self, 0) } diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index e6907030ae635..5fa97dbb1bdd2 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -264,7 +264,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { ty::ParamEnv::reveal_all(), &sig, ); - FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to() + FnType::new(cx, sig, &[]).ptr_to_llvm_type(cx) } _ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO) }; diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 4e24a26983d48..583a92e052158 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -81,7 +81,7 @@ fn main() { let is_crossed = target != host; let mut optional_components = - vec!["x86", "arm", "aarch64", "mips", "powerpc", + vec!["x86", "arm", "aarch64", "avr", "mips", "powerpc", "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"]; let mut version_cmd = Command::new(&llvm_config); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 13605e993a59c..0be8351ebc0f7 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -53,6 +53,12 @@ pub fn initialize_available_targets() { LLVMInitializeARMTargetMC, LLVMInitializeARMAsmPrinter, LLVMInitializeARMAsmParser); + init_target!(llvm_component = "avr", + LLVMInitializeAVRTargetInfo, + LLVMInitializeAVRTarget, + LLVMInitializeAVRTargetMC, + LLVMInitializeAVRAsmPrinter, + LLVMInitializeAVRAsmParser); init_target!(llvm_component = "aarch64", LLVMInitializeAArch64TargetInfo, LLVMInitializeAArch64Target, diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index b317bb7cff0e3..d3e67ea7b7d71 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -453,7 +453,7 @@ pub struct Candidate<'pat, 'tcx:'pat> { bindings: Vec>, // ...and the guard must be evaluated... - guard: Option>, + guard: Option>, // ...and then we branch to arm with this index. arm_index: usize, @@ -998,7 +998,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // the block to branch to if the guard fails; if there is no // guard, this block is simply unreachable - let guard = self.hir.mirror(guard); + let guard = match guard { + Guard::If(e) => self.hir.mirror(e), + }; let source_info = self.source_info(guard.span); let cond = unpack!(block = self.as_local_operand(block, guard)); if autoref { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 8be1f52a9cdfc..055f238e5db4e 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -837,7 +837,10 @@ impl ToBorrowKind for hir::Mutability { fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> { Arm { patterns: arm.pats.iter().map(|p| cx.pattern_from_hir(p)).collect(), - guard: arm.guard.to_ref(), + guard: match arm.guard { + Some(hir::Guard::If(ref e)) => Some(Guard::If(e.to_ref())), + _ => None, + }, body: arm.body.to_ref(), // BUG: fix this lint_level: LintLevel::Inherited, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index c9fd1d04e547b..b4257a40e38af 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -18,7 +18,6 @@ use hair::*; use rustc_data_structures::indexed_vec::Idx; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; -use rustc::hir::map::blocks::FnLikeNode; use rustc::hir::Node; use rustc::middle::region; use rustc::infer::InferCtxt; @@ -67,10 +66,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { let constness = match body_owner_kind { hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => hir::Constness::Const, - hir::BodyOwnerKind::Fn => { - let fn_like = FnLikeNode::from_node(infcx.tcx.hir.get(src_id)); - fn_like.map_or(hir::Constness::NotConst, |f| f.constness()) - } + hir::BodyOwnerKind::Fn => hir::Constness::NotConst, }; let attrs = tcx.hir.attrs(src_id); @@ -83,7 +79,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { // Respect -C overflow-checks. check_overflow |= tcx.sess.overflow_checks(); - // Constants and const fn's always need overflow checks. + // Constants always need overflow checks. check_overflow |= constness == hir::Constness::Const; let lint_level = lint_level_for_hir_id(tcx, src_id); diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index d6037adb53bb7..2ddb810f49148 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -316,11 +316,16 @@ pub struct FruInfo<'tcx> { #[derive(Clone, Debug)] pub struct Arm<'tcx> { pub patterns: Vec>, - pub guard: Option>, + pub guard: Option>, pub body: ExprRef<'tcx>, pub lint_level: LintLevel, } +#[derive(Clone, Debug)] +pub enum Guard<'tcx> { + If(ExprRef<'tcx>), +} + #[derive(Copy, Clone, Debug)] pub enum LogicalOp { And, diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 604cc61a17ecb..bf878145e1fb9 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -208,7 +208,9 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { } (pattern, &**pat) }).collect(), - arm.guard.as_ref().map(|e| &**e) + arm.guard.as_ref().map(|g| match g { + hir::Guard::If(ref e) => &**e, + }) )).collect(); // Bail out early if inlining failed. @@ -540,12 +542,16 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, "cannot bind by-move into a pattern guard") .span_label(p.span, "moves value into pattern guard") .emit(); - } else if by_ref_span.is_some() { - struct_span_err!(cx.tcx.sess, p.span, E0009, - "cannot bind by-move and by-ref in the same pattern") - .span_label(p.span, "by-move pattern here") - .span_label(by_ref_span.unwrap(), "both by-ref and by-move used") - .emit(); + } else if let Some(by_ref_span) = by_ref_span { + struct_span_err!( + cx.tcx.sess, + p.span, + E0009, + "cannot bind by-move and by-ref in the same pattern", + ) + .span_label(p.span, "by-move pattern here") + .span_label(by_ref_span, "both by-ref and by-move used") + .emit(); } }; @@ -575,12 +581,19 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, /// assign. /// /// FIXME: this should be done by borrowck. -fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) { +fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Guard) { let mut checker = MutationChecker { cx, }; - ExprUseVisitor::new(&mut checker, cx.tcx, cx.param_env, cx.region_scope_tree, cx.tables, None) - .walk_expr(guard); + match guard { + hir::Guard::If(expr) => + ExprUseVisitor::new(&mut checker, + cx.tcx, + cx.param_env, + cx.region_scope_tree, + cx.tables, + None).walk_expr(expr), + }; } struct MutationChecker<'a, 'tcx: 'a> { diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 91fc6453446a8..59bebbb87a775 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -22,7 +22,7 @@ use std::ptr; use rustc::ty::{self, Instance, query::TyCtxtAt}; use rustc::ty::layout::{self, Align, TargetDataLayout, Size, HasDataLayout}; -use rustc::mir::interpret::{Pointer, AllocId, Allocation, ScalarMaybeUndef, GlobalId, +use rustc::mir::interpret::{Pointer, AllocId, Allocation, ConstValue, ScalarMaybeUndef, GlobalId, EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic, truncate}; pub use rustc::mir::interpret::{write_target_uint, read_target_uint}; @@ -340,9 +340,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { // no need to report anything, the const_eval call takes care of that for statics assert!(tcx.is_static(def_id).is_some()); EvalErrorKind::ReferencedConstant(err).into() - }).map(|val| { - // FIXME We got our static (will be a ByRef), now we make a *copy*?!? - tcx.const_to_allocation(val) + }).map(|const_val| { + if let ConstValue::ByRef(_, allocation, _) = const_val.val { + allocation + } else { + bug!("Matching on non-ByRef static") + } }) } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index f91ff3642cd10..a55f0496c2dee 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -23,7 +23,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(const_fn)] #![feature(core_intrinsics)] #![feature(decl_macro)] #![cfg_attr(stage0, feature(macro_vis_matcher))] @@ -93,7 +92,6 @@ pub fn provide(providers: &mut Providers) { shim::provide(providers); transform::provide(providers); providers.const_eval = interpret::const_eval_provider; - providers.const_to_allocation = interpret::const_to_allocation_provider; providers.check_match = hair::pattern::check_match; } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index f6006ae045ee7..ec7fd371a442b 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -28,6 +28,7 @@ use util; pub struct UnsafetyChecker<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, + min_const_fn: bool, source_scope_local_data: &'a IndexVec, violations: Vec, source_info: SourceInfo, @@ -38,12 +39,16 @@ pub struct UnsafetyChecker<'a, 'tcx: 'a> { } impl<'a, 'gcx, 'tcx> UnsafetyChecker<'a, 'tcx> { - fn new(mir: &'a Mir<'tcx>, - source_scope_local_data: &'a IndexVec, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParamEnv<'tcx>) -> Self { + fn new( + min_const_fn: bool, + mir: &'a Mir<'tcx>, + source_scope_local_data: &'a IndexVec, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> Self { Self { mir, + min_const_fn, source_scope_local_data, violations: vec![], source_info: SourceInfo { @@ -269,6 +274,15 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { fn register_violations(&mut self, violations: &[UnsafetyViolation], unsafe_blocks: &[(ast::NodeId, bool)]) { + if self.min_const_fn { + for violation in violations { + let mut violation = violation.clone(); + violation.kind = UnsafetyViolationKind::MinConstFn; + if !self.violations.contains(&violation) { + self.violations.push(violation) + } + } + } let within_unsafe = match self.source_scope_local_data[self.source_info.scope].safety { Safety::Safe => { for violation in violations { @@ -276,7 +290,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { self.violations.push(violation.clone()) } } - false } Safety::BuiltinUnsafe | Safety::FnUnsafe => true, @@ -369,6 +382,7 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) let param_env = tcx.param_env(def_id); let mut checker = UnsafetyChecker::new( + tcx.is_const_fn(def_id) && tcx.is_min_const_fn(def_id), mir, source_scope_local_data, tcx, param_env); checker.visit_mir(mir); @@ -478,6 +492,15 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { .note(&details.as_str()[..]) .emit(); } + UnsafetyViolationKind::MinConstFn => { + tcx.sess.struct_span_err( + source_info.span, + &format!("{} is unsafe and unsafe operations \ + are not allowed in const fn", description)) + .span_label(source_info.span, &description.as_str()[..]) + .note(&details.as_str()[..]) + .emit(); + } UnsafetyViolationKind::ExternStatic(lint_node_id) => { tcx.lint_node_note(SAFE_EXTERN_STATICS, lint_node_id, diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 90dfebeef1b0c..1e05b07030ef8 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -36,6 +36,7 @@ pub mod elaborate_drops; pub mod add_call_guards; pub mod promote_consts; pub mod qualify_consts; +mod qualify_min_const_fn; pub mod remove_noop_landing_pads; pub mod dump_mir; pub mod deaggregator; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index a3bca6de6c2d7..0d24286869e6f 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -917,9 +917,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { ); } } else if let Some(&attr::Stability { - rustc_const_unstable: Some(attr::RustcConstUnstable { - feature: ref feature_name - }), + const_stability: Some(ref feature_name), .. }) = self.tcx.lookup_stability(def_id) { if // feature-gate is not enabled, @@ -1173,8 +1171,20 @@ impl MirPass for QualifyAndPromoteConstants { let (temps, candidates) = { let mut qualifier = Qualifier::new(tcx, def_id, mir, mode); if mode == Mode::ConstFn { - // Enforce a constant-like CFG for `const fn`. - qualifier.qualify_const(); + if tcx.is_min_const_fn(def_id) { + // enforce `min_const_fn` for stable const fns + use super::qualify_min_const_fn::is_min_const_fn; + if let Err((span, err)) = is_min_const_fn(tcx, def_id, mir) { + tcx.sess.span_err(span, &err); + } else { + // this should not produce any errors, but better safe than sorry + // FIXME(#53819) + qualifier.qualify_const(); + } + } else { + // Enforce a constant-like CFG for `const fn`. + qualifier.qualify_const(); + } } else { while let Some((bb, data)) = qualifier.rpo.next() { qualifier.visit_basic_block_data(bb, data); diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs new file mode 100644 index 0000000000000..56e32ea5d1a23 --- /dev/null +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -0,0 +1,358 @@ +use rustc::hir::def_id::DefId; +use rustc::hir; +use rustc::mir::*; +use rustc::ty::{self, Predicate, TyCtxt}; +use std::borrow::Cow; +use syntax_pos::Span; + +type McfResult = Result<(), (Span, Cow<'static, str>)>; + +pub fn is_min_const_fn( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId, + mir: &'a Mir<'tcx>, +) -> McfResult { + let mut current = def_id; + loop { + let predicates = tcx.predicates_of(current); + for predicate in &predicates.predicates { + match predicate { + | Predicate::RegionOutlives(_) + | Predicate::TypeOutlives(_) + | Predicate::WellFormed(_) + | Predicate::ConstEvaluatable(..) => continue, + | Predicate::ObjectSafe(_) => { + bug!("object safe predicate on function: {:#?}", predicate) + } + Predicate::ClosureKind(..) => { + bug!("closure kind predicate on function: {:#?}", predicate) + } + Predicate::Subtype(_) => bug!("subtype predicate on function: {:#?}", predicate), + Predicate::Projection(_) => { + let span = tcx.def_span(current); + // we'll hit a `Predicate::Trait` later which will report an error + tcx.sess + .delay_span_bug(span, "projection without trait bound"); + continue; + } + Predicate::Trait(pred) => { + if Some(pred.def_id()) == tcx.lang_items().sized_trait() { + continue; + } + match pred.skip_binder().self_ty().sty { + ty::Param(ref p) => { + let generics = tcx.generics_of(current); + let def = generics.type_param(p, tcx); + let span = tcx.def_span(def.def_id); + return Err(( + span, + "trait bounds other than `Sized` \ + on const fn parameters are unstable" + .into(), + )); + } + // other kinds of bounds are either tautologies + // or cause errors in other passes + _ => continue, + } + } + } + } + match predicates.parent { + Some(parent) => current = parent, + None => break, + } + } + + for local in mir.vars_iter() { + return Err(( + mir.local_decls[local].source_info.span, + "local variables in const fn are unstable".into(), + )); + } + for local in &mir.local_decls { + check_ty(tcx, local.ty, local.source_info.span)?; + } + // impl trait is gone in MIR, so check the return type manually + check_ty( + tcx, + tcx.fn_sig(def_id).output().skip_binder(), + mir.local_decls.iter().next().unwrap().source_info.span, + )?; + + for bb in mir.basic_blocks() { + check_terminator(tcx, mir, bb.terminator())?; + for stmt in &bb.statements { + check_statement(tcx, mir, stmt)?; + } + } + Ok(()) +} + +fn check_ty( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: ty::Ty<'tcx>, + span: Span, +) -> McfResult { + for ty in ty.walk() { + match ty.sty { + ty::Ref(_, _, hir::Mutability::MutMutable) => return Err(( + span, + "mutable references in const fn are unstable".into(), + )), + ty::Anon(..) => return Err((span, "`impl Trait` in const fn is unstable".into())), + ty::FnPtr(..) => { + return Err((span, "function pointers in const fn are unstable".into())) + } + ty::Dynamic(preds, _) => { + for pred in preds.iter() { + match pred.skip_binder() { + | ty::ExistentialPredicate::AutoTrait(_) + | ty::ExistentialPredicate::Projection(_) => { + return Err(( + span, + "trait bounds other than `Sized` \ + on const fn parameters are unstable" + .into(), + )) + } + ty::ExistentialPredicate::Trait(trait_ref) => { + if Some(trait_ref.def_id) != tcx.lang_items().sized_trait() { + return Err(( + span, + "trait bounds other than `Sized` \ + on const fn parameters are unstable" + .into(), + )); + } + } + } + } + } + _ => {} + } + } + Ok(()) +} + +fn check_rvalue( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + mir: &'a Mir<'tcx>, + rvalue: &Rvalue<'tcx>, + span: Span, +) -> McfResult { + match rvalue { + Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => { + check_operand(tcx, mir, operand, span) + } + Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) => { + check_place(tcx, mir, place, span, PlaceMode::Read) + } + Rvalue::Cast(_, operand, cast_ty) => { + use rustc::ty::cast::CastTy; + let cast_in = CastTy::from_ty(operand.ty(mir, tcx)).expect("bad input type for cast"); + let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); + match (cast_in, cast_out) { + (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => Err(( + span, + "casting pointers to ints is unstable in const fn".into(), + )), + (CastTy::RPtr(_), CastTy::Float) => bug!(), + (CastTy::RPtr(_), CastTy::Int(_)) => bug!(), + (CastTy::Ptr(_), CastTy::RPtr(_)) => bug!(), + _ => check_operand(tcx, mir, operand, span), + } + } + // binops are fine on integers + Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => { + check_operand(tcx, mir, lhs, span)?; + check_operand(tcx, mir, rhs, span)?; + let ty = lhs.ty(mir, tcx); + if ty.is_integral() || ty.is_bool() || ty.is_char() { + Ok(()) + } else { + Err(( + span, + "only int, `bool` and `char` operations are stable in const fn".into(), + )) + } + } + // checked by regular const fn checks + Rvalue::NullaryOp(..) => Ok(()), + Rvalue::UnaryOp(_, operand) => { + let ty = operand.ty(mir, tcx); + if ty.is_integral() || ty.is_bool() { + check_operand(tcx, mir, operand, span) + } else { + Err(( + span, + "only int and `bool` operations are stable in const fn".into(), + )) + } + } + Rvalue::Aggregate(_, operands) => { + for operand in operands { + check_operand(tcx, mir, operand, span)?; + } + Ok(()) + } + } +} + +enum PlaceMode { + Assign, + Read, +} + +fn check_statement( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + mir: &'a Mir<'tcx>, + statement: &Statement<'tcx>, +) -> McfResult { + let span = statement.source_info.span; + match &statement.kind { + StatementKind::Assign(place, rval) => { + check_place(tcx, mir, place, span, PlaceMode::Assign)?; + check_rvalue(tcx, mir, rval, span) + } + + StatementKind::ReadForMatch(_) => Err((span, "match in const fn is unstable".into())), + + // just an assignment + StatementKind::SetDiscriminant { .. } => Ok(()), + + | StatementKind::InlineAsm { .. } => { + Err((span, "cannot use inline assembly in const fn".into())) + } + + // These are all NOPs + | StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) + | StatementKind::Validate(..) + | StatementKind::EndRegion(_) + | StatementKind::UserAssertTy(..) + | StatementKind::Nop => Ok(()), + } +} + +fn check_operand( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + mir: &'a Mir<'tcx>, + operand: &Operand<'tcx>, + span: Span, +) -> McfResult { + match operand { + Operand::Move(place) | Operand::Copy(place) => { + check_place(tcx, mir, place, span, PlaceMode::Read) + } + Operand::Constant(_) => Ok(()), + } +} + +fn check_place( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + mir: &'a Mir<'tcx>, + place: &Place<'tcx>, + span: Span, + mode: PlaceMode, +) -> McfResult { + match place { + Place::Local(l) => match mode { + PlaceMode::Assign => match mir.local_kind(*l) { + LocalKind::Temp | LocalKind::ReturnPointer => Ok(()), + LocalKind::Arg | LocalKind::Var => { + Err((span, "assignments in const fn are unstable".into())) + } + }, + PlaceMode::Read => Ok(()), + }, + // promoteds are always fine, they are essentially constants + Place::Promoted(_) => Ok(()), + Place::Static(_) => Err((span, "cannot access `static` items in const fn".into())), + Place::Projection(proj) => { + match proj.elem { + | ProjectionElem::Deref | ProjectionElem::Field(..) | ProjectionElem::Index(_) => { + check_place(tcx, mir, &proj.base, span, mode) + } + // slice patterns are unstable + | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { + return Err((span, "slice patterns in const fn are unstable".into())) + } + | ProjectionElem::Downcast(..) => { + Err((span, "`match` or `if let` in `const fn` is unstable".into())) + } + } + } + } +} + +fn check_terminator( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + mir: &'a Mir<'tcx>, + terminator: &Terminator<'tcx>, +) -> McfResult { + let span = terminator.source_info.span; + match &terminator.kind { + | TerminatorKind::Goto { .. } + | TerminatorKind::Return + | TerminatorKind::Resume => Ok(()), + + TerminatorKind::Drop { location, .. } => { + check_place(tcx, mir, location, span, PlaceMode::Read) + } + TerminatorKind::DropAndReplace { location, value, .. } => { + check_place(tcx, mir, location, span, PlaceMode::Read)?; + check_operand(tcx, mir, value, span) + }, + TerminatorKind::SwitchInt { .. } => Err(( + span, + "`if`, `match`, `&&` and `||` are not stable in const fn".into(), + )), + | TerminatorKind::Abort | TerminatorKind::Unreachable => { + Err((span, "const fn with unreachable code is not stable".into())) + } + | TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => { + Err((span, "const fn generators are unstable".into())) + } + + TerminatorKind::Call { + func, + args, + destination: _, + cleanup: _, + } => { + let fn_ty = func.ty(mir, tcx); + if let ty::FnDef(def_id, _) = fn_ty.sty { + if tcx.is_min_const_fn(def_id) { + check_operand(tcx, mir, func, span)?; + + for arg in args { + check_operand(tcx, mir, arg, span)?; + } + Ok(()) + } else { + Err(( + span, + "can only call other `min_const_fn` within a `min_const_fn`".into(), + )) + } + } else { + Err((span, "can only call other const fns within const fn".into())) + } + } + + TerminatorKind::Assert { + cond, + expected: _, + msg: _, + target: _, + cleanup: _, + } => check_operand(tcx, mir, cond, span), + + | TerminatorKind::FalseEdges { .. } | TerminatorKind::FalseUnwind { .. } => span_bug!( + terminator.source_info.span, + "min_const_fn encountered `{:#?}`", + terminator + ), + } +} diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 677255daa289a..ea4fba3e12481 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -178,9 +178,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { } if let Some(&attr::Stability { - rustc_const_unstable: Some(attr::RustcConstUnstable { - feature: ref feature_name - }), + const_stability: Some(ref feature_name), .. }) = self.tcx.lookup_stability(def_id) { let stable_check = // feature-gate is enabled, @@ -579,7 +577,7 @@ fn check_expr_kind<'a, 'tcx>( for index in hirvec_arm.iter() { let _ = v.check_expr(&*index.body); match index.guard { - Some(ref expr) => { + Some(hir::Guard::If(ref expr)) => { let _ = v.check_expr(&expr); }, None => {}, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 95d5fba9668d4..0f6a974230917 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2701,7 +2701,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // This has to happen *after* we determine which pat_idents are variants self.check_consistent_bindings(&arm.pats); - walk_list!(self, visit_expr, &arm.guard); + match arm.guard { + Some(ast::Guard::If(ref expr)) => self.visit_expr(expr), + _ => {} + } self.visit_expr(&arm.body); self.ribs[ValueNS].pop(); diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 6f5655b8cec53..58665b808d988 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1663,7 +1663,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc fn visit_arm(&mut self, arm: &'l ast::Arm) { self.process_var_decl_multi(&arm.pats); - walk_list!(self, visit_expr, &arm.guard); + match arm.guard { + Some(ast::Guard::If(ref expr)) => self.visit_expr(expr), + _ => {} + } self.visit_expr(&arm.body); } diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index e1a3829cd7538..cc5c722e4f619 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -154,8 +154,7 @@ impl<'a> SpanUtils<'a> { let loc = self.sess.source_map().lookup_char_pos(span.lo()); span_bug!( span, - "Mis-counted brackets when breaking path? Parsing '{}' \ - in {}, line {}", + "Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}", self.snippet(span), loc.file.name, loc.line diff --git a/src/librustc_target/abi/call/avr.rs b/src/librustc_target/abi/call/avr.rs new file mode 100644 index 0000000000000..318495d93f2b1 --- /dev/null +++ b/src/librustc_target/abi/call/avr.rs @@ -0,0 +1,43 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(non_upper_case_globals)] + +use abi::call::{FnType, ArgType}; + +fn classify_ret_ty(ret: &mut ArgType) { + if ret.layout.is_aggregate() { + ret.make_indirect(); + } else { + ret.extend_integer_width_to(8); // Is 8 correct? + } +} + +fn classify_arg_ty(arg: &mut ArgType) { + if arg.layout.is_aggregate() { + arg.make_indirect(); + } else { + arg.extend_integer_width_to(8); + } +} + +pub fn compute_abi_info(fty: &mut FnType) { + if !fty.ret.is_ignore() { + classify_ret_ty(&mut fty.ret); + } + + for arg in &mut fty.args { + if arg.is_ignore() { + continue; + } + + classify_arg_ty(arg); + } +} diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 78ed4b2d615a4..c5fefdda54ee6 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -15,6 +15,7 @@ use spec::HasTargetSpec; mod aarch64; mod arm; mod asmjs; +mod avr; mod hexagon; mod mips; mod mips64; @@ -461,6 +462,8 @@ pub enum Conv { X86_64Win64, AmdGpuKernel, + AvrInterrupt, + AvrNonBlockingInterrupt, } /// Metadata describing how the arguments to a native function @@ -517,6 +520,7 @@ impl<'a, Ty> FnType<'a, Ty> { wasm32::compute_abi_info(self) } } + "avr" => avr::compute_abi_info(self), "msp430" => msp430::compute_abi_info(self), "sparc" => sparc::compute_abi_info(cx, self), "sparc64" => sparc64::compute_abi_info(cx, self), diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 16b5241b29aa5..ca08e3fe909a0 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -35,7 +35,8 @@ pub struct TargetDataLayout { pub aggregate_align: Align, /// Alignments for vector types. - pub vector_align: Vec<(Size, Align)> + pub vector_align: Vec<(Size, Align)>, + pub instruction_address_space: u32, } impl Default for TargetDataLayout { @@ -57,13 +58,22 @@ impl Default for TargetDataLayout { vector_align: vec![ (Size::from_bits(64), Align::from_bits(64, 64).unwrap()), (Size::from_bits(128), Align::from_bits(128, 128).unwrap()) - ] + ], + instruction_address_space: 0, } } } impl TargetDataLayout { pub fn parse(target: &Target) -> Result { + // Parse an address space index from a string. + let parse_address_space = |s: &str, cause: &str| { + s.parse::().map_err(|err| { + format!("invalid address space `{}` for `{}` in \"data-layout\": {}", + s, cause, err) + }) + }; + // Parse a bit count from a string. let parse_bits = |s: &str, kind: &str, cause: &str| { s.parse::().map_err(|err| { @@ -96,6 +106,7 @@ impl TargetDataLayout { match spec.split(':').collect::>()[..] { ["e"] => dl.endian = Endian::Little, ["E"] => dl.endian = Endian::Big, + [p] if p.starts_with("P") => dl.instruction_address_space = parse_address_space(&p[1..], "P")?, ["a", ref a..] => dl.aggregate_align = align(a, "a")?, ["f32", ref a..] => dl.f32_align = align(a, "f32")?, ["f64", ref a..] => dl.f64_align = align(a, "f64")?, diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 1e70a806cce89..e4d958e3b6f35 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -22,7 +22,8 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(box_syntax)] -#![feature(const_fn)] +#![cfg_attr(stage0, feature(const_fn))] +#![cfg_attr(not(stage0), feature(min_const_fn))] #![cfg_attr(not(stage0), feature(nll))] #![cfg_attr(not(stage0), feature(infer_outlives_requirements))] #![feature(slice_patterns)] diff --git a/src/librustc_target/spec/abi.rs b/src/librustc_target/spec/abi.rs index 6d8c8eb19f057..831f880212b04 100644 --- a/src/librustc_target/spec/abi.rs +++ b/src/librustc_target/spec/abi.rs @@ -28,6 +28,8 @@ pub enum Abi { Msp430Interrupt, X86Interrupt, AmdGpuKernel, + AvrInterrupt, + AvrNonBlockingInterrupt, // Multiplatform / generic ABIs Rust, @@ -65,6 +67,8 @@ const AbiDatas: &[AbiData] = &[ AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false }, AbiData {abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false }, AbiData {abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false }, + AbiData {abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false }, + AbiData {abi: Abi::AvrNonBlockingInterrupt, name: "avr-non-blocking-interrupt", generic: false }, // Cross-platform ABIs AbiData {abi: Abi::Rust, name: "Rust", generic: true }, diff --git a/src/librustc_target/spec/avr_unknown_unknown.rs b/src/librustc_target/spec/avr_unknown_unknown.rs new file mode 100644 index 0000000000000..1c6debc1ae56d --- /dev/null +++ b/src/librustc_target/spec/avr_unknown_unknown.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "avr-unknown-unknown".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "16".to_string(), + data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".to_string(), + arch: "avr".to_string(), + linker_flavor: LinkerFlavor::Gcc, + target_os: "unknown".to_string(), + target_env: "".to_string(), + target_vendor: "unknown".to_string(), + target_c_int_width: 16.to_string(), + options: TargetOptions { + // jemalloc is not supported on 16-bit targets. + exe_allocation_crate: Some("alloc_system".to_string()), + .. super::none_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 2514909ba75f3..69ced159d755b 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -65,6 +65,7 @@ mod haiku_base; mod hermit_base; mod linux_base; mod linux_musl_base; +mod none_base; mod openbsd_base; mod netbsd_base; mod solaris_base; @@ -361,6 +362,8 @@ supported_targets! { ("aarch64-fuchsia", aarch64_fuchsia), ("x86_64-fuchsia", x86_64_fuchsia), + ("avr-unknown-unknown", avr_unknown_unknown), + ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), ("x86_64-unknown-redox", x86_64_unknown_redox), @@ -433,7 +436,7 @@ pub struct Target { /// Vendor name to use for conditional compilation. pub target_vendor: String, /// Architecture to use for ABI considerations. Valid options: "x86", - /// "x86_64", "arm", "aarch64", "mips", "powerpc", and "powerpc64". + /// "x86_64", "arm", "aarch64", "avr", "mips", "powerpc", and "powerpc64". pub arch: String, /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, diff --git a/src/librustc_target/spec/none_base.rs b/src/librustc_target/spec/none_base.rs new file mode 100644 index 0000000000000..6afdcb6ecf1c5 --- /dev/null +++ b/src/librustc_target/spec/none_base.rs @@ -0,0 +1,37 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::default::Default; +use spec::{LinkerFlavor, LinkArgs, TargetOptions}; + +pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + + args.insert(LinkerFlavor::Gcc, vec![ + // We want to be able to strip as much executable code as possible + // from the linker command line, and this flag indicates to the + // linker that it can avoid linking in dynamic libraries that don't + // actually satisfy any symbols up to that point (as with many other + // resolutions the linker does). This option only applies to all + // following libraries so we're sure to pass it as one of the first + // arguments. + "-Wl,--as-needed".to_string(), + ]); + + TargetOptions { + dynamic_linking: false, + executables: true, + linker_is_gnu: true, + has_rpath: false, + pre_link_args: args, + position_independent_executables: true, + .. Default::default() + } +} diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index ae68584f2446f..6b5abbfa4a6f7 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -663,9 +663,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); }; for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() { - if let Some(ref e) = arm.guard { + if let Some(ref g) = arm.guard { self.diverges.set(pats_diverge); - self.check_expr_has_type_or_error(e, tcx.types.bool); + match g { + hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool), + }; } self.diverges.set(pats_diverge); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 23872ddf2f64b..c7db3debf5a0d 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -26,12 +26,15 @@ use rustc::hir; use std::iter; -fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - it: &hir::ForeignItem, - n_tps: usize, - abi: Abi, - inputs: Vec>, - output: Ty<'tcx>) { +fn equate_intrinsic_type<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + it: &hir::ForeignItem, + n_tps: usize, + abi: Abi, + safety: hir::Unsafety, + inputs: Vec>, + output: Ty<'tcx>, +) { let def_id = tcx.hir.local_def_id(it.id); match it.node { @@ -65,7 +68,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, inputs.into_iter(), output, false, - hir::Unsafety::Unsafe, + safety, abi ))); let cause = ObligationCause::new(it.span, it.id, ObligationCauseCode::IntrinsicType); @@ -78,7 +81,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::ForeignItem) { let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)).as_interned_str()); let name = it.name.as_str(); - let (n_tps, inputs, output) = if name.starts_with("atomic_") { + let (n_tps, inputs, output, unsafety) = if name.starts_with("atomic_") { let split : Vec<&str> = name.split('_').collect(); assert!(split.len() >= 2, "Atomic intrinsic not correct format"); @@ -109,10 +112,14 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return; } }; - (n_tps, inputs, output) + (n_tps, inputs, output, hir::Unsafety::Unsafe) } else if &name[..] == "abort" || &name[..] == "unreachable" { - (0, Vec::new(), tcx.types.never) + (0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe) } else { + let unsafety = match &name[..] { + "size_of" | "min_align_of" => hir::Unsafety::Normal, + _ => hir::Unsafety::Unsafe, + }; let (n_tps, inputs, output) = match &name[..] { "breakpoint" => (0, Vec::new(), tcx.mk_nil()), "size_of" | @@ -327,9 +334,9 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return; } }; - (n_tps, inputs, output) + (n_tps, inputs, output, unsafety) }; - equate_intrinsic_type(tcx, it, n_tps, Abi::RustIntrinsic, inputs, output) + equate_intrinsic_type(tcx, it, n_tps, Abi::RustIntrinsic, unsafety, inputs, output) } /// Type-check `extern "platform-intrinsic" { ... }` functions. @@ -439,7 +446,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } }; - equate_intrinsic_type(tcx, it, n_tps, Abi::PlatformIntrinsic, + equate_intrinsic_type(tcx, it, n_tps, Abi::PlatformIntrinsic, hir::Unsafety::Unsafe, inputs, output) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bbb45c04e4e98..5cc87e12ed069 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -94,7 +94,7 @@ use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin}; use rustc::infer::anon_types::AnonTypeDecl; use rustc::infer::type_variable::{TypeVariableOrigin}; use rustc::middle::region; -use rustc::mir::interpret::{GlobalId}; +use rustc::mir::interpret::{ConstValue, GlobalId}; use rustc::ty::subst::{CanonicalSubsts, UnpackedKind, Subst, Substs}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine}; use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind}; @@ -1178,6 +1178,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, } } } else { + let span = fcx.tcx.sess.source_map().def_span(span); fcx.tcx.sess.span_err(span, "function should have one argument"); } } else { @@ -1226,6 +1227,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, } } } else { + let span = fcx.tcx.sess.source_map().def_span(span); fcx.tcx.sess.span_err(span, "function should have one argument"); } } else { @@ -1375,7 +1377,11 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt, id: DefId, span: Span) { }; let param_env = ty::ParamEnv::reveal_all(); if let Ok(static_) = tcx.const_eval(param_env.and(cid)) { - let alloc = tcx.const_to_allocation(static_); + let alloc = if let ConstValue::ByRef(_, allocation, _) = static_.val { + allocation + } else { + bug!("Matching on non-ByRef static") + }; if alloc.relocations.len() != 0 { let msg = "statics with a custom `#[link_section]` must be a \ simple list of bytes on the wasm target with no \ diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index b7cf6819e2180..edfa62f109538 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -256,14 +256,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let source_map = self.tcx.sess.source_map(); match is_assign { IsAssign::Yes => { - let mut err = struct_span_err!(self.tcx.sess, expr.span, E0368, - "binary assignment operation `{}=` \ - cannot be applied to type `{}`", - op.node.as_str(), - lhs_ty); - err.span_label(lhs_expr.span, - format!("cannot use `{}=` on type `{}`", - op.node.as_str(), lhs_ty)); + let mut err = struct_span_err!( + self.tcx.sess, + expr.span, + E0368, + "binary assignment operation `{}=` cannot be applied to type `{}`", + op.node.as_str(), + lhs_ty, + ); + err.span_label( + lhs_expr.span, + format!("cannot use `{}=` on type `{}`", + op.node.as_str(), lhs_ty), + ); let mut suggested_deref = false; if let Ref(_, mut rty, _) = lhs_ty.sty { if { @@ -280,13 +285,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { rty = rty_inner; } let msg = &format!( - "`{}=` can be used on '{}', you can \ - dereference `{2}`: `*{2}`", - op.node.as_str(), - rty, - lstring + "`{}=` can be used on '{}', you can dereference `{}`", + op.node.as_str(), + rty, + lstring, + ); + err.span_suggestion_with_applicability( + lhs_expr.span, + msg, + format!("*{}", lstring), + errors::Applicability::MachineApplicable, ); - err.help(msg); suggested_deref = true; } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a42667ab45fc8..b956c72b3a2da 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1981,12 +1981,15 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>( decl: &hir::FnDecl, abi: abi::Abi, ) -> ty::PolyFnSig<'tcx> { - let fty = AstConv::ty_of_fn( - &ItemCtxt::new(tcx, def_id), - hir::Unsafety::Unsafe, - abi, - decl, - ); + let unsafety = if abi == abi::Abi::RustIntrinsic { + match &*tcx.item_name(def_id).as_str() { + "size_of" | "min_align_of" => hir::Unsafety::Normal, + _ => hir::Unsafety::Unsafe, + } + } else { + hir::Unsafety::Unsafe + }; + let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), unsafety, abi, decl); // feature gate SIMD types in FFI, since I (huonw) am not sure the // ABIs are handled at all correctly. diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index be51ab5484da7..368c056f021c1 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2956,12 +2956,16 @@ fn item_trait( ")?; + let mut foreign_cache = FxHashSet(); for implementor in foreign { - let assoc_link = AssocItemLink::GotoSource( - implementor.impl_item.def_id, &implementor.inner_impl().provided_trait_methods - ); - render_impl(w, cx, &implementor, assoc_link, - RenderMode::Normal, implementor.impl_item.stable_since(), false)?; + if foreign_cache.insert(implementor.inner_impl().to_string()) { + let assoc_link = AssocItemLink::GotoSource( + implementor.impl_item.def_id, + &implementor.inner_impl().provided_trait_methods + ); + render_impl(w, cx, &implementor, assoc_link, + RenderMode::Normal, implementor.impl_item.stable_since(), false)?; + } } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index df885d8a772fb..1acae86f0068f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -477,7 +477,8 @@ fn main_args(args: &[String]) -> isize { let output = matches.opt_str("o").map(|s| PathBuf::from(&s)); let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s)); - let cfgs = matches.opt_strs("cfg"); + let mut cfgs = matches.opt_strs("cfg"); + cfgs.push("rustdoc".to_string()); if let Some(ref p) = css_file_extension { if !p.is_file() { @@ -671,7 +672,8 @@ where R: 'static + Send, for s in &matches.opt_strs("L") { paths.add_path(s, ErrorOutputType::default()); } - let cfgs = matches.opt_strs("cfg"); + let mut cfgs = matches.opt_strs("cfg"); + cfgs.push("rustdoc".to_string()); let triple = matches.opt_str("target").map(|target| { if target.ends_with(".json") { TargetTriple::TargetPath(PathBuf::from(target)) diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 9066c0b769479..d14a4bb8c494d 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -821,6 +821,7 @@ pub mod consts { /// - x86_64 /// - arm /// - aarch64 + /// - avr /// - mips /// - mips64 /// - powerpc @@ -933,6 +934,11 @@ mod arch { pub const ARCH: &'static str = "aarch64"; } +#[cfg(target_arch = "avr")] +mod arch { + pub const ARCH: &'static str = "avr"; +} + #[cfg(target_arch = "mips")] mod arch { pub const ARCH: &'static str = "mips"; diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 29534696abc5b..3de4a1bd4170b 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -138,7 +138,72 @@ pub trait Error: Debug + Display { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - fn cause(&self) -> Option<&dyn Error> { None } + #[rustc_deprecated(since = "1.33.0", reason = "replaced by Error::source, which can support \ + downcasting")] + fn cause(&self) -> Option<&dyn Error> { + self.source() + } + + /// The lower-level source of this error, if any. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::fmt; + /// + /// #[derive(Debug)] + /// struct SuperError { + /// side: SuperErrorSideKick, + /// } + /// + /// impl fmt::Display for SuperError { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "SuperError is here!") + /// } + /// } + /// + /// impl Error for SuperError { + /// fn description(&self) -> &str { + /// "I'm the superhero of errors" + /// } + /// + /// fn source(&self) -> Option<&(dyn Error + 'static)> { + /// Some(&self.side) + /// } + /// } + /// + /// #[derive(Debug)] + /// struct SuperErrorSideKick; + /// + /// impl fmt::Display for SuperErrorSideKick { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "SuperErrorSideKick is here!") + /// } + /// } + /// + /// impl Error for SuperErrorSideKick { + /// fn description(&self) -> &str { + /// "I'm SuperError side kick" + /// } + /// } + /// + /// fn get_super_error() -> Result<(), SuperError> { + /// Err(SuperError { side: SuperErrorSideKick }) + /// } + /// + /// fn main() { + /// match get_super_error() { + /// Err(e) => { + /// println!("Error: {}", e.description()); + /// println!("Caused by: {}", e.source().unwrap()); + /// } + /// _ => println!("No error"), + /// } + /// } + /// ``` + #[stable(feature = "error_source", since = "1.30.0")] + fn source(&self) -> Option<&(dyn Error + 'static)> { None } /// Get the `TypeId` of `self` #[doc(hidden)] diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs index 4fb367fb6ba52..24965ff693184 100644 --- a/src/libstd/io/lazy.rs +++ b/src/libstd/io/lazy.rs @@ -18,7 +18,6 @@ pub struct Lazy { // We never call `lock.init()`, so it is UB to attempt to acquire this mutex reentrantly! lock: Mutex, ptr: Cell<*mut Arc>, - init: fn() -> Arc, } #[inline] @@ -26,33 +25,32 @@ const fn done() -> *mut Arc { 1_usize as *mut _ } unsafe impl Sync for Lazy {} -impl Lazy { - /// Safety: `init` must not call `get` on the variable that is being - /// initialized. - pub const unsafe fn new(init: fn() -> Arc) -> Lazy { +impl Lazy { + pub const fn new() -> Lazy { Lazy { lock: Mutex::new(), ptr: Cell::new(ptr::null_mut()), - init, } } +} - pub fn get(&'static self) -> Option> { - unsafe { - let _guard = self.lock.lock(); - let ptr = self.ptr.get(); - if ptr.is_null() { - Some(self.init()) - } else if ptr == done() { - None - } else { - Some((*ptr).clone()) - } +impl Lazy { + /// Safety: `init` must not call `get` on the variable that is being + /// initialized. + pub unsafe fn get(&'static self, init: fn() -> Arc) -> Option> { + let _guard = self.lock.lock(); + let ptr = self.ptr.get(); + if ptr.is_null() { + Some(self.init(init)) + } else if ptr == done() { + None + } else { + Some((*ptr).clone()) } } // Must only be called with `lock` held - unsafe fn init(&'static self) -> Arc { + unsafe fn init(&'static self, init: fn() -> Arc) -> Arc { // If we successfully register an at exit handler, then we cache the // `Arc` allocation in our own internal box (it will get deallocated by // the at exit handler). Otherwise we just return the freshly allocated @@ -66,8 +64,8 @@ impl Lazy { }); // This could reentrantly call `init` again, which is a problem // because our `lock` allows reentrancy! - // That's why `new` is unsafe and requires the caller to ensure no reentrancy happens. - let ret = (self.init)(); + // That's why `get` is unsafe and requires the caller to ensure no reentrancy happens. + let ret = init(); if registered.is_ok() { self.ptr.set(Box::into_raw(Box::new(ret.clone()))); } diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 1f256f518c7ce..a413432cdaabc 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -197,9 +197,11 @@ pub struct StdinLock<'a> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn stdin() -> Stdin { - static INSTANCE: Lazy>>> = unsafe { Lazy::new(stdin_init) }; + static INSTANCE: Lazy>>> = Lazy::new(); return Stdin { - inner: INSTANCE.get().expect("cannot access stdin during shutdown"), + inner: unsafe { + INSTANCE.get(stdin_init).expect("cannot access stdin during shutdown") + }, }; fn stdin_init() -> Arc>>> { @@ -396,10 +398,11 @@ pub struct StdoutLock<'a> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn stdout() -> Stdout { - static INSTANCE: Lazy>>>> - = unsafe { Lazy::new(stdout_init) }; + static INSTANCE: Lazy>>>> = Lazy::new(); return Stdout { - inner: INSTANCE.get().expect("cannot access stdout during shutdown"), + inner: unsafe { + INSTANCE.get(stdout_init).expect("cannot access stdout during shutdown") + }, }; fn stdout_init() -> Arc>>>> { @@ -533,10 +536,11 @@ pub struct StderrLock<'a> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn stderr() -> Stderr { - static INSTANCE: Lazy>>> = - unsafe { Lazy::new(stderr_init) }; + static INSTANCE: Lazy>>> = Lazy::new(); return Stderr { - inner: INSTANCE.get().expect("cannot access stderr during shutdown"), + inner: unsafe { + INSTANCE.get(stderr_init).expect("cannot access stderr during shutdown") + }, }; fn stderr_init() -> Arc>>> { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 310475d31fded..e7195b3e21ee3 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -250,7 +250,8 @@ #![feature(cfg_target_vendor)] #![feature(char_error_internals)] #![feature(compiler_builtins_lib)] -#![feature(const_fn)] +#![cfg_attr(stage0, feature(const_fn))] +#![cfg_attr(not(stage0), feature(min_const_fn))] #![feature(const_int_ops)] #![feature(const_ip)] #![feature(core_intrinsics)] diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 6945a41a5e73b..b649ec2340e93 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -309,7 +309,7 @@ macro_rules! assert_approx_eq { /// These macros do not have any corresponding definition with a `macro_rules!` /// macro, but are documented here. Their implementations can be found hardcoded /// into libsyntax itself. -#[cfg(dox)] +#[cfg(rustdoc)] mod builtin { /// Unconditionally causes compilation to fail with the given error message when encountered. diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index 6d8298f01cdce..1cb9799ff3c22 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -14,7 +14,7 @@ #![allow(missing_docs, nonstandard_style, missing_debug_implementations)] cfg_if! { - if #[cfg(dox)] { + if #[cfg(rustdoc)] { // When documenting libstd we want to show unix/windows/linux modules as // these are the "main modules" that are used across platforms. This diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs index c05c837ade274..ccf848a9be420 100644 --- a/src/libstd/sys/cloudabi/condvar.rs +++ b/src/libstd/sys/cloudabi/condvar.rs @@ -28,11 +28,13 @@ pub struct Condvar { unsafe impl Send for Condvar {} unsafe impl Sync for Condvar {} +const NEW: Condvar = Condvar { + condvar: UnsafeCell::new(AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0)), +}; + impl Condvar { pub const fn new() -> Condvar { - Condvar { - condvar: UnsafeCell::new(AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0)), - } + NEW } pub unsafe fn init(&mut self) {} diff --git a/src/libstd/sys/cloudabi/rwlock.rs b/src/libstd/sys/cloudabi/rwlock.rs index 8539aec5e2c07..dc8624ec8a1b8 100644 --- a/src/libstd/sys/cloudabi/rwlock.rs +++ b/src/libstd/sys/cloudabi/rwlock.rs @@ -32,11 +32,13 @@ pub unsafe fn raw(r: &RWLock) -> *mut AtomicU32 { unsafe impl Send for RWLock {} unsafe impl Sync for RWLock {} +const NEW: RWLock = RWLock { + lock: UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)), +}; + impl RWLock { pub const fn new() -> RWLock { - RWLock { - lock: UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)), - } + NEW } pub unsafe fn try_read(&self) -> bool { diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index c44db3b107224..61e4ce66eec0f 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -57,7 +57,7 @@ cfg_if! { // then later used in the `std::os` module when documenting, for example, // Windows when we're compiling for Linux. -#[cfg(dox)] +#[cfg(rustdoc)] cfg_if! { if #[cfg(any(unix, target_os = "redox"))] { // On unix we'll document what's already available @@ -77,7 +77,7 @@ cfg_if! { } } -#[cfg(dox)] +#[cfg(rustdoc)] cfg_if! { if #[cfg(windows)] { // On windows we'll just be documenting what's already available diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 2b9fbc9ef3945..17214be5b0549 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -13,22 +13,22 @@ use io::{self, ErrorKind}; use libc; -#[cfg(any(dox, target_os = "linux"))] pub use os::linux as platform; - -#[cfg(all(not(dox), target_os = "android"))] pub use os::android as platform; -#[cfg(all(not(dox), target_os = "bitrig"))] pub use os::bitrig as platform; -#[cfg(all(not(dox), target_os = "dragonfly"))] pub use os::dragonfly as platform; -#[cfg(all(not(dox), target_os = "freebsd"))] pub use os::freebsd as platform; -#[cfg(all(not(dox), target_os = "haiku"))] pub use os::haiku as platform; -#[cfg(all(not(dox), target_os = "ios"))] pub use os::ios as platform; -#[cfg(all(not(dox), target_os = "macos"))] pub use os::macos as platform; -#[cfg(all(not(dox), target_os = "netbsd"))] pub use os::netbsd as platform; -#[cfg(all(not(dox), target_os = "openbsd"))] pub use os::openbsd as platform; -#[cfg(all(not(dox), target_os = "solaris"))] pub use os::solaris as platform; -#[cfg(all(not(dox), target_os = "emscripten"))] pub use os::emscripten as platform; -#[cfg(all(not(dox), target_os = "fuchsia"))] pub use os::fuchsia as platform; -#[cfg(all(not(dox), target_os = "l4re"))] pub use os::linux as platform; -#[cfg(all(not(dox), target_os = "hermit"))] pub use os::hermit as platform; +#[cfg(any(rustdoc, target_os = "linux"))] pub use os::linux as platform; + +#[cfg(all(not(rustdoc), target_os = "android"))] pub use os::android as platform; +#[cfg(all(not(rustdoc), target_os = "bitrig"))] pub use os::bitrig as platform; +#[cfg(all(not(rustdoc), target_os = "dragonfly"))] pub use os::dragonfly as platform; +#[cfg(all(not(rustdoc), target_os = "freebsd"))] pub use os::freebsd as platform; +#[cfg(all(not(rustdoc), target_os = "haiku"))] pub use os::haiku as platform; +#[cfg(all(not(rustdoc), target_os = "ios"))] pub use os::ios as platform; +#[cfg(all(not(rustdoc), target_os = "macos"))] pub use os::macos as platform; +#[cfg(all(not(rustdoc), target_os = "netbsd"))] pub use os::netbsd as platform; +#[cfg(all(not(rustdoc), target_os = "openbsd"))] pub use os::openbsd as platform; +#[cfg(all(not(rustdoc), target_os = "solaris"))] pub use os::solaris as platform; +#[cfg(all(not(rustdoc), target_os = "emscripten"))] pub use os::emscripten as platform; +#[cfg(all(not(rustdoc), target_os = "fuchsia"))] pub use os::fuchsia as platform; +#[cfg(all(not(rustdoc), target_os = "l4re"))] pub use os::linux as platform; +#[cfg(all(not(rustdoc), target_os = "hermit"))] pub use os::hermit as platform; pub use self::rand::hashmap_random_keys; pub use libc::strlen; diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 8a744519e9175..4c64322a6dce3 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -794,7 +794,7 @@ pub struct FLOATING_SAVE_AREA { // will not appear in the final documentation. This should be also defined for // other architectures supported by Windows such as ARM, and for historical // interest, maybe MIPS and PowerPC as well. -#[cfg(all(dox, not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))))] +#[cfg(all(rustdoc, not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))))] pub enum CONTEXT {} #[cfg(target_arch = "aarch64")] diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bd0e0d277ee54..72f1791ef7c0f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -857,10 +857,15 @@ pub struct Local { pub struct Arm { pub attrs: Vec, pub pats: Vec>, - pub guard: Option>, + pub guard: Option, pub body: P, } +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +pub enum Guard { + If(P), +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Field { pub ident: Ident, diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index ecd52a62eab26..3eecdf14a4e50 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -107,7 +107,11 @@ pub struct Stability { pub level: StabilityLevel, pub feature: Symbol, pub rustc_depr: Option, - pub rustc_const_unstable: Option, + /// `None` means the function is stable but needs to be allowed by the + /// `min_const_fn` feature + /// `Some` contains the feature gate required to be able to use the function + /// as const fn + pub const_stability: Option, } /// The available stability levels. @@ -141,11 +145,6 @@ pub struct RustcDeprecation { pub reason: Symbol, } -#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)] -pub struct RustcConstUnstable { - pub feature: Symbol, -} - /// Check if `attrs` contains an attribute like `#![feature(feature_name)]`. /// This will not perform any "sanity checks" on the form of the attributes. pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool { @@ -176,7 +175,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, let mut stab: Option = None; let mut rustc_depr: Option = None; - let mut rustc_const_unstable: Option = None; + let mut rustc_const_unstable: Option = None; 'outer: for attr in attrs_iter { if ![ @@ -191,6 +190,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, mark_used(attr); let meta = attr.meta(); + // attributes with data if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta { let meta = meta.as_ref().unwrap(); let get = |meta: &MetaItem, item: &mut Option| { @@ -272,9 +272,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, get_meta!(feature); if let Some(feature) = feature { - rustc_const_unstable = Some(RustcConstUnstable { - feature - }); + rustc_const_unstable = Some(feature); } else { span_err!(diagnostic, attr.span(), E0629, "missing 'feature'"); continue @@ -330,7 +328,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, }, feature, rustc_depr: None, - rustc_const_unstable: None, + const_stability: None, }) } (None, _, _) => { @@ -379,7 +377,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, }, feature, rustc_depr: None, - rustc_const_unstable: None, + const_stability: None, }) } (None, _) => { @@ -412,9 +410,9 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, } // Merge the const-unstable info into the stability info - if let Some(rustc_const_unstable) = rustc_const_unstable { + if let Some(feature) = rustc_const_unstable { if let Some(ref mut stab) = stab { - stab.rustc_const_unstable = Some(rustc_const_unstable); + stab.const_stability = Some(feature); } else { span_err!(diagnostic, item_sp, E0630, "rustc_const_unstable attribute must be paired with \ diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index cd9d76822106c..19bbbceff5fc0 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -15,7 +15,7 @@ mod builtin; pub use self::builtin::{ cfg_matches, contains_feature_attr, eval_condition, find_crate_name, find_deprecation, find_repr_attrs, find_stability, find_unwind_attr, Deprecation, InlineAttr, IntType, ReprAttr, - RustcConstUnstable, RustcDeprecation, Stability, StabilityLevel, UnwindAttr, + RustcDeprecation, Stability, StabilityLevel, UnwindAttr, }; pub use self::IntType::*; pub use self::ReprAttr::*; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 080860f17f5dd..aeb454f1016b7 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -40,6 +40,16 @@ use symbol::{keywords, Symbol}; use std::{env, path}; macro_rules! set { + // The const_fn feature also enables the min_const_fn feature, because `min_const_fn` allows + // the declaration `const fn`, but the `const_fn` feature gate enables things inside those + // functions that we do not want to expose to the user for now. + (const_fn) => {{ + fn f(features: &mut Features, _: Span) { + features.const_fn = true; + features.min_const_fn = true; + } + f as fn(&mut Features, Span) + }}; ($field: ident) => {{ fn f(features: &mut Features, _: Span) { features.$field = true; @@ -206,25 +216,28 @@ declare_features! ( // #23121. Array patterns have some hazards yet. (active, slice_patterns, "1.0.0", Some(23121), None), - // Allows the definition of `const fn` functions. + // Allows the definition of `const fn` functions with some advanced features. (active, const_fn, "1.2.0", Some(24111), None), + // Allows the definition of `const fn` functions. + (active, min_const_fn, "1.30.0", Some(53555), None), + // Allows let bindings and destructuring in `const fn` functions and constants. (active, const_let, "1.22.1", Some(48821), None), - // Allows accessing fields of unions inside const fn + // Allows accessing fields of unions inside const fn. (active, const_fn_union, "1.27.0", Some(51909), None), - // Allows casting raw pointers to `usize` during const eval + // Allows casting raw pointers to `usize` during const eval. (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None), - // Allows dereferencing raw pointers during const eval + // Allows dereferencing raw pointers during const eval. (active, const_raw_ptr_deref, "1.27.0", Some(51911), None), - // Allows reinterpretation of the bits of a value of one type as another type during const eval + // Allows reinterpretation of the bits of a value of one type as another type during const eval. (active, const_transmute, "1.29.0", Some(53605), None), - // Allows comparing raw pointers during const eval + // Allows comparing raw pointers during const eval. (active, const_compare_raw_pointers, "1.27.0", Some(53020), None), // Allows panicking during const eval (produces compile-time errors) @@ -333,6 +346,9 @@ declare_features! ( // `extern "x86-interrupt" fn()` (active, abi_x86_interrupt, "1.17.0", Some(40180), None), + // `extern "avr-interrupt" fn()` + (active, abi_avr_interrupt, "1.18.0", Some(000), None), + // Allows the `try {...}` expression (active, try_blocks, "1.29.0", Some(31436), None), @@ -1151,6 +1167,7 @@ const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[ ("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)), ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)), ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)), + ("rustdoc", "doc_cfg", cfg_fn!(doc_cfg)), ]; #[derive(Debug)] @@ -1450,6 +1467,10 @@ impl<'a> PostExpansionVisitor<'a> { Abi::X86Interrupt => { gate_feature_post!(&self, abi_x86_interrupt, span, "x86-interrupt ABI is experimental and subject to change"); + } + Abi::AvrInterrupt | Abi::AvrNonBlockingInterrupt => { + gate_feature_post!(&self, abi_avr_interrupt, span, + "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change"); }, Abi::AmdGpuKernel => { gate_feature_post!(&self, abi_amdgpu_kernel, span, @@ -1786,7 +1807,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, async_await, span, "async fn is unstable"); } if header.constness.node == ast::Constness::Const { - gate_feature_post!(&self, const_fn, span, "const fn is unstable"); + gate_feature_post!(&self, min_const_fn, span, "const fn is unstable"); } // stability of const fn methods are covered in // visit_trait_item and visit_impl_item below; this is @@ -1844,7 +1865,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match ii.node { ast::ImplItemKind::Method(ref sig, _) => { if sig.header.constness.node == ast::Constness::Const { - gate_feature_post!(&self, const_fn, ii.span, "const fn is unstable"); + gate_feature_post!(&self, min_const_fn, ii.span, "const fn is unstable"); } } ast::ImplItemKind::Existential(..) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 660056e15e06b..dff408d233977 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -118,6 +118,10 @@ pub trait Folder : Sized { noop_fold_arm(a, self) } + fn fold_guard(&mut self, g: Guard) -> Guard { + noop_fold_guard(g, self) + } + fn fold_pat(&mut self, p: P) -> P { noop_fold_pat(p, self) } @@ -354,11 +358,17 @@ pub fn noop_fold_arm(Arm {attrs, pats, guard, body}: Arm, Arm { attrs: fold_attrs(attrs, fld), pats: pats.move_map(|x| fld.fold_pat(x)), - guard: guard.map(|x| fld.fold_expr(x)), + guard: guard.map(|x| fld.fold_guard(x)), body: fld.fold_expr(body), } } +pub fn noop_fold_guard(g: Guard, fld: &mut T) -> Guard { + match g { + Guard::If(e) => Guard::If(fld.fold_expr(e)), + } +} + pub fn noop_fold_ty_binding(b: TypeBinding, fld: &mut T) -> TypeBinding { TypeBinding { id: fld.new_id(b.id), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6c50b9c82f2b8..c741bde7c5f24 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -12,7 +12,7 @@ use rustc_target::spec::abi::{self, Abi}; use ast::{AngleBracketedArgs, ParenthesisedArgs, AttrStyle, BareFnTy}; use ast::{GenericBound, TraitBoundModifier}; use ast::Unsafety; -use ast::{Mod, AnonConst, Arg, Arm, Attribute, BindingMode, TraitItemKind}; +use ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind}; use ast::Block; use ast::{BlockCheckMode, CaptureBy, Movability}; use ast::{Constness, Crate}; @@ -3533,7 +3533,7 @@ impl<'a> Parser<'a> { self.eat(&token::BinOp(token::Or)); let pats = self.parse_pats()?; let guard = if self.eat_keyword(keywords::If) { - Some(self.parse_expr()?) + Some(Guard::If(self.parse_expr()?)) } else { None }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e78e1afe3a402..85d29a5be89db 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2702,10 +2702,14 @@ impl<'a> State<'a> { self.print_outer_attributes(&arm.attrs)?; self.print_pats(&arm.pats)?; self.s.space()?; - if let Some(ref e) = arm.guard { - self.word_space("if")?; - self.print_expr(e)?; - self.s.space()?; + if let Some(ref g) = arm.guard { + match g { + ast::Guard::If(ref e) => { + self.word_space("if")?; + self.print_expr(e)?; + self.s.space()?; + } + } } self.word_space("=>")?; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index e57d692faae53..77311bf53fd1e 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -819,7 +819,11 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { walk_list!(visitor, visit_pat, &arm.pats); - walk_list!(visitor, visit_expr, &arm.guard); + if let Some(ref g) = &arm.guard { + match g { + Guard::If(ref e) => visitor.visit_expr(e), + } + } visitor.visit_expr(&arm.body); walk_list!(visitor, visit_attribute, &arm.attrs); } diff --git a/src/llvm b/src/llvm index 2a1cdeadd3ea8..ddf3253b49b0d 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 2a1cdeadd3ea8e1eba9cc681037b83f07332763b +Subproject commit ddf3253b49b0ded85e030e21ff21dad3e2266413 diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 09befdaae37c5..5f5291b0a1b22 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -147,6 +147,12 @@ bool LLVMRustPassManagerBuilderPopulateThinLTOPassManager( #define SUBTARGET_AARCH64 #endif +#ifdef LLVM_COMPONENT_AVR +#define SUBTARGET_AVR SUBTARGET(AVR) +#else +#define SUBTARGET_AVR +#endif + #ifdef LLVM_COMPONENT_MIPS #define SUBTARGET_MIPS SUBTARGET(Mips) #else @@ -193,6 +199,7 @@ bool LLVMRustPassManagerBuilderPopulateThinLTOPassManager( SUBTARGET_X86 \ SUBTARGET_ARM \ SUBTARGET_AARCH64 \ + SUBTARGET_AVR \ SUBTARGET_MIPS \ SUBTARGET_PPC \ SUBTARGET_SYSTEMZ \ diff --git a/src/test/codegen-units/item-collection/unreferenced-const-fn.rs b/src/test/codegen-units/item-collection/unreferenced-const-fn.rs index c2ff846721c5f..1462417643600 100644 --- a/src/test/codegen-units/item-collection/unreferenced-const-fn.rs +++ b/src/test/codegen-units/item-collection/unreferenced-const-fn.rs @@ -13,7 +13,7 @@ // NB: We do not expect *any* monomorphization to be generated here. -#![feature(const_fn)] +#![feature(min_const_fn)] #![deny(dead_code)] #![crate_type = "rlib"] diff --git a/src/test/codegen/link-dead-code.rs b/src/test/codegen/link-dead-code.rs index 9cabcd9157a6a..3ea20aa921e1b 100644 --- a/src/test/codegen/link-dead-code.rs +++ b/src/test/codegen/link-dead-code.rs @@ -10,7 +10,7 @@ // compile-flags:-Clink-dead-code -#![feature(const_fn)] +#![feature(min_const_fn)] #![crate_type = "rlib"] // This test makes sure that, when -Clink-dead-code is specified, we generate diff --git a/src/test/compile-fail/issue-43733-2.rs b/src/test/compile-fail/issue-43733-2.rs index a5ba9ef9bd35d..fea81f0cc8fa4 100644 --- a/src/test/compile-fail/issue-43733-2.rs +++ b/src/test/compile-fail/issue-43733-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] #![feature(cfg_target_thread_local, thread_local_internals)] // On platforms *without* `#[thread_local]`, use diff --git a/src/test/mir-opt/lower_128bit_debug_test.rs b/src/test/mir-opt/lower_128bit_debug_test.rs index 646c4312fc21f..1bf740fdec619 100644 --- a/src/test/mir-opt/lower_128bit_debug_test.rs +++ b/src/test/mir-opt/lower_128bit_debug_test.rs @@ -15,7 +15,7 @@ // compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=yes -#![feature(const_fn)] +#![feature(min_const_fn)] static TEST_SIGNED: i128 = const_signed(-222); static TEST_UNSIGNED: u128 = const_unsigned(200); diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs index b4b54e13a698e..235df8a6785d4 100644 --- a/src/test/mir-opt/lower_128bit_test.rs +++ b/src/test/mir-opt/lower_128bit_test.rs @@ -10,9 +10,9 @@ // ignore-emscripten -// compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no +// compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no -O -#![feature(const_fn)] +#![feature(min_const_fn)] static TEST_SIGNED: i128 = const_signed(-222); static TEST_UNSIGNED: u128 = const_unsigned(200); @@ -63,103 +63,65 @@ fn main() { // END RUST SOURCE // START rustc.const_signed.Lower128Bit.after.mir -// _8 = _1; -// _9 = const compiler_builtins::int::addsub::rust_i128_addo(move _8, const 1i128) -> bb10; -// ... -// _7 = move (_9.0: i128); -// ... -// _10 = const compiler_builtins::int::addsub::rust_i128_subo(move _7, const 2i128) -> bb11; -// ... -// _6 = move (_10.0: i128); -// ... -// _11 = const compiler_builtins::int::mul::rust_i128_mulo(move _6, const 3i128) -> bb12; -// ... -// _5 = move (_11.0: i128); -// ... -// _12 = Eq(const 4i128, const 0i128); -// assert(!move _12, "attempt to divide by zero") -> bb4; -// ... -// _13 = Eq(const 4i128, const -1i128); -// _14 = Eq(_5, const -170141183460469231731687303715884105728i128); -// _15 = BitAnd(move _13, move _14); -// assert(!move _15, "attempt to divide with overflow") -> bb5; -// ... -// _4 = const compiler_builtins::int::sdiv::rust_i128_div(move _5, const 4i128) -> bb13; -// ... -// _17 = Eq(const 5i128, const -1i128); -// _18 = Eq(_4, const -170141183460469231731687303715884105728i128); -// _19 = BitAnd(move _17, move _18); -// assert(!move _19, "attempt to calculate the remainder with overflow") -> bb7; -// ... -// _3 = const compiler_builtins::int::sdiv::rust_i128_rem(move _4, const 5i128) -> bb15; -// ... -// _2 = move (_20.0: i128); -// ... -// _23 = const 7i32 as u128 (Misc); -// _21 = const compiler_builtins::int::shift::rust_i128_shro(move _2, move _23) -> bb16; -// ... -// _0 = move (_21.0: i128); -// ... -// assert(!move (_9.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_10.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_11.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// _16 = Eq(const 5i128, const 0i128); -// assert(!move _16, "attempt to calculate the remainder with a divisor of zero") -> bb6; -// ... -// assert(!move (_20.1: bool), "attempt to shift left with overflow") -> bb8; -// ... -// _22 = const 6i32 as u128 (Misc); -// _20 = const compiler_builtins::int::shift::rust_i128_shlo(move _3, move _22) -> bb14; -// ... -// assert(!move (_21.1: bool), "attempt to shift right with overflow") -> bb9; +// _7 = const compiler_builtins::int::addsub::rust_i128_add(move _8, const 1i128) -> bb7; +// ... +// _10 = Eq(const 4i128, const -1i128); +// _11 = Eq(_5, const -170141183460469231731687303715884105728i128); +// _12 = BitAnd(move _10, move _11); +// assert(!move _12, "attempt to divide with overflow") -> bb2; +// ... +// _4 = const compiler_builtins::int::sdiv::rust_i128_div(move _5, const 4i128) -> bb8; +// ... +// _14 = Eq(const 5i128, const -1i128); +// _15 = Eq(_4, const -170141183460469231731687303715884105728i128); +// _16 = BitAnd(move _14, move _15); +// assert(!move _16, "attempt to calculate the remainder with overflow") -> bb4; +// ... +// _3 = const compiler_builtins::int::sdiv::rust_i128_rem(move _4, const 5i128) -> bb11; +// ... +// _9 = Eq(const 4i128, const 0i128); +// assert(!move _9, "attempt to divide by zero") -> bb1; +// ... +// _5 = const compiler_builtins::int::mul::rust_i128_mul(move _6, const 3i128) -> bb5; +// ... +// _6 = const compiler_builtins::int::addsub::rust_i128_sub(move _7, const 2i128) -> bb6; +// ... +// _13 = Eq(const 5i128, const 0i128); +// assert(!move _13, "attempt to calculate the remainder with a divisor of zero") -> bb3; +// ... +// _17 = const 7i32 as u32 (Misc); +// _0 = const compiler_builtins::int::shift::rust_i128_shr(move _2, move _17) -> bb9; +// ... +// _18 = const 6i32 as u32 (Misc); +// _2 = const compiler_builtins::int::shift::rust_i128_shl(move _3, move _18) -> bb10; // END rustc.const_signed.Lower128Bit.after.mir // START rustc.const_unsigned.Lower128Bit.after.mir -// _8 = _1; -// _9 = const compiler_builtins::int::addsub::rust_u128_addo(move _8, const 1u128) -> bb8; -// ... -// _7 = move (_9.0: u128); -// ... -// _10 = const compiler_builtins::int::addsub::rust_u128_subo(move _7, const 2u128) -> bb9; -// ... -// _6 = move (_10.0: u128); -// ... -// _11 = const compiler_builtins::int::mul::rust_u128_mulo(move _6, const 3u128) -> bb10; -// ... -// _5 = move (_11.0: u128); -// ... -// _12 = Eq(const 4u128, const 0u128); -// assert(!move _12, "attempt to divide by zero") -> bb4; -// ... -// _4 = const compiler_builtins::int::udiv::rust_u128_div(move _5, const 4u128) -> bb11; -// ... -// _3 = const compiler_builtins::int::udiv::rust_u128_rem(move _4, const 5u128) -> bb13; -// ... -// _2 = move (_14.0: u128); -// ... -// _17 = const 7i32 as u128 (Misc); -// _15 = const compiler_builtins::int::shift::rust_u128_shro(move _2, move _17) -> bb14; -// ... -// _0 = move (_15.0: u128); -// ... -// assert(!move (_9.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_10.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_11.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// _13 = Eq(const 5u128, const 0u128); -// assert(!move _13, "attempt to calculate the remainder with a divisor of zero") -> bb5; -// ... -// assert(!move (_14.1: bool), "attempt to shift left with overflow") -> bb6; -// ... -// _16 = const 6i32 as u128 (Misc); -// _14 = const compiler_builtins::int::shift::rust_u128_shlo(move _3, move _16) -> bb12; -// ... -// assert(!move (_15.1: bool), "attempt to shift right with overflow") -> bb7; +// _8 = _1; +// _7 = const compiler_builtins::int::addsub::rust_u128_add(move _8, const 1u128) -> bb5; +// ... +// _4 = const compiler_builtins::int::udiv::rust_u128_div(move _5, const 4u128) -> bb6; +// ... +// _3 = const compiler_builtins::int::udiv::rust_u128_rem(move _4, const 5u128) -> bb9; +// ... +// _9 = Eq(const 4u128, const 0u128); +// assert(!move _9, "attempt to divide by zero") -> bb1; +// ... +// _5 = const compiler_builtins::int::mul::rust_u128_mul(move _6, const 3u128) -> bb3; +// ... +// _6 = const compiler_builtins::int::addsub::rust_u128_sub(move _7, const 2u128) -> bb4; +// ... +// _10 = Eq(const 5u128, const 0u128); +// assert(!move _10, "attempt to calculate the remainder with a divisor of zero") -> bb2; +// ... +// return; +// ... +// _11 = const 7i32 as u32 (Misc); +// _0 = const compiler_builtins::int::shift::rust_u128_shr(move _2, move _11) -> bb7; +// ... +// _12 = const 6i32 as u32 (Misc); +// _2 = const compiler_builtins::int::shift::rust_u128_shl(move _3, move _12) -> bb8; + // END rustc.const_unsigned.Lower128Bit.after.mir // START rustc.test_signed.Lower128Bit.after.mir diff --git a/src/test/run-fail/issue-29798.rs b/src/test/run-fail/issue-29798.rs index a77175975f941..30efe3b9ab2c4 100644 --- a/src/test/run-fail/issue-29798.rs +++ b/src/test/run-fail/issue-29798.rs @@ -10,7 +10,7 @@ // error-pattern:index out of bounds: the len is 5 but the index is 5 -#![feature(const_fn)] +#![feature(min_const_fn)] const fn test(x: usize) -> i32 { [42;5][x] } diff --git a/src/test/run-pass/auxiliary/const_fn_lib.rs b/src/test/run-pass/auxiliary/const_fn_lib.rs index be06e8dd5700b..6985a6527c874 100644 --- a/src/test/run-pass/auxiliary/const_fn_lib.rs +++ b/src/test/run-pass/auxiliary/const_fn_lib.rs @@ -11,6 +11,6 @@ // Crate that exports a const fn. Used for testing cross-crate. #![crate_type="rlib"] -#![feature(const_fn)] +#![feature(min_const_fn)] pub const fn foo() -> usize { 22 } diff --git a/src/test/run-pass/auxiliary/issue-36954.rs b/src/test/run-pass/auxiliary/issue-36954.rs index 832ee1d7c1b45..5351a40916b7d 100644 --- a/src/test/run-pass/auxiliary/issue-36954.rs +++ b/src/test/run-pass/auxiliary/issue-36954.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] #![crate_type = "lib"] const fn foo(i: i32) -> i32 { diff --git a/src/test/run-pass/const-fn-const-eval.rs b/src/test/run-pass/const-fn-const-eval.rs index 77c70fe7f6354..3fe27ca200cb0 100644 --- a/src/test/run-pass/const-fn-const-eval.rs +++ b/src/test/run-pass/const-fn-const-eval.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] const fn add(x: usize, y: usize) -> usize { x + y diff --git a/src/test/run-pass/const-fn-method.rs b/src/test/run-pass/const-fn-method.rs index 7d8d941439cf8..bed78f1e8978f 100644 --- a/src/test/run-pass/const-fn-method.rs +++ b/src/test/run-pass/const-fn-method.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] struct Foo { value: u32 } diff --git a/src/test/run-pass/const-fn-nested.rs b/src/test/run-pass/const-fn-nested.rs index 86f5dedc4d1b1..d5959a89e51a5 100644 --- a/src/test/run-pass/const-fn-nested.rs +++ b/src/test/run-pass/const-fn-nested.rs @@ -10,7 +10,7 @@ // Test a call whose argument is the result of another call. -#![feature(const_fn)] +#![feature(min_const_fn)] const fn sub(x: u32, y: u32) -> u32 { x - y diff --git a/src/test/run-pass/const-meth-pattern.rs b/src/test/run-pass/const-meth-pattern.rs index 3b27987f190cd..836716051d213 100644 --- a/src/test/run-pass/const-meth-pattern.rs +++ b/src/test/run-pass/const-meth-pattern.rs @@ -7,7 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] struct A; diff --git a/src/test/run-pass/const-pattern-variant.rs b/src/test/run-pass/const-pattern-variant.rs index 104ab6e19db67..689ae19e7d4f4 100644 --- a/src/test/run-pass/const-pattern-variant.rs +++ b/src/test/run-pass/const-pattern-variant.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] #[derive(PartialEq, Eq)] enum Cake { diff --git a/src/test/run-pass/const-size_of-align_of.rs b/src/test/run-pass/const-size_of-align_of.rs index 06fbe9bf4f639..245dd673b512c 100644 --- a/src/test/run-pass/const-size_of-align_of.rs +++ b/src/test/run-pass/const-size_of-align_of.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] use std::mem; diff --git a/src/test/run-pass/const-unsafe-fn.rs b/src/test/run-pass/const-unsafe-fn.rs index 2511cfd042206..b267245b78969 100644 --- a/src/test/run-pass/const-unsafe-fn.rs +++ b/src/test/run-pass/const-unsafe-fn.rs @@ -10,7 +10,7 @@ // A quick test of 'unsafe const fn' functionality -#![feature(const_fn)] +#![feature(min_const_fn)] const unsafe fn dummy(v: u32) -> u32 { !v diff --git a/src/test/run-pass/consts-in-patterns.rs b/src/test/run-pass/consts-in-patterns.rs index eec4c940585c0..574fb29e82c7d 100644 --- a/src/test/run-pass/consts-in-patterns.rs +++ b/src/test/run-pass/consts-in-patterns.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] const FOO: isize = 10; const BAR: isize = 3; diff --git a/src/test/run-pass/ctfe/ice-48279.rs b/src/test/run-pass/ctfe/ice-48279.rs index c435e5fdaab4a..f59a6810e3a78 100644 --- a/src/test/run-pass/ctfe/ice-48279.rs +++ b/src/test/run-pass/ctfe/ice-48279.rs @@ -10,7 +10,7 @@ // https://github.com/rust-lang/rust/issues/48279 -#![feature(const_fn)] +#![feature(min_const_fn)] #[derive(PartialEq, Eq)] pub struct NonZeroU32 { diff --git a/src/test/run-pass/ctfe/match-const-fn-structs.rs b/src/test/run-pass/ctfe/match-const-fn-structs.rs index 0bb253d1a6455..352958f4c6a45 100644 --- a/src/test/run-pass/ctfe/match-const-fn-structs.rs +++ b/src/test/run-pass/ctfe/match-const-fn-structs.rs @@ -10,7 +10,7 @@ // https://github.com/rust-lang/rust/issues/46114 -#![feature(const_fn)] +#![feature(min_const_fn)] #[derive(Eq, PartialEq)] struct A { value: u32 } diff --git a/src/test/run-pass/ctfe/return-in-const-fn.rs b/src/test/run-pass/ctfe/return-in-const-fn.rs index d57d3bcb49aa8..87fdac4bfb4fe 100644 --- a/src/test/run-pass/ctfe/return-in-const-fn.rs +++ b/src/test/run-pass/ctfe/return-in-const-fn.rs @@ -10,7 +10,7 @@ // https://github.com/rust-lang/rust/issues/43754 -#![feature(const_fn)] +#![feature(min_const_fn)] const fn foo(x: usize) -> usize { return x; } diff --git a/src/test/run-pass/invalid_const_promotion.rs b/src/test/run-pass/invalid_const_promotion.rs index 53cb4c4b009e5..a18d82fb7a4e7 100644 --- a/src/test/run-pass/invalid_const_promotion.rs +++ b/src/test/run-pass/invalid_const_promotion.rs @@ -11,6 +11,8 @@ // ignore-wasm32 // ignore-emscripten +// compile-flags: -C debug_assertions=yes + #![feature(const_fn, libc)] #![allow(const_err)] @@ -19,7 +21,7 @@ extern crate libc; use std::env; use std::process::{Command, Stdio}; -// this will panic in debug mode +// this will panic in debug mode and overflow in release mode const fn bar() -> usize { 0 - 1 } fn foo() { diff --git a/src/test/run-pass/issue-28822.rs b/src/test/run-pass/issue-28822.rs index 5a010f2be7a34..10482139a978c 100644 --- a/src/test/run-pass/issue-28822.rs +++ b/src/test/run-pass/issue-28822.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] fn main() {} diff --git a/src/test/run-pass/issue-29927.rs b/src/test/run-pass/issue-29927.rs index 6d9adbcd57980..3079d9de3c238 100644 --- a/src/test/run-pass/issue-29927.rs +++ b/src/test/run-pass/issue-29927.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] struct A { field: usize, } diff --git a/src/test/run-pass/issue-33537.rs b/src/test/run-pass/issue-33537.rs index 24f4c9f590b11..7be79f3a45097 100644 --- a/src/test/run-pass/issue-33537.rs +++ b/src/test/run-pass/issue-33537.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] const fn foo() -> *const i8 { b"foo" as *const _ as *const i8 diff --git a/src/test/run-pass/issue-37991.rs b/src/test/run-pass/issue-37991.rs index 9bdde02d0061c..9b3289e67859a 100644 --- a/src/test/run-pass/issue-37991.rs +++ b/src/test/run-pass/issue-37991.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] const fn foo() -> i64 { 3 diff --git a/src/test/run-pass/issue29927-1.rs b/src/test/run-pass/issue29927-1.rs index 68271accb61a2..488bc6e6927a0 100644 --- a/src/test/run-pass/issue29927-1.rs +++ b/src/test/run-pass/issue29927-1.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] const fn f() -> usize { 5 } diff --git a/src/test/rustdoc/auxiliary/issue-27362.rs b/src/test/rustdoc/auxiliary/issue-27362.rs index 25de698cad10e..0c1eedc86ccfd 100644 --- a/src/test/rustdoc/auxiliary/issue-27362.rs +++ b/src/test/rustdoc/auxiliary/issue-27362.rs @@ -10,7 +10,7 @@ // compile-flags: -Cmetadata=aux -#![feature(const_fn)] +#![feature(min_const_fn)] pub const fn foo() {} pub const unsafe fn bar() {} diff --git a/src/test/rustdoc/const-fn.rs b/src/test/rustdoc/const-fn.rs index c323681f60b0a..dc7a2799b46a9 100644 --- a/src/test/rustdoc/const-fn.rs +++ b/src/test/rustdoc/const-fn.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(const_fn)] +#![feature(min_const_fn)] #![crate_name = "foo"] // @has foo/fn.bar.html diff --git a/src/test/rustdoc/const.rs b/src/test/rustdoc/const.rs index 380feb941d6fe..49694e3ae08d1 100644 --- a/src/test/rustdoc/const.rs +++ b/src/test/rustdoc/const.rs @@ -10,7 +10,7 @@ #![crate_type="lib"] -#![feature(const_fn)] +#![feature(min_const_fn)] pub struct Foo; diff --git a/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs b/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs new file mode 100644 index 0000000000000..74888d3e14004 --- /dev/null +++ b/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// run-pass +// aux-build:lint_tool_test.rs +// ignore-stage1 +// compile-flags: -A test-lint + +#![feature(plugin)] +#![warn(unused)] +#![plugin(lint_tool_test)] + +fn lintme() { } + +pub fn main() { +} diff --git a/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr b/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr new file mode 100644 index 0000000000000..c1a9d81874671 --- /dev/null +++ b/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr @@ -0,0 +1,25 @@ +warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint + | + = note: requested on the command line with `-A test_lint` + +warning: item is named 'lintme' + --> $DIR/lint_tool_cmdline_allow.rs:20:1 + | +LL | fn lintme() { } + | ^^^^^^^^^^^^^^^ + | + = note: #[warn(clippy::test_lint)] on by default + +warning: function is never used: `lintme` + --> $DIR/lint_tool_cmdline_allow.rs:20:1 + | +LL | fn lintme() { } + | ^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/lint_tool_cmdline_allow.rs:17:9 + | +LL | #![warn(unused)] + | ^^^^^^ + = note: #[warn(dead_code)] implied by #[warn(unused)] + diff --git a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr index 9b792c46c24b9..e7885537b06bb 100644 --- a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr +++ b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr @@ -1,10 +1,8 @@ error: function should have one argument --> $DIR/alloc-error-handler-bad-signature-3.rs:20:1 | -LL | / fn oom() -> ! { //~ ERROR function should have one argument -LL | | loop {} -LL | | } - | |_^ +LL | fn oom() -> ! { //~ ERROR function should have one argument + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/borrowck/move-in-static-initializer-issue-38520.rs b/src/test/ui/borrowck/move-in-static-initializer-issue-38520.rs index 508e09318ae11..d71c8462587d0 100644 --- a/src/test/ui/borrowck/move-in-static-initializer-issue-38520.rs +++ b/src/test/ui/borrowck/move-in-static-initializer-issue-38520.rs @@ -15,7 +15,7 @@ // permitted as `Foo` is not copy (even in a static/const // initializer). -#![feature(const_fn)] +#![feature(min_const_fn)] struct Foo(usize); diff --git a/src/test/ui/consts/auxiliary/const_fn_lib.rs b/src/test/ui/consts/auxiliary/const_fn_lib.rs index b0d5a6b12727b..499227e71a74c 100644 --- a/src/test/ui/consts/auxiliary/const_fn_lib.rs +++ b/src/test/ui/consts/auxiliary/const_fn_lib.rs @@ -11,6 +11,6 @@ // Crate that exports a const fn. Used for testing cross-crate. #![crate_type="rlib"] -#![feature(const_fn)] +#![feature(min_const_fn)] pub const fn foo() -> usize { 22 } //~ ERROR const fn is unstable diff --git a/src/test/ui/consts/const-eval/issue-43197.rs b/src/test/ui/consts/const-eval/issue-43197.rs index c0b45f0ba3041..200f423f6e39b 100644 --- a/src/test/ui/consts/const-eval/issue-43197.rs +++ b/src/test/ui/consts/const-eval/issue-43197.rs @@ -10,7 +10,7 @@ #![warn(const_err)] -#![feature(const_fn)] +#![feature(min_const_fn)] const fn foo(x: u32) -> u32 { x diff --git a/src/test/ui/consts/const-eval/issue-47971.rs b/src/test/ui/consts/const-eval/issue-47971.rs index f6a2db31d371a..2bc860e3ef94f 100644 --- a/src/test/ui/consts/const-eval/issue-47971.rs +++ b/src/test/ui/consts/const-eval/issue-47971.rs @@ -10,7 +10,7 @@ // compile-pass -#![feature(const_fn)] +#![feature(min_const_fn)] struct S(pub &'static u32, pub u32); diff --git a/src/test/ui/consts/const-pattern-not-const-evaluable.rs b/src/test/ui/consts/const-pattern-not-const-evaluable.rs index 87d5e13df6eb3..4f02b1eef3a0f 100644 --- a/src/test/ui/consts/const-pattern-not-const-evaluable.rs +++ b/src/test/ui/consts/const-pattern-not-const-evaluable.rs @@ -10,7 +10,7 @@ // compile-pass -#![feature(const_fn)] +#![feature(min_const_fn)] #[derive(PartialEq, Eq)] enum Cake { diff --git a/src/test/ui/consts/const-size_of-cycle.rs b/src/test/ui/consts/const-size_of-cycle.rs index fed8e1885de8a..04c054f8b6db2 100644 --- a/src/test/ui/consts/const-size_of-cycle.rs +++ b/src/test/ui/consts/const-size_of-cycle.rs @@ -10,8 +10,6 @@ // error-pattern: cycle detected -#![feature(const_fn)] - struct Foo { bytes: [u8; std::mem::size_of::()] } diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index 16d87f7e31c9b..ab8b5792e681d 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -4,14 +4,14 @@ note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_ note: ...which requires const-evaluating `Foo::bytes::{{constant}}`... --> $SRC_DIR/libcore/mem.rs:LL:COL | -LL | unsafe { intrinsics::size_of::() } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::size_of::() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires computing layout of `Foo`, completing the cycle note: cycle used when const-evaluating `Foo::bytes::{{constant}}` --> $SRC_DIR/libcore/mem.rs:LL:COL | -LL | unsafe { intrinsics::size_of::() } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | intrinsics::size_of::() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error 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 new file mode 100644 index 0000000000000..b156e5a9731da --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr @@ -0,0 +1,224 @@ +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:49:25 + | +LL | const fn into_inner(self) -> T { self.0 } //~ destructors cannot be evaluated + | ^^^^ constant functions cannot evaluate destructors + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:51:5 + | +LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:56:28 + | +LL | const fn into_inner_lt(self) -> T { self.0 } //~ destructors cannot be evaluated + | ^^^^ constant functions cannot evaluate destructors + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:58:5 + | +LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:63:27 + | +LL | const fn into_inner_s(self) -> T { self.0 } //~ ERROR destructors + | ^^^^ constant functions cannot evaluate destructors + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:65:5 + | +LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:70:5 + | +LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:88:16 + | +LL | const fn foo11(t: T) -> T { t } + | ^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:90:18 + | +LL | const fn foo11_2(t: T) -> T { t } + | ^ + +error: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:92:33 + | +LL | const fn foo19(f: f32) -> f32 { f * 2.0 } + | ^^^^^^^ + +error: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:94:35 + | +LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f } + | ^^^^^^^ + +error: only int and `bool` operations are stable in const fn + --> $DIR/min_const_fn.rs:96:35 + | +LL | const fn foo19_3(f: f32) -> f32 { -f } + | ^^ + +error: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:98:43 + | +LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g } + | ^^^^^ + +error: cannot access `static` items in const fn + --> $DIR/min_const_fn.rs:102:27 + | +LL | const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn + | ^^^ + +error: cannot access `static` items in const fn + --> $DIR/min_const_fn.rs:103:36 + | +LL | const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items + | ^^^^ + +error: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:104:42 + | +LL | const fn foo30(x: *const u32) -> usize { x as usize } + | ^^^^^^^^^^ + +error: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:106:42 + | +LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } + | ^^^^^^^^^^ + +error: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:108:38 + | +LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:110:29 + | +LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn + | ^^^^^^^^^^^ + +error: local variables in const fn are unstable + --> $DIR/min_const_fn.rs:111:34 + | +LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn are unstable + | ^ + +error: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:112:44 + | +LL | const fn foo36(a: bool, b: bool) -> bool { a && b } + | ^^^^^^ + +error: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:114:44 + | +LL | const fn foo37(a: bool, b: bool) -> bool { a || b } + | ^^^^^^ + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:116:14 + | +LL | const fn inc(x: &mut i32) { *x += 1 } + | ^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:121:6 + | +LL | impl Foo { + | ^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:126:6 + | +LL | impl Foo { + | ^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:131:6 + | +LL | impl Foo { + | ^ + +error: `impl Trait` in const fn is unstable + --> $DIR/min_const_fn.rs:137:1 + | +LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:139:34 + | +LL | const fn no_apit2(_x: AlanTuring) {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:141:22 + | +LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` + | ^^^^^^^^^^^^^^^^^^^^ + +error: `impl Trait` in const fn is unstable + --> $DIR/min_const_fn.rs:142:1 + | +LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:143:23 + | +LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` + | ^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:144:1 + | +LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0597]: borrowed value does not live long enough + --> $DIR/min_const_fn.rs:144:64 + | +LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } + | ^^ - temporary value only lives until here + | | + | temporary value does not live long enough + | + = note: borrowed value must be valid for the static lifetime... + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:149:41 + | +LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: function pointers in const fn are unstable + --> $DIR/min_const_fn.rs:152:21 + | +LL | const fn no_fn_ptrs(_x: fn()) {} + | ^^ + +error: function pointers in const fn are unstable + --> $DIR/min_const_fn.rs:154:1 + | +LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 36 previous errors + +Some errors occurred: E0493, E0597. +For more information about an error, try `rustc --explain E0493`. 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 new file mode 100644 index 0000000000000..b861e312d4245 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -0,0 +1,156 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(min_const_fn)] + +// ok +const fn foo1() {} +const fn foo2(x: i32) -> i32 { x } +const fn foo3(x: T) -> T { x } +const fn foo7() { + ( + foo1(), + foo2(420), + foo3(69), + ).0 +} +const fn foo12(t: T) -> T { t } +const fn foo13(t: &T) -> &T { t } +const fn foo14<'a, T: 'a>(t: &'a T) -> &'a T { t } +const fn foo15(t: T) -> T where T: Sized { t } +const fn foo15_2(t: &T) -> &T where T: ?Sized { t } +const fn foo16(f: f32) -> f32 { f } +const fn foo17(f: f32) -> u32 { f as u32 } +const fn foo18(i: i32) -> i32 { i * 3 } +const fn foo20(b: bool) -> bool { !b } +const fn foo21(t: T, u: U) -> (T, U) { (t, u) } +const fn foo22(s: &[u8], i: usize) -> u8 { s[i] } +const FOO: u32 = 42; +const fn foo23() -> u32 { FOO } +const fn foo24() -> &'static u32 { &FOO } +const fn foo27(x: &u32) -> u32 { *x } +const fn foo28(x: u32) -> u32 { *&x } +const fn foo29(x: u32) -> i32 { x as i32 } +const fn foo31(a: bool, b: bool) -> bool { a & b } +const fn foo32(a: bool, b: bool) -> bool { a | b } +const fn foo33(a: bool, b: bool) -> bool { a & b } +const fn foo34(a: bool, b: bool) -> bool { a | b } +const fn foo35(a: bool, b: bool) -> bool { a ^ b } +struct Foo(T); +impl Foo { + const fn new(t: T) -> Self { Foo(t) } + const fn into_inner(self) -> T { self.0 } //~ destructors cannot be evaluated + const fn get(&self) -> &T { &self.0 } + const fn get_mut(&mut self) -> &mut T { &mut self.0 } + //~^ mutable references in const fn are unstable +} +impl<'a, T> Foo { + const fn new_lt(t: T) -> Self { Foo(t) } + const fn into_inner_lt(self) -> T { self.0 } //~ destructors cannot be evaluated + const fn get_lt(&'a self) -> &T { &self.0 } + const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } + //~^ mutable references in const fn are unstable +} +impl Foo { + const fn new_s(t: T) -> Self { Foo(t) } + const fn into_inner_s(self) -> T { self.0 } //~ ERROR destructors + const fn get_s(&self) -> &T { &self.0 } + const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } + //~^ mutable references in const fn are unstable +} +impl Foo { + const fn get_sq(&self) -> &T { &self.0 } + const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } + //~^ mutable references in const fn are unstable +} + + +const fn char_ops(c: char, d: char) -> bool { c == d } +const fn char_ops2(c: char, d: char) -> bool { c < d } +const fn char_ops3(c: char, d: char) -> bool { c != d } +const fn i32_ops(c: i32, d: i32) -> bool { c == d } +const fn i32_ops2(c: i32, d: i32) -> bool { c < d } +const fn i32_ops3(c: i32, d: i32) -> bool { c != d } +const fn i32_ops4(c: i32, d: i32) -> i32 { c + d } +const fn char_cast(u: u8) -> char { u as char } +const unsafe fn foo4() -> i32 { 42 } +const unsafe fn foo5() -> *const T { 0 as *const T } +const unsafe fn foo6() -> *mut T { 0 as *mut T } + +// not ok +const fn foo11(t: T) -> T { t } +//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable +const fn foo11_2(t: T) -> T { t } +//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable +const fn foo19(f: f32) -> f32 { f * 2.0 } +//~^ ERROR only int, `bool` and `char` operations are stable in const fn +const fn foo19_2(f: f32) -> f32 { 2.0 - f } +//~^ ERROR only int, `bool` and `char` operations are stable in const fn +const fn foo19_3(f: f32) -> f32 { -f } +//~^ ERROR only int and `bool` operations are stable in const fn +const fn foo19_4(f: f32, g: f32) -> f32 { f / g } +//~^ ERROR only int, `bool` and `char` operations are stable in const fn + +static BAR: u32 = 42; +const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn +const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items +const fn foo30(x: *const u32) -> usize { x as usize } +//~^ ERROR casting pointers to int +const fn foo30_2(x: *mut u32) -> usize { x as usize } +//~^ ERROR casting pointers to int +const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } +//~^ ERROR `if`, `match`, `&&` and `||` 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 } //~ ERROR local variables in const fn are unstable +const fn foo36(a: bool, b: bool) -> bool { a && b } +//~^ ERROR `if`, `match`, `&&` and `||` 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 +const fn inc(x: &mut i32) { *x += 1 } +//~^ ERROR mutable references in const fn are unstable + +fn main() {} + +impl Foo { +//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable + const fn foo(&self) {} +} + +impl Foo { +//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable + const fn foo2(&self) {} +} + +impl Foo { +//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable + const fn foo3(&self) {} +} + +struct AlanTuring(T); +const fn no_rpit2() -> AlanTuring { AlanTuring(0) } +//~^ ERROR `impl Trait` in const fn is unstable +const fn no_apit2(_x: AlanTuring) {} +//~^ ERROR trait bounds other than `Sized` +const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` +const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable +const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` +const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } +//~^ ERROR trait bounds other than `Sized` + +const fn no_unsafe() { unsafe {} } + +const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 } +//~^ ERROR trait bounds other than `Sized` + +const fn no_fn_ptrs(_x: fn()) {} +//~^ ERROR function pointers in const fn are unstable +const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } +//~^ ERROR function pointers 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 new file mode 100644 index 0000000000000..019948c31b15c --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -0,0 +1,213 @@ +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:49:25 + | +LL | const fn into_inner(self) -> T { self.0 } //~ destructors cannot be evaluated + | ^^^^ constant functions cannot evaluate destructors + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:51:5 + | +LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:56:28 + | +LL | const fn into_inner_lt(self) -> T { self.0 } //~ destructors cannot be evaluated + | ^^^^ constant functions cannot evaluate destructors + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:58:5 + | +LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0493]: destructors cannot be evaluated at compile-time + --> $DIR/min_const_fn.rs:63:27 + | +LL | const fn into_inner_s(self) -> T { self.0 } //~ ERROR destructors + | ^^^^ constant functions cannot evaluate destructors + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:65:5 + | +LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:70:5 + | +LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:88:16 + | +LL | const fn foo11(t: T) -> T { t } + | ^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:90:18 + | +LL | const fn foo11_2(t: T) -> T { t } + | ^ + +error: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:92:33 + | +LL | const fn foo19(f: f32) -> f32 { f * 2.0 } + | ^^^^^^^ + +error: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:94:35 + | +LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f } + | ^^^^^^^ + +error: only int and `bool` operations are stable in const fn + --> $DIR/min_const_fn.rs:96:35 + | +LL | const fn foo19_3(f: f32) -> f32 { -f } + | ^^ + +error: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn.rs:98:43 + | +LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g } + | ^^^^^ + +error: cannot access `static` items in const fn + --> $DIR/min_const_fn.rs:102:27 + | +LL | const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn + | ^^^ + +error: cannot access `static` items in const fn + --> $DIR/min_const_fn.rs:103:36 + | +LL | const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items + | ^^^^ + +error: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:104:42 + | +LL | const fn foo30(x: *const u32) -> usize { x as usize } + | ^^^^^^^^^^ + +error: casting pointers to ints is unstable in const fn + --> $DIR/min_const_fn.rs:106:42 + | +LL | const fn foo30_2(x: *mut u32) -> usize { x as usize } + | ^^^^^^^^^^ + +error: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:108:38 + | +LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:110:29 + | +LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn + | ^^^^^^^^^^^ + +error: local variables in const fn are unstable + --> $DIR/min_const_fn.rs:111:34 + | +LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn are unstable + | ^ + +error: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:112:44 + | +LL | const fn foo36(a: bool, b: bool) -> bool { a && b } + | ^^^^^^ + +error: `if`, `match`, `&&` and `||` are not stable in const fn + --> $DIR/min_const_fn.rs:114:44 + | +LL | const fn foo37(a: bool, b: bool) -> bool { a || b } + | ^^^^^^ + +error: mutable references in const fn are unstable + --> $DIR/min_const_fn.rs:116:14 + | +LL | const fn inc(x: &mut i32) { *x += 1 } + | ^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:121:6 + | +LL | impl Foo { + | ^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:126:6 + | +LL | impl Foo { + | ^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:131:6 + | +LL | impl Foo { + | ^ + +error: `impl Trait` in const fn is unstable + --> $DIR/min_const_fn.rs:137:1 + | +LL | const fn no_rpit2() -> AlanTuring { AlanTuring(0) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:139:34 + | +LL | const fn no_apit2(_x: AlanTuring) {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:141:22 + | +LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` + | ^^^^^^^^^^^^^^^^^^^^ + +error: `impl Trait` in const fn is unstable + --> $DIR/min_const_fn.rs:142:1 + | +LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:143:23 + | +LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized` + | ^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:144:1 + | +LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn.rs:149:41 + | +LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: function pointers in const fn are unstable + --> $DIR/min_const_fn.rs:152:21 + | +LL | const fn no_fn_ptrs(_x: fn()) {} + | ^^ + +error: function pointers in const fn are unstable + --> $DIR/min_const_fn.rs:154:1 + | +LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 35 previous errors + +For more information about this error, try `rustc --explain E0493`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr new file mode 100644 index 0000000000000..cfcc7990fb30d --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.nll.stderr @@ -0,0 +1,25 @@ +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn_dyn.rs:21:5 + | +LL | x.0.field; + | ^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn_dyn.rs:24:66 + | +LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } + | ^^ + +error[E0597]: borrowed value does not live long enough + --> $DIR/min_const_fn_dyn.rs:24:67 + | +LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } + | ^ - temporary value only lives until here + | | + | temporary value does not live long enough + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs new file mode 100644 index 0000000000000..38e2825643009 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(min_const_fn)] + +struct HasDyn { + field: &'static dyn std::fmt::Debug, +} + +struct Hide(HasDyn); + +const fn no_inner_dyn_trait(_x: Hide) {} +const fn no_inner_dyn_trait2(x: Hide) { + x.0.field; +//~^ ERROR trait bounds other than `Sized` +} +const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } +//~^ ERROR trait bounds other than `Sized` + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr new file mode 100644 index 0000000000000..3a1055f2ede15 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr @@ -0,0 +1,14 @@ +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn_dyn.rs:21:5 + | +LL | x.0.field; + | ^^^^^^^^^ + +error: trait bounds other than `Sized` on const fn parameters are unstable + --> $DIR/min_const_fn_dyn.rs:24:66 + | +LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } + | ^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.rs b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.rs new file mode 100644 index 0000000000000..100d275f97e73 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.rs @@ -0,0 +1,29 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(min_const_fn)] + +struct HasPtr { + field: fn(), +} + +struct Hide(HasPtr); + +fn field() {} + +const fn no_inner_dyn_trait(_x: Hide) {} +const fn no_inner_dyn_trait2(x: Hide) { + x.0.field; +//~^ ERROR function pointers in const fn +} +const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) } +//~^ ERROR function pointers in const fn + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr new file mode 100644 index 0000000000000..c10af3d2c8e71 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr @@ -0,0 +1,14 @@ +error: function pointers in const fn are unstable + --> $DIR/min_const_fn_fn_ptr.rs:23:5 + | +LL | x.0.field; + | ^^^^^^^^^ + +error: function pointers in const fn are unstable + --> $DIR/min_const_fn_fn_ptr.rs:26:59 + | +LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) } + | ^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs b/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs new file mode 100644 index 0000000000000..fcc9545d97f15 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs @@ -0,0 +1,38 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(integer_atomics, min_const_fn)] + +// compile-pass + +use std::cell::UnsafeCell; +use std::sync::atomic::AtomicU32; +pub struct Condvar { + condvar: UnsafeCell, +} + +unsafe impl Send for Condvar {} +unsafe impl Sync for Condvar {} + +#[repr(C)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +struct NoWait(u32); + +const CONDVAR_HAS_NO_WAITERS: NoWait = NoWait(42); + +impl Condvar { + pub const fn new() -> Condvar { + Condvar { + condvar: UnsafeCell::new(AtomicU32::new(CONDVAR_HAS_NO_WAITERS.0)), + } + } +} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs new file mode 100644 index 0000000000000..9f5d0ad5df3e1 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs @@ -0,0 +1,46 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![unstable(feature = "humans", + reason = "who ever let humans program computers, + we're apparently really bad at it", + issue = "0")] + +#![feature(rustc_const_unstable, const_fn, foo, foo2)] +#![feature(staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature="foo")] +const fn foo() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const fn bar() -> u32 { foo() } //~ ERROR can only call other `min_const_fn` + +#[unstable(feature = "rust1", issue="0")] +const fn foo2() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const fn bar2() -> u32 { foo2() } //~ ERROR can only call other `min_const_fn` + +#[stable(feature = "rust1", since = "1.0.0")] +// conformity is required, even with `const_fn` feature gate +const fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` operations + +// check whether this function cannot be called even with the feature gate active +#[unstable(feature = "foo2", issue="0")] +const fn foo2_gated() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `min_const_fn` + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr new file mode 100644 index 0000000000000..1ef7ffd3a916e --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr @@ -0,0 +1,26 @@ +error: can only call other `min_const_fn` within a `min_const_fn` + --> $DIR/min_const_fn_libstd_stability.rs:25:25 + | +LL | const fn bar() -> u32 { foo() } //~ ERROR can only call other `min_const_fn` + | ^^^^^ + +error: can only call other `min_const_fn` within a `min_const_fn` + --> $DIR/min_const_fn_libstd_stability.rs:32:26 + | +LL | const fn bar2() -> u32 { foo2() } //~ ERROR can only call other `min_const_fn` + | ^^^^^^ + +error: only int, `bool` and `char` operations are stable in const fn + --> $DIR/min_const_fn_libstd_stability.rs:36:26 + | +LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` operations + | ^^^^^^^^^^^^^ + +error: can only call other `min_const_fn` within a `min_const_fn` + --> $DIR/min_const_fn_libstd_stability.rs:44:32 + | +LL | const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `min_const_fn` + | ^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs new file mode 100644 index 0000000000000..e7caa4c6cb426 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs @@ -0,0 +1,38 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(min_const_fn)] + +// ok +const unsafe fn foo4() -> i32 { 42 } +const unsafe fn foo5() -> *const T { 0 as *const T } +const unsafe fn foo6() -> *mut T { 0 as *mut T } +const fn no_unsafe() { unsafe {} } + +// not ok +const fn foo8() -> i32 { + unsafe { foo4() } //~ ERROR unsafe operations are not allowed in const fn +} +const fn foo9() -> *const String { + unsafe { foo5::() } //~ ERROR unsafe operations are not allowed in const fn +} +const fn foo10() -> *const Vec> { + unsafe { foo6::>>() } //~ ERROR not allowed in const fn +} +const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn +//~^ dereferencing raw pointers in constant functions + +fn main() {} + +const unsafe fn no_union() { + union Foo { x: (), y: () } + Foo { x: () }.y //~ ERROR not allowed in const fn + //~^ unions in const fn +} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr new file mode 100644 index 0000000000000..17cba8569c148 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr @@ -0,0 +1,59 @@ +error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911) + --> $DIR/min_const_fn_unsafe.rs:29:51 + | +LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn + | ^^ + | + = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable + +error[E0658]: unions in const fn are unstable (see issue #51909) + --> $DIR/min_const_fn_unsafe.rs:36:5 + | +LL | Foo { x: () }.y //~ ERROR not allowed in const fn + | ^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_fn_union)] to the crate attributes to enable + +error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn + --> $DIR/min_const_fn_unsafe.rs:21:14 + | +LL | unsafe { foo4() } //~ ERROR unsafe operations are not allowed in const fn + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn + --> $DIR/min_const_fn_unsafe.rs:24:14 + | +LL | unsafe { foo5::() } //~ ERROR unsafe operations are not allowed in const fn + | ^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn + --> $DIR/min_const_fn_unsafe.rs:27:14 + | +LL | unsafe { foo6::>>() } //~ ERROR not allowed in const fn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn + --> $DIR/min_const_fn_unsafe.rs:29:51 + | +LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn + | ^^ dereference of raw pointer + | + = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: access to union field is unsafe and unsafe operations are not allowed in const fn + --> $DIR/min_const_fn_unsafe.rs:36:5 + | +LL | Foo { x: () }.y //~ ERROR not allowed in const fn + | ^^^^^^^^^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/enum/enum-discrim-autosizing.rs b/src/test/ui/enum/enum-discrim-autosizing.rs index 3a243330ad9b0..dab22de1b6e58 100644 --- a/src/test/ui/enum/enum-discrim-autosizing.rs +++ b/src/test/ui/enum/enum-discrim-autosizing.rs @@ -18,3 +18,4 @@ enum Eu64 { Bu64 = 0x8000_0000_0000_0000 //~ERROR already exists } +fn main() {} diff --git a/src/test/ui/enum/enum-discrim-autosizing.stderr b/src/test/ui/enum/enum-discrim-autosizing.stderr index 3b4ac436898e6..e4419d6285127 100644 --- a/src/test/ui/enum/enum-discrim-autosizing.stderr +++ b/src/test/ui/enum/enum-discrim-autosizing.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `enum_discrim_autosizing` - | - = note: consider adding a `main` function to `$DIR/enum-discrim-autosizing.rs` - error[E0081]: discriminant value `0` already exists --> $DIR/enum-discrim-autosizing.rs:18:12 | @@ -10,7 +6,6 @@ LL | Au64 = 0, LL | Bu64 = 0x8000_0000_0000_0000 //~ERROR already exists | ^^^^^^^^^^^^^^^^^^^^^ enum already has `0` -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0081, E0601. -For more information about an error, try `rustc --explain E0081`. +For more information about this error, try `rustc --explain E0081`. diff --git a/src/test/ui/error-codes/E0308.stderr b/src/test/ui/error-codes/E0308.stderr index 490a8e0ff0f1d..438dd50f2bfa8 100644 --- a/src/test/ui/error-codes/E0308.stderr +++ b/src/test/ui/error-codes/E0308.stderr @@ -4,8 +4,8 @@ error[E0308]: intrinsic has wrong type LL | fn size_of(); //~ ERROR E0308 | ^^^^^^^^^^^^^^^^ expected (), found usize | - = note: expected type `unsafe extern "rust-intrinsic" fn()` - found type `unsafe extern "rust-intrinsic" fn() -> usize` + = note: expected type `extern "rust-intrinsic" fn()` + found type `extern "rust-intrinsic" fn() -> usize` error: aborting due to previous error diff --git a/src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.rs b/src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.rs new file mode 100644 index 0000000000000..6207d99dc36aa --- /dev/null +++ b/src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[cfg(rustdoc)] //~ ERROR: `cfg(rustdoc)` is experimental and subject to change +pub struct SomeStruct; + +fn main() {} diff --git a/src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.stderr b/src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.stderr new file mode 100644 index 0000000000000..be2c263af042d --- /dev/null +++ b/src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.stderr @@ -0,0 +1,11 @@ +error[E0658]: `cfg(rustdoc)` is experimental and subject to change (see issue #43781) + --> $DIR/feature-gate-doc_cfg-cfg-rustdoc.rs:11:7 + | +LL | #[cfg(rustdoc)] //~ ERROR: `cfg(rustdoc)` is experimental and subject to change + | ^^^^^^^ + | + = help: add #![feature(doc_cfg)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-const_fn.rs b/src/test/ui/feature-gates/feature-gate-const_fn.rs index 1d1dedddaaa3e..f774658975b79 100644 --- a/src/test/ui/feature-gates/feature-gate-const_fn.rs +++ b/src/test/ui/feature-gates/feature-gate-const_fn.rs @@ -8,9 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test use of const fn without feature gate. +// Test use of const fn without the `const_fn` feature gate. +// `min_const_fn` is checked in its own file +#![feature(min_const_fn)] -const fn foo() -> usize { 0 } //~ ERROR const fn is unstable +const fn foo() -> usize { 0 } // ok trait Foo { const fn foo() -> u32; //~ ERROR const fn is unstable @@ -20,12 +22,11 @@ trait Foo { } impl Foo { - const fn baz() -> u32 { 0 } //~ ERROR const fn is unstable + const fn baz() -> u32 { 0 } // ok } impl Foo for u32 { - const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable - //~| ERROR trait fns cannot be declared const + const fn foo() -> u32 { 0 } //~ ERROR trait fns cannot be declared const } static FOO: usize = foo(); diff --git a/src/test/ui/feature-gates/feature-gate-const_fn.stderr b/src/test/ui/feature-gates/feature-gate-const_fn.stderr index d7c00a3e0cb40..26c0c7877b4ec 100644 --- a/src/test/ui/feature-gates/feature-gate-const_fn.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_fn.stderr @@ -1,31 +1,23 @@ error[E0379]: trait fns cannot be declared const - --> $DIR/feature-gate-const_fn.rs:16:5 + --> $DIR/feature-gate-const_fn.rs:18:5 | LL | const fn foo() -> u32; //~ ERROR const fn is unstable | ^^^^^ trait fns cannot be const error[E0379]: trait fns cannot be declared const - --> $DIR/feature-gate-const_fn.rs:18:5 + --> $DIR/feature-gate-const_fn.rs:20:5 | LL | const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable | ^^^^^ trait fns cannot be const error[E0379]: trait fns cannot be declared const - --> $DIR/feature-gate-const_fn.rs:27:5 + --> $DIR/feature-gate-const_fn.rs:29:5 | -LL | const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable +LL | const fn foo() -> u32 { 0 } //~ ERROR trait fns cannot be declared const | ^^^^^ trait fns cannot be const error[E0658]: const fn is unstable (see issue #24111) - --> $DIR/feature-gate-const_fn.rs:13:1 - | -LL | const fn foo() -> usize { 0 } //~ ERROR const fn is unstable - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_fn)] to the crate attributes to enable - -error[E0658]: const fn is unstable (see issue #24111) - --> $DIR/feature-gate-const_fn.rs:16:5 + --> $DIR/feature-gate-const_fn.rs:18:5 | LL | const fn foo() -> u32; //~ ERROR const fn is unstable | ^^^^^^^^^^^^^^^^^^^^^^ @@ -33,30 +25,14 @@ LL | const fn foo() -> u32; //~ ERROR const fn is unstable = help: add #![feature(const_fn)] to the crate attributes to enable error[E0658]: const fn is unstable (see issue #24111) - --> $DIR/feature-gate-const_fn.rs:18:5 + --> $DIR/feature-gate-const_fn.rs:20:5 | LL | const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add #![feature(const_fn)] to the crate attributes to enable -error[E0658]: const fn is unstable (see issue #24111) - --> $DIR/feature-gate-const_fn.rs:23:5 - | -LL | const fn baz() -> u32 { 0 } //~ ERROR const fn is unstable - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_fn)] to the crate attributes to enable - -error[E0658]: const fn is unstable (see issue #24111) - --> $DIR/feature-gate-const_fn.rs:27:5 - | -LL | const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_fn)] to the crate attributes to enable - -error: aborting due to 8 previous errors +error: aborting due to 5 previous errors Some errors occurred: E0379, E0658. For more information about an error, try `rustc --explain E0379`. diff --git a/src/test/ui/feature-gates/feature-gate-min_const_fn.rs b/src/test/ui/feature-gates/feature-gate-min_const_fn.rs new file mode 100644 index 0000000000000..e052ba9c8b43a --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-min_const_fn.rs @@ -0,0 +1,46 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test use of min_const_fn without feature gate. + +const fn foo() -> usize { 0 } //~ ERROR const fn is unstable + +trait Foo { + const fn foo() -> u32; //~ ERROR const fn is unstable + //~| ERROR trait fns cannot be declared const + const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable + //~| ERROR trait fns cannot be declared const +} + +impl Foo { + const fn baz() -> u32 { 0 } //~ ERROR const fn is unstable +} + +impl Foo for u32 { + const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable + //~| ERROR trait fns cannot be declared const +} + +static FOO: usize = foo(); +const BAR: usize = foo(); + +macro_rules! constant { + ($n:ident: $t:ty = $v:expr) => { + const $n: $t = $v; + } +} + +constant! { + BAZ: usize = foo() +} + +fn main() { + let x: [usize; foo()] = []; +} diff --git a/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr b/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr new file mode 100644 index 0000000000000..aa7750362b2fd --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-min_const_fn.stderr @@ -0,0 +1,62 @@ +error[E0379]: trait fns cannot be declared const + --> $DIR/feature-gate-min_const_fn.rs:16:5 + | +LL | const fn foo() -> u32; //~ ERROR const fn is unstable + | ^^^^^ trait fns cannot be const + +error[E0379]: trait fns cannot be declared const + --> $DIR/feature-gate-min_const_fn.rs:18:5 + | +LL | const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable + | ^^^^^ trait fns cannot be const + +error[E0379]: trait fns cannot be declared const + --> $DIR/feature-gate-min_const_fn.rs:27:5 + | +LL | const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable + | ^^^^^ trait fns cannot be const + +error[E0658]: const fn is unstable (see issue #53555) + --> $DIR/feature-gate-min_const_fn.rs:13:1 + | +LL | const fn foo() -> usize { 0 } //~ ERROR const fn is unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(min_const_fn)] to the crate attributes to enable + +error[E0658]: const fn is unstable (see issue #24111) + --> $DIR/feature-gate-min_const_fn.rs:16:5 + | +LL | const fn foo() -> u32; //~ ERROR const fn is unstable + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0658]: const fn is unstable (see issue #24111) + --> $DIR/feature-gate-min_const_fn.rs:18:5 + | +LL | const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(const_fn)] to the crate attributes to enable + +error[E0658]: const fn is unstable (see issue #53555) + --> $DIR/feature-gate-min_const_fn.rs:23:5 + | +LL | const fn baz() -> u32 { 0 } //~ ERROR const fn is unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(min_const_fn)] to the crate attributes to enable + +error[E0658]: const fn is unstable (see issue #53555) + --> $DIR/feature-gate-min_const_fn.rs:27:5 + | +LL | const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(min_const_fn)] to the crate attributes to enable + +error: aborting due to 8 previous errors + +Some errors occurred: E0379, E0658. +For more information about an error, try `rustc --explain E0379`. diff --git a/src/test/ui/gated-bad-feature.rs b/src/test/ui/gated-bad-feature.rs index 5baafd4153159..0d74f9011c3ec 100644 --- a/src/test/ui/gated-bad-feature.rs +++ b/src/test/ui/gated-bad-feature.rs @@ -20,3 +20,5 @@ #![feature = "foo"] //~ ERROR: malformed feature #![feature(test_removed_feature)] //~ ERROR: feature has been removed + +fn main() {} diff --git a/src/test/ui/gated-bad-feature.stderr b/src/test/ui/gated-bad-feature.stderr index 2bed241d68cab..68be49a7277d2 100644 --- a/src/test/ui/gated-bad-feature.stderr +++ b/src/test/ui/gated-bad-feature.stderr @@ -28,11 +28,7 @@ error[E0557]: feature has been removed LL | #![feature(test_removed_feature)] //~ ERROR: feature has been removed | ^^^^^^^^^^^^^^^^^^^^ -error[E0601]: `main` function not found in crate `gated_bad_feature` - | - = note: consider adding a `main` function to `$DIR/gated-bad-feature.rs` - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors occurred: E0555, E0556, E0557, E0601. +Some errors occurred: E0555, E0556, E0557. For more information about an error, try `rustc --explain E0555`. diff --git a/src/test/ui/hygiene/generate-mod.rs b/src/test/ui/hygiene/generate-mod.rs index 2b2108558a0f3..efb3696cf8513 100644 --- a/src/test/ui/hygiene/generate-mod.rs +++ b/src/test/ui/hygiene/generate-mod.rs @@ -55,3 +55,5 @@ fn check_legacy() { struct FromOutside; genmod_legacy!(); } + +fn main() {} diff --git a/src/test/ui/hygiene/generate-mod.stderr b/src/test/ui/hygiene/generate-mod.stderr index 0c5905c5acb4f..f86444bae77e8 100644 --- a/src/test/ui/hygiene/generate-mod.stderr +++ b/src/test/ui/hygiene/generate-mod.stderr @@ -46,11 +46,6 @@ LL | type Inner = Outer; //~ ERROR cannot find type `Outer` in this scop LL | genmod_legacy!(); | ----------------- in this macro invocation -error[E0601]: `main` function not found in crate `generate_mod` - | - = note: consider adding a `main` function to `$DIR/generate-mod.rs` - -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -Some errors occurred: E0412, E0601. -For more information about an error, try `rustc --explain E0412`. +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/hygiene/no_implicit_prelude.rs b/src/test/ui/hygiene/no_implicit_prelude.rs index c90c7b3093c9f..bf07bc05491cc 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.rs +++ b/src/test/ui/hygiene/no_implicit_prelude.rs @@ -23,3 +23,5 @@ mod bar { } fn f() { ::foo::m!(); } } + +fn main() {} diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index b3d82e9094ba7..463fdbf00ce54 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -7,10 +7,6 @@ LL | fn f() { ::bar::m!(); } LL | Vec::new(); //~ ERROR failed to resolve | ^^^ Use of undeclared type or module `Vec` -error[E0601]: `main` function not found in crate `no_implicit_prelude` - | - = note: consider adding a `main` function to `$DIR/no_implicit_prelude.rs` - error[E0599]: no method named `clone` found for type `()` in the current scope --> $DIR/no_implicit_prelude.rs:22:12 | @@ -24,7 +20,7 @@ LL | ().clone() //~ ERROR no method named `clone` found = note: the following trait is implemented but not in scope, perhaps add a `use` for it: `use std::clone::Clone;` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0433, E0599, E0601. +Some errors occurred: E0433, E0599. For more information about an error, try `rustc --explain E0433`. diff --git a/src/test/ui/imports/import-glob-circular.rs b/src/test/ui/imports/import-glob-circular.rs index d9cc17791ed56..b2e92fe0e1bf9 100644 --- a/src/test/ui/imports/import-glob-circular.rs +++ b/src/test/ui/imports/import-glob-circular.rs @@ -25,3 +25,5 @@ mod test { fn test() { f1066(); } //~ ERROR cannot find function `f1066` in this scope } + +fn main() {} diff --git a/src/test/ui/imports/import-glob-circular.stderr b/src/test/ui/imports/import-glob-circular.stderr index 078a6a3937a47..fdff04cc24148 100644 --- a/src/test/ui/imports/import-glob-circular.stderr +++ b/src/test/ui/imports/import-glob-circular.stderr @@ -4,11 +4,6 @@ error[E0425]: cannot find function `f1066` in this scope LL | fn test() { f1066(); } //~ ERROR cannot find function `f1066` in this scope | ^^^^^ not found in this scope -error[E0601]: `main` function not found in crate `import_glob_circular` - | - = note: consider adding a `main` function to `$DIR/import-glob-circular.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0425, E0601. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/imports/import-loop-2.rs b/src/test/ui/imports/import-loop-2.rs index b7bbe11a4dc96..0bc968872db5b 100644 --- a/src/test/ui/imports/import-loop-2.rs +++ b/src/test/ui/imports/import-loop-2.rs @@ -19,3 +19,5 @@ mod b { fn main() { let y = x; } } + +fn main() {} diff --git a/src/test/ui/imports/import-loop-2.stderr b/src/test/ui/imports/import-loop-2.stderr index 717f74643ebb4..09c2e7918f376 100644 --- a/src/test/ui/imports/import-loop-2.stderr +++ b/src/test/ui/imports/import-loop-2.stderr @@ -4,16 +4,6 @@ error[E0432]: unresolved import `a::x` LL | pub use a::x; | ^^^^ no `x` in `a` -error[E0601]: `main` function not found in crate `import_loop_2` - | - = note: the main function must be defined at the crate level but you have one or more functions named 'main' that are not defined at the crate level. Either move the definition or attach the `#[main]` attribute to override this behavior. -note: here is a function named 'main' - --> $DIR/import-loop-2.rs:20:5 - | -LL | fn main() { let y = x; } - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0432, E0601. -For more information about an error, try `rustc --explain E0432`. +For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.rs b/src/test/ui/infinite/infinite-recursion-const-fn.rs index 4f1f67214509e..63ae18cf9c2fa 100644 --- a/src/test/ui/infinite/infinite-recursion-const-fn.rs +++ b/src/test/ui/infinite/infinite-recursion-const-fn.rs @@ -10,7 +10,7 @@ //https://github.com/rust-lang/rust/issues/31364 -#![feature(const_fn)] +#![feature(min_const_fn)] const fn a() -> usize { b() } const fn b() -> usize { a() } const ARR: [i32; a()] = [5; 6]; //~ ERROR could not evaluate constant expression diff --git a/src/test/ui/invalid_crate_type_syntax.rs b/src/test/ui/invalid_crate_type_syntax.rs index 6d42515704ea1..904a9acf9e530 100644 --- a/src/test/ui/invalid_crate_type_syntax.rs +++ b/src/test/ui/invalid_crate_type_syntax.rs @@ -12,3 +12,5 @@ #![crate_type(lib)] //~ ERROR `crate_type` requires a value fn my_lib_fn() {} + +fn main() {} diff --git a/src/test/ui/invalid_crate_type_syntax.stderr b/src/test/ui/invalid_crate_type_syntax.stderr index b609695b86ee5..6f02f96faca93 100644 --- a/src/test/ui/invalid_crate_type_syntax.stderr +++ b/src/test/ui/invalid_crate_type_syntax.stderr @@ -6,10 +6,5 @@ LL | #![crate_type(lib)] //~ ERROR `crate_type` requires a value | = note: for example: `#![crate_type="lib"]` -error[E0601]: `main` function not found in crate `invalid_crate_type_syntax` - | - = note: consider adding a `main` function to `$DIR/invalid_crate_type_syntax.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/issues/issue-38715.rs b/src/test/ui/issues/issue-38715.rs index 552653c21bad6..5c745d1fab3b5 100644 --- a/src/test/ui/issues/issue-38715.rs +++ b/src/test/ui/issues/issue-38715.rs @@ -14,3 +14,5 @@ macro_rules! foo { ($i:ident) => {} } #[macro_export] macro_rules! foo { () => {} } //~ ERROR a macro named `foo` has already been exported //~| WARN this was previously accepted + +fn main() {} diff --git a/src/test/ui/issues/issue-38715.stderr b/src/test/ui/issues/issue-38715.stderr index a0dbcbd18c673..67b27cc83cc89 100644 --- a/src/test/ui/issues/issue-38715.stderr +++ b/src/test/ui/issues/issue-38715.stderr @@ -13,10 +13,5 @@ note: previous macro export is now shadowed LL | macro_rules! foo { ($i:ident) => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0601]: `main` function not found in crate `issue_38715` - | - = note: consider adding a `main` function to `$DIR/issue-38715.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/issues/issue-42755.rs b/src/test/ui/issues/issue-42755.rs index dd53a1c71a5bc..46c8cb740ded7 100644 --- a/src/test/ui/issues/issue-42755.rs +++ b/src/test/ui/issues/issue-42755.rs @@ -15,3 +15,5 @@ macro_rules! foo { } foo!(a); + +fn main() {} diff --git a/src/test/ui/issues/issue-42755.stderr b/src/test/ui/issues/issue-42755.stderr index 9143906199616..fa736edc47f5b 100644 --- a/src/test/ui/issues/issue-42755.stderr +++ b/src/test/ui/issues/issue-42755.stderr @@ -4,10 +4,5 @@ error: repetition matches empty token tree LL | ($($p:vis)*) => {} //~ ERROR repetition matches empty token tree | ^^^^^^^^ -error[E0601]: `main` function not found in crate `issue_42755` - | - = note: consider adding a `main` function to `$DIR/issue-42755.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/issues/issue-43784-associated-type.rs b/src/test/ui/issues/issue-43784-associated-type.rs index 94b5c0034a76d..1ff1238ec54b8 100644 --- a/src/test/ui/issues/issue-43784-associated-type.rs +++ b/src/test/ui/issues/issue-43784-associated-type.rs @@ -23,3 +23,5 @@ impl Partial for T::Assoc where impl Complete for T { //~ ERROR the trait bound `T: std::marker::Copy` is not satisfied type Assoc = T; } + +fn main() {} diff --git a/src/test/ui/issues/issue-43784-associated-type.stderr b/src/test/ui/issues/issue-43784-associated-type.stderr index 798d8c6601668..18e97e24b733a 100644 --- a/src/test/ui/issues/issue-43784-associated-type.stderr +++ b/src/test/ui/issues/issue-43784-associated-type.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `issue_43784_associated_type` - | - = note: consider adding a `main` function to `$DIR/issue-43784-associated-type.rs` - error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied --> $DIR/issue-43784-associated-type.rs:23:9 | @@ -10,7 +6,6 @@ LL | impl Complete for T { //~ ERROR the trait bound `T: std::marker::Copy` i | = help: consider adding a `where T: std::marker::Copy` bound -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0277, E0601. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-43784-supertrait.rs b/src/test/ui/issues/issue-43784-supertrait.rs index e70df113da33c..30132c3be88a7 100644 --- a/src/test/ui/issues/issue-43784-supertrait.rs +++ b/src/test/ui/issues/issue-43784-supertrait.rs @@ -16,3 +16,5 @@ pub trait Complete: Partial { impl Partial for T where T: Complete {} impl Complete for T {} //~ ERROR the trait bound `T: std::marker::Copy` is not satisfied + +fn main() {} diff --git a/src/test/ui/issues/issue-43784-supertrait.stderr b/src/test/ui/issues/issue-43784-supertrait.stderr index 8646b315abdab..422075f62aa0d 100644 --- a/src/test/ui/issues/issue-43784-supertrait.stderr +++ b/src/test/ui/issues/issue-43784-supertrait.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `issue_43784_supertrait` - | - = note: consider adding a `main` function to `$DIR/issue-43784-supertrait.rs` - error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied --> $DIR/issue-43784-supertrait.rs:18:9 | @@ -10,7 +6,6 @@ LL | impl Complete for T {} //~ ERROR the trait bound `T: std::marker::Copy` | = help: consider adding a `where T: std::marker::Copy` bound -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0277, E0601. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-44415.rs b/src/test/ui/issues/issue-44415.rs index 5d295510844ab..bd50f93945c51 100644 --- a/src/test/ui/issues/issue-44415.rs +++ b/src/test/ui/issues/issue-44415.rs @@ -10,7 +10,7 @@ //~^^^^^^^^^^ ERROR cycle detected when computing layout of -#![feature(const_fn)] + #![feature(core_intrinsics)] use std::intrinsics; diff --git a/src/test/ui/issues/issue-52060.rs b/src/test/ui/issues/issue-52060.rs new file mode 100644 index 0000000000000..54eff228934e3 --- /dev/null +++ b/src/test/ui/issues/issue-52060.rs @@ -0,0 +1,8 @@ +// Regression test for https://github.com/rust-lang/rust/issues/52060 +// The compiler shouldn't ICE in this case +static A: &'static [u32] = &[1]; +static B: [u32; 1] = [0; A.len()]; +//~^ ERROR [E0013] +//~| ERROR `core::slice::::len` is not yet stable as a const fn + +fn main() {} diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/issues/issue-52060.stderr new file mode 100644 index 0000000000000..988bfd480e6ad --- /dev/null +++ b/src/test/ui/issues/issue-52060.stderr @@ -0,0 +1,17 @@ +error[E0013]: constants cannot refer to statics, use a constant instead + --> $DIR/issue-52060.rs:4:26 + | +LL | static B: [u32; 1] = [0; A.len()]; + | ^ + +error: `core::slice::::len` is not yet stable as a const fn + --> $DIR/issue-52060.rs:4:26 + | +LL | static B: [u32; 1] = [0; A.len()]; + | ^^^^^^^ + | + = help: in Nightly builds, add `#![feature(const_slice_len)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/issues/issue-5239-1.stderr b/src/test/ui/issues/issue-5239-1.stderr index 7ae01fb7d6012..f9191a9fd8229 100644 --- a/src/test/ui/issues/issue-5239-1.stderr +++ b/src/test/ui/issues/issue-5239-1.stderr @@ -5,8 +5,10 @@ LL | let x = |ref x: isize| { x += 1; }; | -^^^^^ | | | cannot use `+=` on type `&isize` +help: `+=` can be used on 'isize', you can dereference `x` | - = help: `+=` can be used on 'isize', you can dereference `x`: `*x` +LL | let x = |ref x: isize| { *x += 1; }; + | ^^ error: aborting due to previous error diff --git a/src/test/ui/macros/macro-use-bad-args-1.rs b/src/test/ui/macros/macro-use-bad-args-1.rs index a07cc83441173..fefc6ff6ca615 100644 --- a/src/test/ui/macros/macro-use-bad-args-1.rs +++ b/src/test/ui/macros/macro-use-bad-args-1.rs @@ -13,3 +13,5 @@ #[allow(unused_extern_crates)] #[macro_use(foo(bar))] //~ ERROR bad macro import extern crate std; + +fn main() {} diff --git a/src/test/ui/macros/macro-use-bad-args-1.stderr b/src/test/ui/macros/macro-use-bad-args-1.stderr index 19a8c7c0382d1..308fb6c76e1b9 100644 --- a/src/test/ui/macros/macro-use-bad-args-1.stderr +++ b/src/test/ui/macros/macro-use-bad-args-1.stderr @@ -4,11 +4,6 @@ error[E0466]: bad macro import LL | #[macro_use(foo(bar))] //~ ERROR bad macro import | ^^^^^^^^ -error[E0601]: `main` function not found in crate `macro_use_bad_args_1` - | - = note: consider adding a `main` function to `$DIR/macro-use-bad-args-1.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0466, E0601. -For more information about an error, try `rustc --explain E0466`. +For more information about this error, try `rustc --explain E0466`. diff --git a/src/test/ui/macros/macro-use-bad-args-2.rs b/src/test/ui/macros/macro-use-bad-args-2.rs index 89004f1689774..81352cf2e427d 100644 --- a/src/test/ui/macros/macro-use-bad-args-2.rs +++ b/src/test/ui/macros/macro-use-bad-args-2.rs @@ -13,3 +13,5 @@ #[allow(unused_extern_crates)] #[macro_use(foo="bar")] //~ ERROR bad macro import extern crate std; + +fn main() {} diff --git a/src/test/ui/macros/macro-use-bad-args-2.stderr b/src/test/ui/macros/macro-use-bad-args-2.stderr index 0ac18201d791e..62e3c22fab3ec 100644 --- a/src/test/ui/macros/macro-use-bad-args-2.stderr +++ b/src/test/ui/macros/macro-use-bad-args-2.stderr @@ -4,11 +4,6 @@ error[E0466]: bad macro import LL | #[macro_use(foo="bar")] //~ ERROR bad macro import | ^^^^^^^^^ -error[E0601]: `main` function not found in crate `macro_use_bad_args_2` - | - = note: consider adding a `main` function to `$DIR/macro-use-bad-args-2.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0466, E0601. -For more information about an error, try `rustc --explain E0466`. +For more information about this error, try `rustc --explain E0466`. diff --git a/src/test/ui/nested-ty-params.rs b/src/test/ui/nested-ty-params.rs index aac37289bb749..2378cccf56f76 100644 --- a/src/test/ui/nested-ty-params.rs +++ b/src/test/ui/nested-ty-params.rs @@ -14,3 +14,5 @@ fn hd(v: Vec ) -> U { return hd1(v); } + +fn main() {} diff --git a/src/test/ui/nested-ty-params.stderr b/src/test/ui/nested-ty-params.stderr index 93b934f610f8c..58b6cd18989f2 100644 --- a/src/test/ui/nested-ty-params.stderr +++ b/src/test/ui/nested-ty-params.stderr @@ -18,11 +18,6 @@ LL | fn hd1(w: [U]) -> U { return w[0]; } | | | help: try using a local type parameter instead: `hd1` -error[E0601]: `main` function not found in crate `nested_ty_params` - | - = note: consider adding a `main` function to `$DIR/nested-ty-params.rs` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0401, E0601. -For more information about an error, try `rustc --explain E0401`. +For more information about this error, try `rustc --explain E0401`. diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-3.stderr b/src/test/ui/panic-handler/panic-handler-bad-signature-3.stderr index 0eb0d4e10004b..5d0395e17f54d 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-3.stderr +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-3.stderr @@ -1,10 +1,8 @@ error: function should have one argument --> $DIR/panic-handler-bad-signature-3.rs:20:1 | -LL | / fn panic() -> ! { //~ ERROR function should have one argument -LL | | loop {} -LL | | } - | |_^ +LL | fn panic() -> ! { //~ ERROR function should have one argument + | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/repr/repr-transparent-other-items.rs b/src/test/ui/repr/repr-transparent-other-items.rs index 685d62dc3a9c8..be6f3cf9eb205 100644 --- a/src/test/ui/repr/repr-transparent-other-items.rs +++ b/src/test/ui/repr/repr-transparent-other-items.rs @@ -36,3 +36,5 @@ fn cant_repr_this() {} #[repr(transparent)] //~ ERROR should be applied to struct static CANT_REPR_THIS: u32 = 0; + +fn main() {} diff --git a/src/test/ui/repr/repr-transparent-other-items.stderr b/src/test/ui/repr/repr-transparent-other-items.stderr index e5889cf53e58a..5a1978991480e 100644 --- a/src/test/ui/repr/repr-transparent-other-items.stderr +++ b/src/test/ui/repr/repr-transparent-other-items.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `repr_transparent_other_items` - | - = note: consider adding a `main` function to `$DIR/repr-transparent-other-items.rs` - error[E0517]: attribute should be applied to struct --> $DIR/repr-transparent-other-items.rs:13:8 | @@ -67,7 +63,7 @@ LL | #[repr(transparent)] //~ ERROR unsupported representation for zero-variant LL | enum Void {} //~| ERROR should be applied to struct | ------------ zero-variant enum -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors occurred: E0084, E0517, E0601. +Some errors occurred: E0084, E0517. For more information about an error, try `rustc --explain E0084`. diff --git a/src/test/ui/repr/repr-transparent-other-reprs.rs b/src/test/ui/repr/repr-transparent-other-reprs.rs index fa5f1a2f7fb80..aed8a69f66ef8 100644 --- a/src/test/ui/repr/repr-transparent-other-reprs.rs +++ b/src/test/ui/repr/repr-transparent-other-reprs.rs @@ -26,3 +26,5 @@ struct TransparentPlusAlign(u8); #[repr(transparent)] //~ ERROR cannot have other repr #[repr(C)] struct SeparateAttributes(*mut u8); + +fn main() {} diff --git a/src/test/ui/repr/repr-transparent-other-reprs.stderr b/src/test/ui/repr/repr-transparent-other-reprs.stderr index 40f41c474dbda..c8f5dea3c1242 100644 --- a/src/test/ui/repr/repr-transparent-other-reprs.stderr +++ b/src/test/ui/repr/repr-transparent-other-reprs.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `repr_transparent_other_reprs` - | - = note: consider adding a `main` function to `$DIR/repr-transparent-other-reprs.rs` - error[E0692]: transparent struct cannot have other repr hints --> $DIR/repr-transparent-other-reprs.rs:15:8 | @@ -28,7 +24,6 @@ LL | #[repr(transparent)] //~ ERROR cannot have other repr LL | #[repr(C)] | ^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors occurred: E0601, E0692. -For more information about an error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0692`. diff --git a/src/test/ui/repr/repr-transparent.rs b/src/test/ui/repr/repr-transparent.rs index 230573247316e..f5b99af156ee0 100644 --- a/src/test/ui/repr/repr-transparent.rs +++ b/src/test/ui/repr/repr-transparent.rs @@ -48,3 +48,5 @@ struct ZstAlign32(PhantomData); #[repr(transparent)] struct GenericAlign(ZstAlign32, u32); //~ ERROR alignment larger than 1 + +fn main() {} diff --git a/src/test/ui/repr/repr-transparent.stderr b/src/test/ui/repr/repr-transparent.stderr index 0f620880fa9d3..f7bfdbdc625bb 100644 --- a/src/test/ui/repr/repr-transparent.stderr +++ b/src/test/ui/repr/repr-transparent.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `repr_transparent` - | - = note: consider adding a `main` function to `$DIR/repr-transparent.rs` - error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0 --> $DIR/repr-transparent.rs:21:1 | @@ -70,7 +66,7 @@ error[E0691]: zero-sized field in transparent struct has alignment larger than 1 LL | struct GenericAlign(ZstAlign32, u32); //~ ERROR alignment larger than 1 | ^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors -Some errors occurred: E0601, E0690, E0691. -For more information about an error, try `rustc --explain E0601`. +Some errors occurred: E0690, E0691. +For more information about an error, try `rustc --explain E0690`. diff --git a/src/test/ui/resolve/resolve-unknown-trait.rs b/src/test/ui/resolve/resolve-unknown-trait.rs index 9432e727fa5b7..05bf4b928b725 100644 --- a/src/test/ui/resolve/resolve-unknown-trait.rs +++ b/src/test/ui/resolve/resolve-unknown-trait.rs @@ -17,3 +17,5 @@ impl SomeNonExistentTrait for isize {} fn f() {} //~^ ERROR cannot find trait `SomeNonExistentTrait` in this scope + +fn main() {} diff --git a/src/test/ui/resolve/resolve-unknown-trait.stderr b/src/test/ui/resolve/resolve-unknown-trait.stderr index 8a2d791654d2f..74b190f86845f 100644 --- a/src/test/ui/resolve/resolve-unknown-trait.stderr +++ b/src/test/ui/resolve/resolve-unknown-trait.stderr @@ -16,11 +16,6 @@ error[E0405]: cannot find trait `SomeNonExistentTrait` in this scope LL | fn f() {} | ^^^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0601]: `main` function not found in crate `resolve_unknown_trait` - | - = note: consider adding a `main` function to `$DIR/resolve-unknown-trait.rs` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors occurred: E0405, E0601. -For more information about an error, try `rustc --explain E0405`. +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve_self_super_hint.rs b/src/test/ui/resolve_self_super_hint.rs index a89fd802baf0c..c5dd367c0ab88 100644 --- a/src/test/ui/resolve_self_super_hint.rs +++ b/src/test/ui/resolve_self_super_hint.rs @@ -32,3 +32,5 @@ mod a { } } } + +fn main() {} diff --git a/src/test/ui/resolve_self_super_hint.stderr b/src/test/ui/resolve_self_super_hint.stderr index 8538da06baf64..40b2a4bf96842 100644 --- a/src/test/ui/resolve_self_super_hint.stderr +++ b/src/test/ui/resolve_self_super_hint.stderr @@ -22,11 +22,6 @@ error[E0432]: unresolved import `alloc` LL | use alloc::HashMap; | ^^^^^ Did you mean `a::alloc`? -error[E0601]: `main` function not found in crate `resolve_self_super_hint` - | - = note: consider adding a `main` function to `$DIR/resolve_self_super_hint.rs` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors occurred: E0432, E0601. -For more information about an error, try `rustc --explain E0432`. +For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/specialization/defaultimpl/validation.rs b/src/test/ui/specialization/defaultimpl/validation.rs index 26b8b737f340d..068eb7a448556 100644 --- a/src/test/ui/specialization/defaultimpl/validation.rs +++ b/src/test/ui/specialization/defaultimpl/validation.rs @@ -21,3 +21,5 @@ default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default trait Tr {} default impl !Tr for S {} //~ ERROR negative impls are only allowed for auto traits + +fn main() {} diff --git a/src/test/ui/specialization/defaultimpl/validation.stderr b/src/test/ui/specialization/defaultimpl/validation.stderr index 54b92da7b2192..c25c428eb4e94 100644 --- a/src/test/ui/specialization/defaultimpl/validation.stderr +++ b/src/test/ui/specialization/defaultimpl/validation.stderr @@ -6,10 +6,6 @@ LL | default impl S {} //~ ERROR inherent impls cannot be default | = note: only trait implementations may be annotated with default -error[E0601]: `main` function not found in crate `validation` - | - = note: consider adding a `main` function to `$DIR/validation.rs` - error: impls of auto traits cannot be default --> $DIR/validation.rs:19:1 | @@ -28,7 +24,6 @@ error[E0192]: negative impls are only allowed for auto traits (e.g., `Send` and LL | default impl !Tr for S {} //~ ERROR negative impls are only allowed for auto traits | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors occurred: E0192, E0601. -For more information about an error, try `rustc --explain E0192`. +For more information about this error, try `rustc --explain E0192`. diff --git a/src/test/ui/tuple/tuple-struct-fields/test.rs b/src/test/ui/tuple/tuple-struct-fields/test.rs index 22d54a3834073..c8b77bfabdb95 100644 --- a/src/test/ui/tuple/tuple-struct-fields/test.rs +++ b/src/test/ui/tuple/tuple-struct-fields/test.rs @@ -15,3 +15,5 @@ mod foo { //~^ ERROR expected one of `)` or `,`, found `(` //~| ERROR cannot find type `foo` in this scope } + +fn main() {} diff --git a/src/test/ui/tuple/tuple-struct-fields/test.stderr b/src/test/ui/tuple/tuple-struct-fields/test.stderr index 59228ea8c14d2..f83e9dd5458fb 100644 --- a/src/test/ui/tuple/tuple-struct-fields/test.stderr +++ b/src/test/ui/tuple/tuple-struct-fields/test.stderr @@ -10,11 +10,6 @@ error[E0412]: cannot find type `foo` in this scope LL | struct S2(pub((foo)) ()); | ^^^ not found in this scope -error[E0601]: `main` function not found in crate `test` - | - = note: consider adding a `main` function to `$DIR/test.rs` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0412, E0601. -For more information about an error, try `rustc --explain E0412`. +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/unresolved/unresolved-import.rs b/src/test/ui/unresolved/unresolved-import.rs index a3eeb6de96bda..efa7494647691 100644 --- a/src/test/ui/unresolved/unresolved-import.rs +++ b/src/test/ui/unresolved/unresolved-import.rs @@ -55,3 +55,5 @@ mod items { fn item() {} } + +fn main() {} diff --git a/src/test/ui/unresolved/unresolved-import.stderr b/src/test/ui/unresolved/unresolved-import.stderr index 1e663cde48a65..9bcebb0011a75 100644 --- a/src/test/ui/unresolved/unresolved-import.stderr +++ b/src/test/ui/unresolved/unresolved-import.stderr @@ -34,11 +34,6 @@ error[E0432]: unresolved import `Enum` LL | use Enum::*; //~ ERROR unresolved import `Enum` [E0432] | ^^^^ Did you mean `self::Enum`? -error[E0601]: `main` function not found in crate `unresolved_import` - | - = note: consider adding a `main` function to `$DIR/unresolved-import.rs` - -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -Some errors occurred: E0432, E0601. -For more information about an error, try `rustc --explain E0432`. +For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/unsafe/unsafe-const-fn.rs b/src/test/ui/unsafe/unsafe-const-fn.rs index 765e2059a4b5e..fe0bb7533a86f 100644 --- a/src/test/ui/unsafe/unsafe-const-fn.rs +++ b/src/test/ui/unsafe/unsafe-const-fn.rs @@ -10,7 +10,7 @@ // A quick test of 'unsafe const fn' functionality -#![feature(const_fn)] +#![feature(min_const_fn)] const unsafe fn dummy(v: u32) -> u32 { !v diff --git a/src/test/ui/user-defined-macro-rules.rs b/src/test/ui/user-defined-macro-rules.rs index 02e1a585fa89d..fe76d58f1ef76 100644 --- a/src/test/ui/user-defined-macro-rules.rs +++ b/src/test/ui/user-defined-macro-rules.rs @@ -11,3 +11,5 @@ #![allow(unused_macros)] macro_rules! macro_rules { () => {} } //~ ERROR user-defined macros may not be named `macro_rules` + +fn main() {} diff --git a/src/test/ui/user-defined-macro-rules.stderr b/src/test/ui/user-defined-macro-rules.stderr index 3359aa4bcd720..1f8b18166c9c9 100644 --- a/src/test/ui/user-defined-macro-rules.stderr +++ b/src/test/ui/user-defined-macro-rules.stderr @@ -4,10 +4,5 @@ error: user-defined macros may not be named `macro_rules` LL | macro_rules! macro_rules { () => {} } //~ ERROR user-defined macros may not be named `macro_rules` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0601]: `main` function not found in crate `user_defined_macro_rules` - | - = note: consider adding a `main` function to `$DIR/user-defined-macro-rules.rs` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/wasm-custom-section-relocations.rs b/src/test/ui/wasm-custom-section-relocations.rs index 5631a70192afd..9f431e7806139 100644 --- a/src/test/ui/wasm-custom-section-relocations.rs +++ b/src/test/ui/wasm-custom-section-relocations.rs @@ -21,3 +21,5 @@ pub static C: usize = 3; #[link_section = "test"] pub static D: &usize = &C; //~ ERROR: no extra levels of indirection + +fn main() {} diff --git a/src/test/ui/wasm-custom-section-relocations.stderr b/src/test/ui/wasm-custom-section-relocations.stderr index 9b96b99e02ae4..cea6e5c41923a 100644 --- a/src/test/ui/wasm-custom-section-relocations.stderr +++ b/src/test/ui/wasm-custom-section-relocations.stderr @@ -1,7 +1,3 @@ -error[E0601]: `main` function not found in crate `wasm_custom_section_relocations` - | - = note: consider adding a `main` function to `$DIR/wasm-custom-section-relocations.rs` - error: statics with a custom `#[link_section]` must be a simple list of bytes on the wasm target with no extra levels of indirection such as references --> $DIR/wasm-custom-section-relocations.rs:14:1 | @@ -14,6 +10,5 @@ error: statics with a custom `#[link_section]` must be a simple list of bytes on LL | pub static D: &usize = &C; //~ ERROR: no extra levels of indirection | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 2a716970ca7b9..9c77627954118 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -31,6 +31,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("linux", "linux"), ("mingw32", "windows"), ("netbsd", "netbsd"), + ("none", "none"), ("openbsd", "openbsd"), ("redox", "redox"), ("solaris", "solaris"), @@ -48,6 +49,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("armv7", "arm"), ("armv7s", "arm"), ("asmjs", "asmjs"), + ("avr", "avr"), ("hexagon", "hexagon"), ("i386", "x86"), ("i586", "x86"),