cmd.arg("--color=always");
}
- if env::var_os("RUSTC_DENY_WARNINGS").is_some() {
+ if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none()
+ {
cmd.arg("-Dwarnings");
+ cmd.arg("-Dbare_trait_objects");
}
if verbose > 1 {
use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, add_to_sysroot};
use builder::{RunConfig, Builder, ShouldRun, Step};
-use tool::{self, prepare_tool_cargo};
+use tool::{self, prepare_tool_cargo, SourceType};
use {Compiler, Mode};
use cache::{INTERNER, Interned};
use std::path::PathBuf;
Mode::ToolRustc,
target,
"check",
- "src/tools/rustdoc");
+ "src/tools/rustdoc",
+ SourceType::InTree);
let _folder = builder.fold_output(|| format!("stage{}-rustdoc", compiler.stage));
println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
use util::symlink_dir;
use builder::{Builder, Compiler, RunConfig, ShouldRun, Step};
-use tool::{self, prepare_tool_cargo, Tool};
+use tool::{self, prepare_tool_cargo, Tool, SourceType};
use compile;
use cache::{INTERNER, Interned};
use config::Config;
target,
"doc",
"src/tools/rustdoc",
+ SourceType::InTree,
);
cargo.env("RUSTDOCFLAGS", "--document-private-items");
use dist;
use flags::Subcommand;
use native;
-use tool::{self, Tool};
+use tool::{self, Tool, SourceType};
use toolstate::ToolState;
use util::{self, dylib_path, dylib_path_var};
use Crate as CargoCrate;
compiler,
target: self.host,
});
- let mut cargo = builder.cargo(compiler, Mode::ToolRustc, self.host, "test");
- cargo
- .arg("--manifest-path")
- .arg(builder.src.join("src/tools/cargo/Cargo.toml"));
+ let mut cargo = tool::prepare_tool_cargo(builder,
+ compiler,
+ Mode::ToolRustc,
+ self.host,
+ "test",
+ "src/tools/cargo",
+ SourceType::Submodule);
+
if !builder.fail_fast {
cargo.arg("--no-fail-fast");
}
- // Don't build tests dynamically, just a pain to work with
- cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
-
// Don't run cross-compile tests, we may not have cross-compiled libstd libs
// available.
cargo.env("CFG_DISABLE_CROSS_TESTS", "1");
Mode::ToolRustc,
host,
"test",
- "src/tools/rls");
-
- // Don't build tests dynamically, just a pain to work with
- cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
+ "src/tools/rls",
+ SourceType::Submodule);
builder.add_rustc_lib_path(compiler, &mut cargo);
Mode::ToolRustc,
host,
"test",
- "src/tools/rustfmt");
+ "src/tools/rustfmt",
+ SourceType::Submodule);
- // Don't build tests dynamically, just a pain to work with
- cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
let dir = testdir(builder, compiler.host);
t!(fs::create_dir_all(&dir));
cargo.env("RUSTFMT_TEST_DIR", dir);
extra_features: Vec::new(),
});
if let Some(miri) = miri {
- let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test");
- cargo
- .arg("--manifest-path")
- .arg(builder.src.join("src/tools/miri/Cargo.toml"));
+ let mut cargo = tool::prepare_tool_cargo(builder,
+ compiler,
+ Mode::ToolRustc,
+ host,
+ "test",
+ "src/tools/miri",
+ SourceType::Submodule);
- // Don't build tests dynamically, just a pain to work with
- cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
// miri tests need to know about the stage sysroot
cargo.env("MIRI_SYSROOT", builder.sysroot(compiler));
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
extra_features: Vec::new(),
});
if let Some(clippy) = clippy {
- let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test");
- cargo
- .arg("--manifest-path")
- .arg(builder.src.join("src/tools/clippy/Cargo.toml"));
+ let mut cargo = tool::prepare_tool_cargo(builder,
+ compiler,
+ Mode::ToolRustc,
+ host,
+ "test",
+ "src/tools/clippy",
+ SourceType::Submodule);
- // Don't build tests dynamically, just a pain to work with
- cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
// clippy tests need to know about the stage sysroot
cargo.env("SYSROOT", builder.sysroot(compiler));
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
Mode::ToolRustc,
target,
test_kind.subcommand(),
- "src/tools/rustdoc");
+ "src/tools/rustdoc",
+ SourceType::InTree);
if test_kind.subcommand() == "test" && !builder.fail_fast {
cargo.arg("--no-fail-fast");
}
}
}
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+pub enum SourceType {
+ InTree,
+ Submodule,
+}
+
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
struct ToolBuild {
compiler: Compiler,
tool: &'static str,
path: &'static str,
mode: Mode,
- is_ext_tool: bool,
+ is_optional_tool: bool,
+ source_type: SourceType,
extra_features: Vec<String>,
}
let target = self.target;
let tool = self.tool;
let path = self.path;
- let is_ext_tool = self.is_ext_tool;
+ let is_optional_tool = self.is_optional_tool;
match self.mode {
Mode::ToolRustc => {
_ => panic!("unexpected Mode for tool build")
}
- let mut cargo = prepare_tool_cargo(builder, compiler, self.mode, target, "build", path);
+ let mut cargo = prepare_tool_cargo(
+ builder,
+ compiler,
+ self.mode,
+ target,
+ "build",
+ path,
+ self.source_type,
+ );
cargo.arg("--features").arg(self.extra_features.join(" "));
let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
});
if !is_expected {
- if !is_ext_tool {
+ if !is_optional_tool {
exit(1);
} else {
return None;
target: Interned<String>,
command: &'static str,
path: &'static str,
+ source_type: SourceType,
) -> Command {
let mut cargo = builder.cargo(compiler, mode, target, command);
let dir = builder.src.join(path);
// stages and such and it's just easier if they're not dynamically linked.
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
+ if source_type == SourceType::Submodule {
+ cargo.env("RUSTC_EXTERNAL_TOOL", "1");
+ }
+
if let Some(dir) = builder.openssl_install_dir(target) {
cargo.env("OPENSSL_STATIC", "1");
cargo.env("OPENSSL_DIR", dir);
}
macro_rules! tool {
- ($($name:ident, $path:expr, $tool_name:expr, $mode:expr $(,llvm_tools = $llvm:expr)*;)+) => {
+ ($($name:ident, $path:expr, $tool_name:expr, $mode:expr
+ $(,llvm_tools = $llvm:expr)* $(,is_external_tool = $external:expr)*;)+) => {
#[derive(Copy, PartialEq, Eq, Clone)]
pub enum Tool {
$(
tool: $tool_name,
mode: $mode,
path: $path,
- is_ext_tool: false,
+ is_optional_tool: false,
+ source_type: if false $(|| $external)* {
+ SourceType::Submodule
+ } else {
+ SourceType::InTree
+ },
extra_features: Vec::new(),
}).expect("expected to build -- essential tool")
}
Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, llvm_tools = true;
BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolBootstrap;
RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolBootstrap;
- RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap;
+ RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap,
+ is_external_tool = true;
RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolBootstrap;
);
tool: "remote-test-server",
mode: Mode::ToolStd,
path: "src/tools/remote-test-server",
- is_ext_tool: false,
+ is_optional_tool: false,
+ source_type: SourceType::InTree,
extra_features: Vec::new(),
}).expect("expected to build -- essential tool")
}
target: builder.config.build,
});
- let mut cargo = prepare_tool_cargo(builder,
- build_compiler,
- Mode::ToolRustc,
- target,
- "build",
- "src/tools/rustdoc");
+ let mut cargo = prepare_tool_cargo(
+ builder,
+ build_compiler,
+ Mode::ToolRustc,
+ target,
+ "build",
+ "src/tools/rustdoc",
+ SourceType::InTree,
+ );
// Most tools don't get debuginfo, but rustdoc should.
cargo.env("RUSTC_DEBUGINFO", builder.config.rust_debuginfo.to_string())
tool: "cargo",
mode: Mode::ToolRustc,
path: "src/tools/cargo",
- is_ext_tool: false,
+ is_optional_tool: false,
+ source_type: SourceType::Submodule,
extra_features: Vec::new(),
}).expect("expected to build -- essential tool")
}
mode: Mode::ToolRustc,
path: $path,
extra_features: $sel.extra_features,
- is_ext_tool: true,
+ is_optional_tool: true,
+ source_type: SourceType::Submodule,
})
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
use std::fs::File;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
RUN sh /scripts/sccache.sh
ENV \
- AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \
- CC_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang \
- CXX_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang++ \
- AR_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-ar \
- CC_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-clang \
- CXX_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-clang++ \
+ AR_x86_64_fuchsia=x86_64-fuchsia-ar \
+ CC_x86_64_fuchsia=x86_64-fuchsia-clang \
+ CXX_x86_64_fuchsia=x86_64-fuchsia-clang++ \
+ AR_aarch64_fuchsia=aarch64-fuchsia-ar \
+ CC_aarch64_fuchsia=aarch64-fuchsia-clang \
+ CXX_aarch64_fuchsia=aarch64-fuchsia-clang++ \
AR_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-ar \
CC_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-gcc \
CXX_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-g++ \
CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \
CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++
-ENV TARGETS=x86_64-unknown-fuchsia
-ENV TARGETS=$TARGETS,aarch64-unknown-fuchsia
+ENV TARGETS=x86_64-fuchsia
+ENV TARGETS=$TARGETS,aarch64-fuchsia
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
ENV TARGETS=$TARGETS,wasm32-unknown-unknown
ENV TARGETS=$TARGETS,x86_64-sun-solaris
esac
hide_output make -j$(getconf _NPROCESSORS_ONLN) $tgt
- dst=/usr/local/${arch}-unknown-fuchsia
+ dst=/usr/local/${arch}-fuchsia
mkdir -p $dst
cp -a build-${tgt}/sysroot/include $dst/
cp -a build-${tgt}/sysroot/lib $dst/
for arch in x86_64 aarch64; do
for tool in clang clang++; do
- cat >/usr/local/bin/${arch}-unknown-fuchsia-${tool} <<EOF
+ cat >/usr/local/bin/${arch}-fuchsia-${tool} <<EOF
#!/bin/sh
-${tool} --target=${arch}-unknown-fuchsia --sysroot=/usr/local/${arch}-unknown-fuchsia "\$@"
+${tool} --target=${arch}-fuchsia --sysroot=/usr/local/${arch}-fuchsia "\$@"
EOF
- chmod +x /usr/local/bin/${arch}-unknown-fuchsia-${tool}
+ chmod +x /usr/local/bin/${arch}-fuchsia-${tool}
done
- ln -s /usr/local/bin/llvm-ar /usr/local/bin/${arch}-unknown-fuchsia-ar
+ ln -s /usr/local/bin/llvm-ar /usr/local/bin/${arch}-fuchsia-ar
done
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
#![no_std]
#![needs_allocator]
-#![deny(bare_trait_objects)]
#![deny(missing_debug_implementations)]
#![cfg_attr(test, allow(deprecated))] // rand
a = a.clone();
assert!(a.upgrade().is_none());
- let mut a: Weak<Any> = a; // Unsizing
+ let mut a: Weak<dyn Any> = a; // Unsizing
a = a.clone();
assert!(a.upgrade().is_none());
}
#[test]
fn trait_object() {
let a: Arc<u32> = Arc::new(4);
- let a: Arc<Any> = a; // Unsizing
+ let a: Arc<dyn Any> = a; // Unsizing
// Exercise is_dangling() with a DST
let mut a = Arc::downgrade(&a);
let mut b = Weak::<u32>::new();
b = b.clone();
assert!(b.upgrade().is_none());
- let mut b: Weak<Any> = b; // Unsizing
+ let mut b: Weak<dyn Any> = b; // Unsizing
b = b.clone();
assert!(b.upgrade().is_none());
}
}
fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
- where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> bool
+ where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut dyn FnMut(&i32) -> bool) -> bool
{
let mut set_a = BTreeSet::new();
let mut set_b = BTreeSet::new();
5u32.hash(&mut hasher_1);
assert_eq!(ordinary_hash, hasher_1.finish());
- let mut hasher_2 = Box::new(DefaultHasher::new()) as Box<Hasher>;
+ let mut hasher_2 = Box::new(DefaultHasher::new()) as Box<dyn Hasher>;
5u32.hash(&mut hasher_2);
assert_eq!(ordinary_hash, hasher_2.finish());
}
a = a.clone();
assert!(a.upgrade().is_none());
- let mut a: Weak<Any> = a; // Unsizing
+ let mut a: Weak<dyn Any> = a; // Unsizing
a = a.clone();
assert!(a.upgrade().is_none());
}
#[test]
fn trait_object() {
let a: Rc<u32> = Rc::new(4);
- let a: Rc<Any> = a; // Unsizing
+ let a: Rc<dyn Any> = a; // Unsizing
// Exercise is_dangling() with a DST
let mut a = Rc::downgrade(&a);
let mut b = Weak::<u32>::new();
b = b.clone();
assert!(b.upgrade().is_none());
- let mut b: Weak<Any> = b; // Unsizing
+ let mut b: Weak<dyn Any> = b; // Unsizing
b = b.clone();
assert!(b.upgrade().is_none());
}
#![no_std]
#![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
#![unstable(feature = "alloc_jemalloc",
reason = "implementation detail of std, does not provide any public API",
issue = "0")]
#![no_std]
#![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
#![unstable(feature = "alloc_system",
reason = "this library is unlikely to be stabilized in its current \
form or name",
#![cfg_attr(test, feature(test))]
#![allow(deprecated)]
-#![deny(bare_trait_objects)]
extern crate alloc;
extern crate rustc_data_structures;
///////////////////////////////////////////////////////////////////////////////
#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Any {
+impl fmt::Debug for dyn Any {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Any")
}
// hence used with `unwrap`. May eventually no longer be needed if
// dispatch works with upcasting.
#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Any + Send {
+impl fmt::Debug for dyn Any + Send {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Any")
}
}
#[stable(feature = "any_send_sync_methods", since = "1.28.0")]
-impl fmt::Debug for Any + Send + Sync {
+impl fmt::Debug for dyn Any + Send + Sync {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Any")
}
}
-impl Any {
+impl dyn Any {
/// Returns `true` if the boxed type is the same as `T`.
///
/// # Examples
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
if self.is::<T>() {
unsafe {
- Some(&*(self as *const Any as *const T))
+ Some(&*(self as *const dyn Any as *const T))
}
} else {
None
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
unsafe {
- Some(&mut *(self as *mut Any as *mut T))
+ Some(&mut *(self as *mut dyn Any as *mut T))
}
} else {
None
}
}
-impl Any+Send {
+impl dyn Any+Send {
/// Forwards to the method defined on the type `Any`.
///
/// # Examples
}
}
-impl Any+Send+Sync {
+impl dyn Any+Send+Sync {
/// Forwards to the method defined on the type `Any`.
///
/// # Examples
#[allow(unused)]
fn assert_coerce_unsized(a: UnsafeCell<&i32>, b: Cell<&i32>, c: RefCell<&i32>) {
- let _: UnsafeCell<&Send> = a;
- let _: Cell<&Send> = b;
- let _: RefCell<&Send> = c;
+ let _: UnsafeCell<&dyn Send> = a;
+ let _: Cell<&dyn Send> = b;
+ let _: RefCell<&dyn Send> = c;
}
use fmt;
struct PadAdapter<'a> {
- buf: &'a mut (fmt::Write + 'a),
+ buf: &'a mut (dyn fmt::Write + 'a),
on_newline: bool,
}
impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
/// Adds a new field to the generated struct output.
#[stable(feature = "debug_builders", since = "1.2.0")]
- pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> {
+ pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut DebugStruct<'a, 'b> {
self.result = self.result.and_then(|_| {
let prefix = if self.has_fields {
","
impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
/// Adds a new field to the generated tuple struct output.
#[stable(feature = "debug_builders", since = "1.2.0")]
- pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
+ pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut DebugTuple<'a, 'b> {
self.result = self.result.and_then(|_| {
let (prefix, space) = if self.fields > 0 {
(",", " ")
}
impl<'a, 'b: 'a> DebugInner<'a, 'b> {
- fn entry(&mut self, entry: &fmt::Debug) {
+ fn entry(&mut self, entry: &dyn fmt::Debug) {
self.result = self.result.and_then(|_| {
if self.is_pretty() {
let mut slot = None;
impl<'a, 'b: 'a> DebugSet<'a, 'b> {
/// Adds a new entry to the set output.
#[stable(feature = "debug_builders", since = "1.2.0")]
- pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
+ pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugSet<'a, 'b> {
self.inner.entry(entry);
self
}
impl<'a, 'b: 'a> DebugList<'a, 'b> {
/// Adds a new entry to the list output.
#[stable(feature = "debug_builders", since = "1.2.0")]
- pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> {
+ pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugList<'a, 'b> {
self.inner.entry(entry);
self
}
impl<'a, 'b: 'a> DebugMap<'a, 'b> {
/// Adds a new entry to the map output.
#[stable(feature = "debug_builders", since = "1.2.0")]
- pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
+ pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> {
self.result = self.result.and_then(|_| {
if self.is_pretty() {
let mut slot = None;
width: Option<usize>,
precision: Option<usize>,
- buf: &'a mut (Write+'a),
+ buf: &'a mut (dyn Write+'a),
curarg: slice::Iter<'a, ArgumentV1<'a>>,
args: &'a [ArgumentV1<'a>],
}
///
/// It was added after #45197 showed that one could share a `!Sync`
/// object across threads by passing it into `format_args!`.
- _oibit_remover: PhantomData<*mut Fn()>,
+ _oibit_remover: PhantomData<*mut dyn Fn()>,
}
/// This struct represents the generic "argument" which is taken by the Xprintf
///
/// [`write!`]: ../../std/macro.write.html
#[stable(feature = "rust1", since = "1.0.0")]
-pub fn write(output: &mut Write, args: Arguments) -> Result {
+pub fn write(output: &mut dyn Write, args: Arguments) -> Result {
let mut formatter = Formatter {
flags: 0,
width: None,
impl<'a> Formatter<'a> {
fn wrap_buf<'b, 'c, F>(&'b mut self, wrap: F) -> Formatter<'c>
- where 'b: 'c, F: FnOnce(&'b mut (Write+'b)) -> &'c mut (Write+'c)
+ where 'b: 'c, F: FnOnce(&'b mut (dyn Write+'b)) -> &'c mut (dyn Write+'c)
{
Formatter {
// We want to change this
}
fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result {
- fn write_bytes(buf: &mut Write, s: &[u8]) -> Result {
+ fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result {
buf.write_str(unsafe { str::from_utf8_unchecked(s) })
}
use super::{Zip, Sum, Product};
use super::{ChainState, FromIterator, ZipImpl};
-fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
+fn _assert_is_object_safe(_: &dyn Iterator<Item=()>) {}
/// An interface for dealing with iterators.
///
#[stable(feature = "panic_hooks", since = "1.10.0")]
#[derive(Debug)]
pub struct PanicInfo<'a> {
- payload: &'a (Any + Send),
+ payload: &'a (dyn Any + Send),
message: Option<&'a fmt::Arguments<'a>>,
location: Location<'a>,
}
#[doc(hidden)]
#[inline]
- pub fn set_payload(&mut self, info: &'a (Any + Send)) {
+ pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) {
self.payload = info;
}
/// panic!("Normal panic");
/// ```
#[stable(feature = "panic_hooks", since = "1.10.0")]
- pub fn payload(&self) -> &(Any + Send) {
+ pub fn payload(&self) -> &(dyn Any + Send) {
self.payload
}
#[unstable(feature = "std_internals", issue = "0")]
#[doc(hidden)]
pub unsafe trait BoxMeUp {
- fn box_me_up(&mut self) -> *mut (Any + Send);
- fn get(&mut self) -> &(Any + Send);
+ fn box_me_up(&mut self) -> *mut (dyn Any + Send);
+ fn get(&mut self) -> &(dyn Any + Send);
}
/// when performing a single `poll` step on a task.
pub struct Context<'a> {
local_waker: &'a LocalWaker,
- executor: &'a mut Executor,
+ executor: &'a mut dyn Executor,
}
impl<'a> fmt::Debug for Context<'a> {
impl<'a> Context<'a> {
/// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`.
#[inline]
- pub fn new(local_waker: &'a LocalWaker, executor: &'a mut Executor) -> Context<'a> {
+ pub fn new(local_waker: &'a LocalWaker, executor: &'a mut dyn Executor) -> Context<'a> {
Context {
local_waker,
executor,
/// This method is useful primarily if you want to explicitly handle
/// spawn failures.
#[inline]
- pub fn executor(&mut self) -> &mut Executor {
+ pub fn executor(&mut self) -> &mut dyn Executor {
self.executor
}
/// trait, allowing notifications to get routed through it.
#[repr(transparent)]
pub struct Waker {
- inner: NonNull<UnsafeWake>,
+ inner: NonNull<dyn UnsafeWake>,
}
impl Unpin for Waker {}
/// use the `Waker::from` function instead which works with the safe
/// `Arc` type and the safe `Wake` trait.
#[inline]
- pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
+ pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self {
Waker { inner: inner }
}
/// behavior.
#[repr(transparent)]
pub struct LocalWaker {
- inner: NonNull<UnsafeWake>,
+ inner: NonNull<dyn UnsafeWake>,
}
impl Unpin for LocalWaker {}
/// For this function to be used safely, it must be sound to call `inner.wake_local()`
/// on the current thread.
#[inline]
- pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
+ pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self {
LocalWaker { inner: inner }
}
#[test]
fn any_referenced() {
- let (a, b, c) = (&5 as &Any, &TEST as &Any, &Test as &Any);
+ let (a, b, c) = (&5 as &dyn Any, &TEST as &dyn Any, &Test as &dyn Any);
assert!(a.is::<i32>());
assert!(!b.is::<i32>());
#[test]
fn any_owning() {
- let (a, b, c) = (box 5_usize as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>);
+ let (a, b, c) = (
+ box 5_usize as Box<dyn Any>,
+ box TEST as Box<dyn Any>,
+ box Test as Box<dyn Any>,
+ );
assert!(a.is::<usize>());
assert!(!b.is::<usize>());
#[test]
fn any_downcast_ref() {
- let a = &5_usize as &Any;
+ let a = &5_usize as &dyn Any;
match a.downcast_ref::<usize>() {
Some(&5) => {}
let mut a = 5_usize;
let mut b: Box<_> = box 7_usize;
- let a_r = &mut a as &mut Any;
+ let a_r = &mut a as &mut dyn Any;
let tmp: &mut usize = &mut *b;
- let b_r = tmp as &mut Any;
+ let b_r = tmp as &mut dyn Any;
match a_r.downcast_mut::<usize>() {
Some(x) => {
#[test]
fn any_fixed_vec() {
let test = [0_usize; 8];
- let test = &test as &Any;
+ let test = &test as &dyn Any;
assert!(test.is::<[usize; 8]>());
assert!(!test.is::<[usize; 10]>());
}
fn test_indirect_hasher() {
let mut hasher = MyHasher { hash: 0 };
{
- let mut indirect_hasher: &mut Hasher = &mut hasher;
+ let mut indirect_hasher: &mut dyn Hasher = &mut hasher;
5u32.hash(&mut indirect_hasher);
}
assert_eq!(hasher.hash, 5);
#[test]
fn test_typeid_unsized_types() {
trait Z {}
- struct X(str); struct Y(Z + 'static);
+ struct X(str); struct Y(dyn Z + 'static);
assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
trait Foo { fn dummy(&self) { } }
impl Foo for isize {}
- let a = box 100isize as Box<Foo>;
+ let a = box 100isize as Box<dyn Foo>;
unsafe {
let x: ::core::raw::TraitObject = transmute(a);
assert!(*(x.data as *const isize) == 100);
- let _x: Box<Foo> = transmute(x);
+ let _x: Box<dyn Foo> = transmute(x);
}
unsafe {
assert!(v == None);
// test that it does not take more elements than it needs
- let mut functions: [Box<Fn() -> Option<()>>; 3] =
+ let mut functions: [Box<dyn Fn() -> Option<()>>; 3] =
[box || Some(()), box || None, box || panic!()];
let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect();
assert!(nms.is_null());
// Pointers to unsized types -- trait objects
- let ci: *const ToString = &3;
+ let ci: *const dyn ToString = &3;
assert!(!ci.is_null());
- let mi: *mut ToString = &mut 3;
+ let mi: *mut dyn ToString = &mut 3;
assert!(!mi.is_null());
- let nci: *const ToString = null::<isize>();
+ let nci: *const dyn ToString = null::<isize>();
assert!(nci.is_null());
- let nmi: *mut ToString = null_mut::<isize>();
+ let nmi: *mut dyn ToString = null_mut::<isize>();
assert!(nmi.is_null());
}
assert_eq!(nms.as_ref(), None);
// Pointers to unsized types -- trait objects
- let ci: *const ToString = &3;
+ let ci: *const dyn ToString = &3;
assert!(ci.as_ref().is_some());
- let mi: *mut ToString = &mut 3;
+ let mi: *mut dyn ToString = &mut 3;
assert!(mi.as_ref().is_some());
- let nci: *const ToString = null::<isize>();
+ let nci: *const dyn ToString = null::<isize>();
assert!(nci.as_ref().is_none());
- let nmi: *mut ToString = null_mut::<isize>();
+ let nmi: *mut dyn ToString = null_mut::<isize>();
assert!(nmi.as_ref().is_none());
}
}
assert_eq!(nms.as_mut(), None);
// Pointers to unsized types -- trait objects
- let mi: *mut ToString = &mut 3;
+ let mi: *mut dyn ToString = &mut 3;
assert!(mi.as_mut().is_some());
- let nmi: *mut ToString = null_mut::<isize>();
+ let nmi: *mut dyn ToString = null_mut::<isize>();
assert!(nmi.as_mut().is_none());
}
}
assert!(v == Err(2));
// test that it does not take more elements than it needs
- let mut functions: [Box<Fn() -> Result<(), isize>>; 3] =
+ let mut functions: [Box<dyn Fn() -> Result<(), isize>>; 3] =
[box || Ok(()), box || Err(1), box || panic!()];
let v: Result<Vec<()>, isize> = functions.iter_mut().map(|f| (*f)()).collect();
//! Parsing does not happen at runtime: structures of `std::fmt::rt` are
//! generated instead.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/",
//!
//! * [DOT language](http://www.graphviz.org/doc/info/lang.html)
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
#![panic_runtime]
#![allow(unused_features)]
-#![deny(bare_trait_objects)]
#![feature(core_intrinsics)]
#![feature(libc)]
//! More documentation about each implementation can be found in the respective
//! module.
-#![deny(bare_trait_objects)]
#![no_std]
#![unstable(feature = "panic_unwind", issue = "32837")]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
//! See [the book](../book/first-edition/procedural-macros.html) for more.
#![stable(feature = "proc_macro_lib", since = "1.15.0")]
-#![deny(bare_trait_objects)]
#![deny(missing_docs)]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
reason = "internal implementation detail of rustc right now",
issue = "0")]
#![allow(unused_features)]
-#![deny(bare_trait_objects)]
#![feature(staged_api)]
.collect();
// Try to map those to something more useful
- let mut missing_items = vec![];
+ let mut missing_items = Vec::with_capacity(missing.len());
for local_id in missing {
let hir_id = HirId {
// }
// ```
if let Some(anon_node_id) = tcx.hir.as_local_node_id(def_id) {
- let in_definition_scope = match tcx.hir.expect_item(anon_node_id).node {
- // impl trait
- hir::ItemKind::Existential(hir::ExistTy {
- impl_trait_fn: Some(parent),
- ..
- }) => parent == self.parent_def_id,
- // named existential types
- hir::ItemKind::Existential(hir::ExistTy {
- impl_trait_fn: None,
- ..
- }) => may_define_existential_type(
- tcx,
- self.parent_def_id,
- anon_node_id,
- ),
- _ => {
- let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
- self.parent_def_id == tcx.hir.local_def_id(anon_parent_node_id)
+ let parent_def_id = self.parent_def_id;
+ let def_scope_default = || {
+ let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
+ parent_def_id == tcx.hir.local_def_id(anon_parent_node_id)
+ };
+ let in_definition_scope = match tcx.hir.find(anon_node_id) {
+ Some(hir::map::NodeItem(item)) => match item.node {
+ // impl trait
+ hir::ItemKind::Existential(hir::ExistTy {
+ impl_trait_fn: Some(parent),
+ ..
+ }) => parent == self.parent_def_id,
+ // named existential types
+ hir::ItemKind::Existential(hir::ExistTy {
+ impl_trait_fn: None,
+ ..
+ }) => may_define_existential_type(
+ tcx,
+ self.parent_def_id,
+ anon_node_id,
+ ),
+ _ => def_scope_default(),
},
+ Some(hir::map::NodeImplItem(item)) => match item.node {
+ hir::ImplItemKind::Existential(_) => may_define_existential_type(
+ tcx,
+ self.parent_def_id,
+ anon_node_id,
+ ),
+ _ => def_scope_default(),
+ },
+ _ => bug!(
+ "expected (impl) item, found {}",
+ tcx.hir.node_to_string(anon_node_id),
+ ),
};
if in_definition_scope {
return self.fold_anon_ty(ty, def_id, substs);
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
- fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
+ pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
if let ty::TyInfer(ty::TyVar(ty_vid)) = (*ty).sty {
let ty_vars = self.type_variables.borrow();
if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
}
fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
- let mut bounds = vec![];
-
- for subty in ty.walk_shallow() {
- bounds.push(self.type_bound(subty));
- }
+ let mut bounds = ty.walk_shallow().map(|subty| self.type_bound(subty)).collect::<Vec<_>>();
let mut regions = ty.regions();
regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions
//!
//! This API is completely unstable and subject to change.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
}
}
- let mut future_incompatible = vec![];
+ let mut future_incompatible = Vec::with_capacity(lints.len());
for lint in lints {
future_incompatible.push(lint.id);
self.future_incompatible.insert(lint.id, lint);
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+pub enum SignalledError { SawSomeError, NoErrorsSeen }
+
+impl_stable_hash_for!(enum self::SignalledError { SawSomeError, NoErrorsSeen });
+
#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct BorrowCheckResult {
pub used_mut_nodes: FxHashSet<HirId>,
+ pub signalled_any_error: SignalledError,
}
impl<'a> HashStable<StableHashingContext<'a>> for BorrowCheckResult {
hasher: &mut StableHasher<W>) {
let BorrowCheckResult {
ref used_mut_nodes,
+ ref signalled_any_error,
} = *self;
used_mut_nodes.hash_stable(hcx, hasher);
+ signalled_any_error.hash_stable(hcx, hasher);
}
}
Ast,
Mir,
Compare,
+ Migrate,
}
impl BorrowckMode {
+ /// Should we run the MIR-based borrow check, but also fall back
+ /// on the AST borrow check if the MIR-based one errors.
+ pub fn migrate(self) -> bool {
+ match self {
+ BorrowckMode::Ast => false,
+ BorrowckMode::Compare => false,
+ BorrowckMode::Mir => false,
+ BorrowckMode::Migrate => true,
+ }
+ }
+
/// Should we emit the AST-based borrow checker errors?
pub fn use_ast(self) -> bool {
match self {
BorrowckMode::Ast => true,
BorrowckMode::Compare => true,
BorrowckMode::Mir => false,
+ BorrowckMode::Migrate => false,
}
}
/// Should we emit the MIR-based borrow checker errors?
BorrowckMode::Ast => false,
BorrowckMode::Compare => true,
BorrowckMode::Mir => true,
+ BorrowckMode::Migrate => true,
}
}
}
emit_end_regions: bool = (false, parse_bool, [UNTRACKED],
"emit EndRegion as part of MIR; enable transforms that solely process EndRegion"),
borrowck: Option<String> = (None, parse_opt_string, [UNTRACKED],
- "select which borrowck is used (`ast`, `mir`, or `compare`)"),
+ "select which borrowck is used (`ast`, `mir`, `migrate`, or `compare`)"),
two_phase_borrows: bool = (false, parse_bool, [UNTRACKED],
"use two-phase reserved/active distinction for `&mut` borrows in MIR borrowck"),
two_phase_beyond_autoref: bool = (false, parse_bool, [UNTRACKED],
"for every macro invocation, print its name and arguments"),
debug_macros: bool = (false, parse_bool, [TRACKED],
"emit line numbers debug info inside macros"),
- enable_nonzeroing_move_hints: bool = (false, parse_bool, [TRACKED],
- "force nonzeroing move optimization on"),
keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
"don't clear the hygiene data after analysis"),
keep_ast: bool = (false, parse_bool, [UNTRACKED],
None | Some("ast") => BorrowckMode::Ast,
Some("mir") => BorrowckMode::Mir,
Some("compare") => BorrowckMode::Compare,
+ Some("migrate") => BorrowckMode::Migrate,
Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)),
};
opts.debugging_opts.force_overflow_checks = Some(true);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
- opts = reference.clone();
- opts.debugging_opts.enable_nonzeroing_move_hints = true;
- assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
-
opts = reference.clone();
opts.debugging_opts.show_span = Some(String::from("abc"));
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
pub fn unstable_options(&self) -> bool {
self.opts.debugging_opts.unstable_options
}
- pub fn nonzeroing_move_hints(&self) -> bool {
- self.opts.debugging_opts.enable_nonzeroing_move_hints
- }
pub fn overflow_checks(&self) -> bool {
self.opts
.cg
pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
-> Vec<ObjectSafetyViolation>
{
- let mut violations = vec![];
-
- for def_id in traits::supertrait_def_ids(self, trait_def_id) {
- if self.predicates_reference_self(def_id, true) {
- violations.push(ObjectSafetyViolation::SupertraitSelf);
- }
- }
+ let violations = traits::supertrait_def_ids(self, trait_def_id)
+ .filter(|&def_id| self.predicates_reference_self(def_id, true))
+ .map(|_| ObjectSafetyViolation::SupertraitSelf)
+ .collect();
debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}",
trait_def_id,
let param_env = obligation.param_env;
let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_def_id);
- let ty = if !assoc_ty.item.defaultness.has_value() {
+ if !assoc_ty.item.defaultness.has_value() {
// This means that the impl is missing a definition for the
// associated type. This error will be reported by the type
// checker method `check_impl_items_against_trait`, so here we
debug!("confirm_impl_candidate: no associated type {:?} for {:?}",
assoc_ty.item.ident,
obligation.predicate);
- tcx.types.err
+ return Progress {
+ ty: tcx.types.err,
+ obligations: nested,
+ };
+ }
+ let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
+ let ty = if let ty::AssociatedKind::Existential = assoc_ty.item.kind {
+ let item_substs = Substs::identity_for_item(tcx, assoc_ty.item.def_id);
+ tcx.mk_anon(assoc_ty.item.def_id, item_substs)
} else {
tcx.type_of(assoc_ty.item.def_id)
};
- let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
Progress {
ty: ty.subst(tcx, substs),
obligations: nested,
trait_def_id: DefId,
) -> impl Iterator<Item = NodeItem<ty::AssociatedItem>> + Captures<'gcx> + Captures<'tcx> + 'a {
self.flat_map(move |node| {
- node.items(tcx).filter(move |impl_item| {
- impl_item.kind == trait_item_kind &&
- tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id)
+ use ty::AssociatedKind::*;
+ node.items(tcx).filter(move |impl_item| match (trait_item_kind, impl_item.kind) {
+ | (Const, Const)
+ | (Method, Method)
+ | (Type, Type)
+ | (Type, Existential)
+ => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id),
+
+ | (Const, _)
+ | (Method, _)
+ | (Type, _)
+ | (Existential, _)
+ => false,
}).map(move |item| NodeItem { node: node, item: item })
})
}
use syntax::ast::{self, NodeId};
use syntax::attr;
use syntax::codemap::MultiSpan;
+use syntax::edition::Edition;
use syntax::feature_gate;
use syntax::symbol::{Symbol, keywords, InternedString};
use syntax_pos::Span;
self.borrowck_mode().use_mir()
}
+ /// If true, we should use the MIR-based borrow check, but also
+ /// fall back on the AST borrow check if the MIR-based one errors.
+ pub fn migrate_borrowck(self) -> bool {
+ self.borrowck_mode().migrate()
+ }
+
/// If true, make MIR codegen for `match` emit a temp that holds a
/// borrow of the input to the match expression.
pub fn generate_borrow_of_any_match_input(&self) -> bool {
/// What mode(s) of borrowck should we run? AST? MIR? both?
/// (Also considers the `#![feature(nll)]` setting.)
pub fn borrowck_mode(&self) -> BorrowckMode {
- match self.sess.opts.borrowck_mode {
- mode @ BorrowckMode::Mir |
- mode @ BorrowckMode::Compare => mode,
+ // Here are the main constraints we need to deal with:
+ //
+ // 1. An opts.borrowck_mode of `BorrowckMode::Ast` is
+ // synonymous with no `-Z borrowck=...` flag at all.
+ // (This is arguably a historical accident.)
+ //
+ // 2. `BorrowckMode::Migrate` is the limited migration to
+ // NLL that we are deploying with the 2018 edition.
+ //
+ // 3. We want to allow developers on the Nightly channel
+ // to opt back into the "hard error" mode for NLL,
+ // (which they can do via specifying `#![feature(nll)]`
+ // explicitly in their crate).
+ //
+ // So, this precedence list is how pnkfelix chose to work with
+ // the above constraints:
+ //
+ // * `#![feature(nll)]` *always* means use NLL with hard
+ // errors. (To simplify the code here, it now even overrides
+ // a user's attempt to specify `-Z borrowck=compare`, which
+ // we arguably do not need anymore and should remove.)
+ //
+ // * Otherwise, if no `-Z borrowck=...` flag was given (or
+ // if `borrowck=ast` was specified), then use the default
+ // as required by the edition.
+ //
+ // * Otherwise, use the behavior requested via `-Z borrowck=...`
- mode @ BorrowckMode::Ast => {
- if self.features().nll {
- BorrowckMode::Mir
- } else {
- mode
- }
- }
+ if self.features().nll { return BorrowckMode::Mir; }
+ match self.sess.opts.borrowck_mode {
+ mode @ BorrowckMode::Mir |
+ mode @ BorrowckMode::Compare |
+ mode @ BorrowckMode::Migrate => mode,
+
+ BorrowckMode::Ast => match self.sess.edition() {
+ Edition::Edition2015 => BorrowckMode::Ast,
+ Edition::Edition2018 => BorrowckMode::Migrate,
+
+ // For now, future editions mean Migrate. (But it
+ // would make a lot of sense for it to be changed to
+ // `BorrowckMode::Mir`, depending on how we plan to
+ // time the forcing of full migration to NLL.)
+ _ => BorrowckMode::Migrate,
+ },
}
}
use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
use ty::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon};
use ty::{TyDynamic, TyInt, TyUint, TyInfer};
-use ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind};
+use ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind};
use util::nodemap::FxHashSet;
use std::cell::Cell;
use syntax::symbol::{Symbol, InternedString};
use hir;
+thread_local! {
+ /// Mechanism for highlighting of specific regions for display in NLL region inference errors.
+ /// Contains region to highlight and counter for number to use when highlighting.
+ static HIGHLIGHT_REGION: Cell<Option<(RegionVid, usize)>> = Cell::new(None)
+}
+
macro_rules! gen_display_debug_body {
( $with:path ) => {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
PrintContext::new().parameterized(f, substs, did, projections)
}
+fn get_highlight_region() -> Option<(RegionVid, usize)> {
+ HIGHLIGHT_REGION.with(|hr| hr.get())
+}
+
+pub fn with_highlight_region<R>(r: RegionVid, counter: usize, op: impl FnOnce() -> R) -> R {
+ HIGHLIGHT_REGION.with(|hr| {
+ assert_eq!(hr.get(), None);
+ hr.set(Some((r, counter)));
+ let r = op();
+ hr.set(None);
+ r
+ })
+}
impl<'a, T: Print> Print for &'a T {
fn print<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result {
define_print! {
() ty::RegionKind, (self, f, cx) {
display {
- if cx.is_verbose {
+ if cx.is_verbose || get_highlight_region().is_some() {
return self.print_debug(f, cx);
}
impl fmt::Debug for ty::RegionVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if let Some((region, counter)) = get_highlight_region() {
+ debug!("RegionVid.fmt: region={:?} self={:?} counter={:?}", region, self, counter);
+ return if *self == region {
+ write!(f, "'{:?}", counter)
+ } else {
+ write!(f, "'_")
+ }
+ }
+
write!(f, "'_#{}r", self.index())
}
}
TyRef(r, ty, mutbl) => {
write!(f, "&")?;
let s = r.print_to_string(cx);
- write!(f, "{}", s)?;
- if !s.is_empty() {
- write!(f, " ")?;
+ if s != "'_" {
+ write!(f, "{}", s)?;
+ if !s.is_empty() {
+ write!(f, " ")?;
+ }
}
ty::TypeAndMut { ty, mutbl }.print(f, cx)
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
#![feature(rustc_private)]
#[macro_use] extern crate log;
//!
//! This API is completely unstable and subject to change.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![sanitizer_runtime]
#![feature(alloc_system)]
#![feature(sanitizer_runtime)]
.region_scope_tree
.yield_in_scope_for_expr(scope,
cmt.hir_id,
- self.bccx.body) {
+ self.bccx.body)
+ {
self.bccx.cannot_borrow_across_generator_yield(borrow_span,
yield_span,
Origin::Ast).emit();
+ self.bccx.signal_error();
}
}
new_loan, old_loan, old_loan, new_loan).err();
match (err_old_new, err_new_old) {
- (Some(mut err), None) | (None, Some(mut err)) => err.emit(),
+ (Some(mut err), None) | (None, Some(mut err)) => {
+ err.emit();
+ self.bccx.signal_error();
+ }
(Some(mut err_old), Some(mut err_new)) => {
err_old.emit();
+ self.bccx.signal_error();
err_new.cancel();
}
(None, None) => return true,
loan_span, &self.bccx.loan_path_to_string(&loan_path),
Origin::Ast)
.emit();
+ self.bccx.signal_error();
}
}
}
};
err.emit();
+ self.bccx.signal_error();
}
}
}
self.bccx.cannot_assign_to_borrowed(
span, loan.span, &self.bccx.loan_path_to_string(loan_path), Origin::Ast)
.emit();
+ self.bccx.signal_error();
}
}
"captured outer variable");
}
err.emit();
+ bccx.signal_error();
}
}
use rustc::middle::dataflow::BitwiseOperator;
use rustc::middle::dataflow::DataFlowOperator;
use rustc::middle::dataflow::KillFrom;
-use rustc::middle::borrowck::BorrowCheckResult;
+use rustc::middle::borrowck::{BorrowCheckResult, SignalledError};
use rustc::hir::def_id::{DefId, LocalDefId};
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc_mir::util::suggest_ref_mut;
use rustc::util::nodemap::FxHashSet;
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
use std::fmt;
use std::rc::Rc;
use rustc_data_structures::sync::Lrc;
fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
-> Lrc<BorrowCheckResult>
{
- assert!(tcx.use_ast_borrowck());
+ assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck());
debug!("borrowck(body_owner_def_id={:?})", owner_def_id);
// and do not need borrowchecking.
return Lrc::new(BorrowCheckResult {
used_mut_nodes: FxHashSet(),
+ signalled_any_error: SignalledError::NoErrorsSeen,
})
}
_ => { }
owner_def_id,
body,
used_mut_nodes: RefCell::new(FxHashSet()),
+ signalled_any_error: Cell::new(SignalledError::NoErrorsSeen),
};
// Eventually, borrowck will always read the MIR, but at the
Lrc::new(BorrowCheckResult {
used_mut_nodes: bccx.used_mut_nodes.into_inner(),
+ signalled_any_error: bccx.signalled_any_error.into_inner(),
})
}
owner_def_id,
body,
used_mut_nodes: RefCell::new(FxHashSet()),
+ signalled_any_error: Cell::new(SignalledError::NoErrorsSeen),
};
let dataflow_data = build_borrowck_dataflow_data(&mut bccx, true, body_id, |_| cfg);
body: &'tcx hir::Body,
used_mut_nodes: RefCell<FxHashSet<HirId>>,
+
+ signalled_any_error: Cell<SignalledError>,
+}
+
+
+impl<'a, 'tcx: 'a> BorrowckCtxt<'a, 'tcx> {
+ fn signal_error(&self) {
+ self.signalled_any_error.set(SignalledError::SawSomeError);
+ }
}
impl<'a, 'b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> {
.span_label(use_span, format!("use of possibly uninitialized `{}`",
self.loan_path_to_string(lp)))
.emit();
+ self.signal_error();
return;
}
_ => {
// not considered particularly helpful.
err.emit();
+ self.signal_error();
}
pub fn report_partial_reinitialization_of_uninitialized_structure(
&self.loan_path_to_string(lp),
Origin::Ast)
.emit();
+ self.signal_error();
}
pub fn report_reassigned_immutable_variable(&self,
self.loan_path_to_string(lp)));
}
err.emit();
+ self.signal_error();
}
pub fn struct_span_err_with_code<S: Into<MultiSpan>>(&self,
self.tcx.hir.hir_to_node_id(err.cmt.hir_id)
);
db.emit();
+ self.signal_error();
}
err_out_of_scope(super_scope, sub_scope, cause) => {
let msg = match opt_loan_path(&err.cmt) {
}
db.emit();
+ self.signal_error();
}
err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
let descr = self.cmt_to_path_or_string(err.cmt);
"");
db.emit();
+ self.signal_error();
}
}
}
err.help("closures behind references must be called via `&mut`");
}
err.emit();
+ self.signal_error();
}
/// Given a type, if it is an immutable reference, return a suggestion to make it mutable
cmt_path_or_string),
suggestion)
.emit();
+ self.signal_error();
}
fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> {
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![allow(non_camel_case_types)]
-#![deny(bare_trait_objects)]
#![feature(from_ref)]
#![feature(quote)]
use std::fmt;
use std::fs;
use std::io;
+use std::iter;
use std::path::{Path, PathBuf};
use std::process::{Output, Stdio};
use std::str;
}
let file = tmpdir.join("linker-arguments");
let bytes = if sess.target.target.options.is_like_msvc {
- let mut out = vec![];
+ let mut out = Vec::with_capacity((1 + args.len()) * 2);
// start the stream with a UTF-16 BOM
- for c in vec![0xFEFF].into_iter().chain(args.encode_utf16()) {
+ for c in iter::once(0xFEFF).chain(args.encode_utf16()) {
// encode in little endian
out.push(c as u8);
out.push((c >> 8) as u8);
#![feature(custom_attribute)]
#![feature(fs_read_write)]
#![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
#![feature(libc)]
#![feature(quote)]
#![feature(range_contains)]
#![feature(box_syntax)]
#![feature(custom_attribute)]
#![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
//!
//! This API is completely unstable and subject to change.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
//!
//! This API is completely unstable and subject to change.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
}
}
+ pub fn is_error(&self) -> bool {
+ match self.level {
+ Level::Bug |
+ Level::Fatal |
+ Level::PhaseFatal |
+ Level::Error |
+ Level::FailureNote => {
+ true
+ }
+
+ Level::Warning |
+ Level::Note |
+ Level::Help |
+ Level::Cancelled => {
+ false
+ }
+ }
+ }
+
/// Cancel the diagnostic (a structured diagnostic must either be emitted or
/// canceled or it will panic when dropped).
pub fn cancel(&mut self) {
buffered_diagnostics.push(diagnostic);
}
- pub fn is_error(&self) -> bool {
- match self.level {
- Level::Bug |
- Level::Fatal |
- Level::PhaseFatal |
- Level::Error |
- Level::FailureNote => {
- true
- }
-
- Level::Warning |
- Level::Note |
- Level::Help |
- Level::Cancelled => {
- false
- }
- }
- }
-
/// Convenience function for internal use, clients should use one of the
/// span_* methods instead.
pub fn sub<S: Into<MultiSpan>>(
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
//! Support for serializing the dep-graph and reloading it.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
//!
//! This API is completely unstable and subject to change.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]
-#![deny(bare_trait_objects)]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![sanitizer_runtime]
#![feature(alloc_system)]
#![feature(sanitizer_runtime)]
use std::mem;
#[test]
- fn test_loading_cosine() {
+ fn test_loading_atoi() {
if cfg!(windows) {
return
}
- // The math library does not need to be loaded since it is already
- // statically linked in
- let libm = match DynamicLibrary::open(None) {
+ // The C library does not need to be loaded since it is already linked in
+ let lib = match DynamicLibrary::open(None) {
Err(error) => panic!("Could not load self as module: {}", error),
- Ok(libm) => libm
+ Ok(lib) => lib
};
- let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
- match libm.symbol("cos") {
- Err(error) => panic!("Could not load function cos: {}", error),
- Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
+ let atoi: extern fn(*const libc::c_char) -> libc::c_int = unsafe {
+ match lib.symbol("atoi") {
+ Err(error) => panic!("Could not load function atoi: {}", error),
+ Ok(atoi) => mem::transmute::<*mut u8, _>(atoi)
}
};
- let argument = 0.0;
- let expected_result = 1.0;
- let result = cosine(argument);
+ let argument = CString::new("1383428980").unwrap();
+ let expected_result = 0x52757374;
+ let result = atoi(argument.as_ptr());
if result != expected_result {
- panic!("cos({}) != {} but equaled {} instead", argument,
+ panic!("atoi({:?}) != {} but equaled {} instead", argument,
expected_result, result)
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
// Consider the borrow not activated to start. When we find an activation, we'll update
// this field.
- let borrow_data = &mut self.idx_vec[borrow_index];
- borrow_data.activation_location = TwoPhaseActivation::NotActivated;
+ {
+ let borrow_data = &mut self.idx_vec[borrow_index];
+ borrow_data.activation_location = TwoPhaseActivation::NotActivated;
+ }
// Insert `temp` into the list of pending activations. From
// now on, we'll be on the lookout for a use of it. Note that
// we are guaranteed that this use will come after the
// assignment.
let old_value = self.pending_activations.insert(temp, borrow_index);
- assert!(old_value.is_none());
+ if let Some(old_index) = old_value {
+ span_bug!(self.mir.source_info(start_location).span,
+ "found already pending activation for temp: {:?} \
+ at borrow_index: {:?} with associated data {:?}",
+ temp, old_index, self.idx_vec[old_index]);
+ }
}
}
use rustc::hir::map::definitions::DefPathData;
use rustc::infer::InferCtxt;
use rustc::lint::builtin::UNUSED_MUT;
+use rustc::middle::borrowck::SignalledError;
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place};
use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
use rustc::ty::query::Providers;
use rustc::ty::{self, ParamEnv, TyCtxt};
-use rustc_errors::{Diagnostic, DiagnosticBuilder};
+use rustc_errors::{Diagnostic, DiagnosticBuilder, Level};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_set::IdxSetBuf;
}
}
- for diag in mbcx.errors_buffer.drain(..) {
- DiagnosticBuilder::new_diagnostic(mbcx.tcx.sess.diagnostic(), diag).emit();
+ if mbcx.errors_buffer.len() > 0 {
+ if tcx.migrate_borrowck() {
+ match tcx.borrowck(def_id).signalled_any_error {
+ SignalledError::NoErrorsSeen => {
+ // if AST-borrowck signalled no errors, then
+ // downgrade all the buffered MIR-borrowck errors
+ // to warnings.
+ for err in &mut mbcx.errors_buffer {
+ if err.is_error() {
+ err.level = Level::Warning;
+ err.warn("This error has been downgraded to a warning \
+ for backwards compatibility with previous releases.\n\
+ It represents potential unsoundness in your code.\n\
+ This warning will become a hard error in the future.");
+ }
+ }
+ }
+ SignalledError::SawSomeError => {
+ // if AST-borrowck signalled a (cancelled) error,
+ // then we will just emit the buffered
+ // MIR-borrowck errors as normal.
+ }
+ }
+ }
+
+ for diag in mbcx.errors_buffer.drain(..) {
+ DiagnosticBuilder::new_diagnostic(mbcx.tcx.sess.diagnostic(), diag).emit();
+ }
}
let result = BorrowCheckResult {
}
}
- Reservation(WriteKind::Move)
- | Write(WriteKind::Move)
- | Reservation(WriteKind::StorageDeadOrDrop)
- | Reservation(WriteKind::MutableBorrow(BorrowKind::Shared))
- | Write(WriteKind::StorageDeadOrDrop)
- | Write(WriteKind::MutableBorrow(BorrowKind::Shared)) => {
+ Reservation(wk @ WriteKind::Move)
+ | Write(wk @ WriteKind::Move)
+ | Reservation(wk @ WriteKind::StorageDeadOrDrop)
+ | Reservation(wk @ WriteKind::MutableBorrow(BorrowKind::Shared))
+ | Write(wk @ WriteKind::StorageDeadOrDrop)
+ | Write(wk @ WriteKind::MutableBorrow(BorrowKind::Shared)) => {
if let Err(_place_err) = self.is_mutable(place, is_local_mutation_allowed) {
- self.tcx.sess.delay_span_bug(
- span,
- &format!(
- "Accessing `{:?}` with the kind `{:?}` shouldn't be possible",
- place, kind
- ),
- );
+ if self.tcx.migrate_borrowck() {
+ // rust-lang/rust#46908: In pure NLL mode this
+ // code path should be unreachable (and thus
+ // we signal an ICE in the else branch
+ // here). But we can legitimately get here
+ // under borrowck=migrate mode, so instead of
+ // ICE'ing we instead report a legitimate
+ // error (which will then be downgraded to a
+ // warning by the migrate machinery).
+ error_access = match wk {
+ WriteKind::MutableBorrow(_) => AccessKind::MutableBorrow,
+ WriteKind::Move => AccessKind::Move,
+ WriteKind::StorageDeadOrDrop |
+ WriteKind::Mutate => AccessKind::Mutate,
+ };
+ self.report_mutability_error(
+ place,
+ span,
+ _place_err,
+ error_access,
+ location,
+ );
+ } else {
+ self.tcx.sess.delay_span_bug(
+ span,
+ &format!(
+ "Accessing `{:?}` with the kind `{:?}` shouldn't be possible",
+ place, kind
+ ),
+ );
+ }
}
return false;
}
pub(super) enum AccessKind {
MutableBorrow,
Mutate,
+ Move,
}
impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
if let Some(desc) = access_place_desc {
item_msg = format!("`{}`", desc);
reason = match error_access {
+ AccessKind::Move |
AccessKind::Mutate => format!(" which is behind a {}", pointer_type),
AccessKind::MutableBorrow => {
format!(", as it is behind a {}", pointer_type)
let span = match error_access {
+ AccessKind::Move => {
+ err = self.tcx
+ .cannot_move_out_of(span, &(item_msg + &reason), Origin::Mir);
+ act = "move";
+ acted_on = "moved";
+ span
+ }
AccessKind::Mutate => {
err = self.tcx
.cannot_assign(span, &(item_msg + &reason), Origin::Mir);
enum ConstraintCategory {
Cast,
Assignment,
- AssignmentToUpvar,
Return,
- CallArgumentToUpvar,
CallArgument,
Other,
Boring,
impl fmt::Display for ConstraintCategory {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ // Must end with a space. Allows for empty names to be provided.
match self {
- ConstraintCategory::Assignment | ConstraintCategory::AssignmentToUpvar => {
- write!(f, "assignment")
- }
- ConstraintCategory::Return => write!(f, "return"),
- ConstraintCategory::Cast => write!(f, "cast"),
- ConstraintCategory::CallArgument | ConstraintCategory::CallArgumentToUpvar => {
- write!(f, "argument")
- }
- _ => write!(f, "free region"),
+ ConstraintCategory::Assignment => write!(f, "assignment "),
+ ConstraintCategory::Return => write!(f, "return "),
+ ConstraintCategory::Cast => write!(f, "cast "),
+ ConstraintCategory::CallArgument => write!(f, "argument "),
+ _ => write!(f, ""),
}
}
}
"constraint_is_interesting: locations={:?} constraint={:?}",
constraint.locations, constraint
);
- if let Locations::Interesting(_) = constraint.locations {
- true
- } else {
- false
+
+ match constraint.locations {
+ Locations::Interesting(_) | Locations::All => true,
+ _ => false,
}
}
}
}
- let category = match (
- category,
+ let (fr_is_local, outlived_fr_is_local): (bool, bool) = (
self.universal_regions.is_local_free_region(fr),
self.universal_regions.is_local_free_region(outlived_fr),
- ) {
- (ConstraintCategory::Assignment, true, false) => ConstraintCategory::AssignmentToUpvar,
- (ConstraintCategory::CallArgument, true, false) => {
- ConstraintCategory::CallArgumentToUpvar
- }
- (category, _, _) => category,
+ );
+ debug!("report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}",
+ fr_is_local, outlived_fr_is_local, category);
+
+ match (category, fr_is_local, outlived_fr_is_local) {
+ (ConstraintCategory::Assignment, true, false) |
+ (ConstraintCategory::CallArgument, true, false) =>
+ self.report_escaping_data_error(mir, infcx, mir_def_id, fr, outlived_fr,
+ category, span, errors_buffer),
+ _ =>
+ self.report_general_error(mir, infcx, mir_def_id, fr, fr_is_local,
+ outlived_fr, outlived_fr_is_local,
+ category, span, errors_buffer),
};
-
- debug!("report_error: category={:?}", category);
- match category {
- ConstraintCategory::AssignmentToUpvar | ConstraintCategory::CallArgumentToUpvar => self
- .report_closure_error(
- mir,
- infcx,
- mir_def_id,
- fr,
- outlived_fr,
- category,
- span,
- errors_buffer,
- ),
- _ => self.report_general_error(
- mir,
- infcx,
- mir_def_id,
- fr,
- outlived_fr,
- category,
- span,
- errors_buffer,
- ),
- }
}
- fn report_closure_error(
+ fn report_escaping_data_error(
&self,
mir: &Mir<'tcx>,
infcx: &InferCtxt<'_, '_, 'tcx>,
let outlived_fr_name_and_span =
self.get_var_name_and_span_for_region(infcx.tcx, mir, outlived_fr);
+ let escapes_from = if infcx.tcx.is_closure(mir_def_id) { "closure" } else { "function" };
+
if fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none() {
- return self.report_general_error(
- mir,
- infcx,
- mir_def_id,
- fr,
- outlived_fr,
- category,
- span,
- errors_buffer,
- );
+ return self.report_general_error(mir, infcx, mir_def_id,
+ fr, true, outlived_fr, false,
+ category, span, errors_buffer);
}
- let mut diag = infcx
- .tcx
- .sess
- .struct_span_err(span, &format!("borrowed data escapes outside of closure"));
+ let mut diag = infcx.tcx.sess.struct_span_err(
+ span, &format!("borrowed data escapes outside of {}", escapes_from),
+ );
if let Some((outlived_fr_name, outlived_fr_span)) = outlived_fr_name_and_span {
if let Some(name) = outlived_fr_name {
diag.span_label(
outlived_fr_span,
- format!("`{}` is declared here, outside of the closure body", name),
+ format!("`{}` is declared here, outside of the {} body", name, escapes_from),
);
}
}
if let Some(name) = fr_name {
diag.span_label(
fr_span,
- format!(
- "`{}` is a reference that is only valid in the closure body",
- name
- ),
+ format!("`{}` is a reference that is only valid in the {} body",
+ name, escapes_from),
);
- diag.span_label(span, format!("`{}` escapes the closure body here", name));
+ diag.span_label(span, format!("`{}` escapes the {} body here",
+ name, escapes_from));
}
}
infcx: &InferCtxt<'_, '_, 'tcx>,
mir_def_id: DefId,
fr: RegionVid,
+ fr_is_local: bool,
outlived_fr: RegionVid,
+ outlived_fr_is_local: bool,
category: ConstraintCategory,
span: Span,
errors_buffer: &mut Vec<Diagnostic>,
);
let counter = &mut 1;
- let fr_name = self.give_region_a_name(infcx.tcx, mir, mir_def_id, fr, counter, &mut diag);
- let outlived_fr_name =
- self.give_region_a_name(infcx.tcx, mir, mir_def_id, outlived_fr, counter, &mut diag);
-
- diag.span_label(
- span,
- format!(
- "{} requires that `{}` must outlive `{}`",
- category, fr_name, outlived_fr_name,
- ),
- );
+ let fr_name = self.give_region_a_name(
+ infcx, mir, mir_def_id, fr, counter, &mut diag);
+ let outlived_fr_name = self.give_region_a_name(
+ infcx, mir, mir_def_id, outlived_fr, counter, &mut diag);
+
+ let mir_def_name = if infcx.tcx.is_closure(mir_def_id) { "closure" } else { "function" };
+
+ match (category, outlived_fr_is_local, fr_is_local) {
+ (ConstraintCategory::Return, true, _) => {
+ diag.span_label(span, format!(
+ "{} was supposed to return data with lifetime `{}` but it is returning \
+ data with lifetime `{}`",
+ mir_def_name, fr_name, outlived_fr_name,
+ ));
+ },
+ _ => {
+ diag.span_label(span, format!(
+ "{}requires that `{}` must outlive `{}`",
+ category, fr_name, outlived_fr_name,
+ ));
+ },
+ }
diag.buffer(errors_buffer);
}
use borrow_check::nll::ToRegionVid;
use rustc::hir;
use rustc::hir::def_id::DefId;
+use rustc::infer::InferCtxt;
use rustc::mir::Mir;
use rustc::ty::subst::{Substs, UnpackedKind};
use rustc::ty::{self, RegionVid, Ty, TyCtxt};
+use rustc::util::ppaux::with_highlight_region;
use rustc_errors::DiagnosticBuilder;
use syntax::ast::Name;
use syntax::symbol::keywords;
/// and then return the name `'1` for us to use.
crate fn give_region_a_name(
&self,
- tcx: TyCtxt<'_, '_, 'tcx>,
+ infcx: &InferCtxt<'_, '_, 'tcx>,
mir: &Mir<'tcx>,
mir_def_id: DefId,
fr: RegionVid,
assert!(self.universal_regions.is_universal_region(fr));
- self.give_name_from_error_region(tcx, mir_def_id, fr, counter, diag)
+ self.give_name_from_error_region(infcx.tcx, mir_def_id, fr, counter, diag)
.or_else(|| {
self.give_name_if_anonymous_region_appears_in_arguments(
- tcx, mir, mir_def_id, fr, counter, diag)
+ infcx, mir, mir_def_id, fr, counter, diag)
})
.or_else(|| {
self.give_name_if_anonymous_region_appears_in_upvars(
- tcx, mir, fr, counter, diag)
+ infcx.tcx, mir, fr, counter, diag)
})
.or_else(|| {
- self.give_name_if_anonymous_region_appears_in_output(tcx, mir, fr, counter, diag)
+ self.give_name_if_anonymous_region_appears_in_output(
+ infcx.tcx, mir, fr, counter, diag)
})
.unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr))
}
/// ```
fn give_name_if_anonymous_region_appears_in_arguments(
&self,
- tcx: TyCtxt<'_, '_, 'tcx>,
+ infcx: &InferCtxt<'_, '_, 'tcx>,
mir: &Mir<'tcx>,
mir_def_id: DefId,
fr: RegionVid,
diag: &mut DiagnosticBuilder<'_>,
) -> Option<InternedString> {
let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
- let argument_index = self.get_argument_index_for_region(tcx, fr)?;
+ let argument_index = self.get_argument_index_for_region(infcx.tcx, fr)?;
let arg_ty =
self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index];
if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(
- tcx,
+ infcx,
+ mir,
mir_def_id,
fr,
arg_ty,
fn give_name_if_we_can_match_hir_ty_from_argument(
&self,
- tcx: TyCtxt<'_, '_, 'tcx>,
+ infcx: &InferCtxt<'_, '_, 'tcx>,
+ mir: &Mir<'tcx>,
mir_def_id: DefId,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
counter: &mut usize,
diag: &mut DiagnosticBuilder<'_>,
) -> Option<InternedString> {
- let mir_node_id = tcx.hir.as_local_node_id(mir_def_id)?;
- let fn_decl = tcx.hir.fn_decl(mir_node_id)?;
+ let mir_node_id = infcx.tcx.hir.as_local_node_id(mir_def_id)?;
+ let fn_decl = infcx.tcx.hir.fn_decl(mir_node_id)?;
let argument_hir_ty: &hir::Ty = &fn_decl.inputs[argument_index];
match argument_hir_ty.node {
// This indicates a variable with no type annotation, like
// `|x|`... in that case, we can't highlight the type but
// must highlight the variable.
- hir::TyKind::Infer => None,
+ hir::TyKind::Infer => self.give_name_if_we_cannot_match_hir_ty(
+ infcx,
+ mir,
+ needle_fr,
+ argument_ty,
+ counter,
+ diag,
+ ),
_ => self.give_name_if_we_can_match_hir_ty(
- tcx,
+ infcx.tcx,
needle_fr,
argument_ty,
argument_hir_ty,
}
}
+ /// Attempts to highlight the specific part of a type in an argument
+ /// that has no type annotation.
+ /// For example, we might produce an annotation like this:
+ ///
+ /// ```
+ /// | foo(|a, b| b)
+ /// | - -
+ /// | | |
+ /// | | has type `&'1 u32`
+ /// | has type `&'2 u32`
+ /// ```
+ fn give_name_if_we_cannot_match_hir_ty(
+ &self,
+ infcx: &InferCtxt<'_, '_, 'tcx>,
+ mir: &Mir<'tcx>,
+ needle_fr: RegionVid,
+ argument_ty: Ty<'tcx>,
+ counter: &mut usize,
+ diag: &mut DiagnosticBuilder<'_>,
+ ) -> Option<InternedString> {
+ let type_name = with_highlight_region(needle_fr, *counter, || {
+ infcx.extract_type_name(&argument_ty)
+ });
+
+ debug!("give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
+ type_name, needle_fr);
+ let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() {
+ // Only add a label if we can confirm that a region was labelled.
+ let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?;
+ let (_, span) = self.get_argument_name_and_span_for_region(mir, argument_index);
+ diag.span_label(span, format!("has type `{}`", type_name));
+
+ // This counter value will already have been used, so this function will increment it
+ // so the next value will be used next and return the region name that would have been
+ // used.
+ Some(self.synthesize_region_name(counter))
+ } else {
+ None
+ };
+
+ assigned_region_name
+ }
+
/// Attempts to highlight the specific part of a type annotation
/// that contains the anonymous reference we want to give a name
/// to. For example, we might produce an annotation like this:
use rustc::hir;
use syntax_pos::Span;
+use std::slice;
+
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
pub fn ast_block(&mut self,
destination: &Place<'tcx>,
None,
remainder_span,
lint_level,
- &pattern,
+ slice::from_ref(&pattern),
ArmHasGuard(false),
Some((None, initializer_span)),
);
})
}));
} else {
- scope = this.declare_bindings(None, remainder_span, lint_level, &pattern,
- ArmHasGuard(false), None);
+ scope = this.declare_bindings(
+ None, remainder_span, lint_level, slice::from_ref(&pattern),
+ ArmHasGuard(false), None);
// FIXME(#47184): We currently only insert `UserAssertTy` statements for
// patterns that are bindings, this is as we do not want to deconstruct
//! See docs in build/expr/mod.rs
use build::{BlockAnd, BlockAndExtension, Builder};
-use build::ForGuard::{OutsideGuard, RefWithinGuard, ValWithinGuard};
+use build::ForGuard::{OutsideGuard, RefWithinGuard};
use build::expr::category::Category;
use hair::*;
use rustc::mir::*;
block.and(Place::Local(Local::new(1)))
}
ExprKind::VarRef { id } => {
- let place = if this.is_bound_var_in_guard(id) {
- if this.hir.tcx().all_pat_vars_are_implicit_refs_within_guards() {
- let index = this.var_local_id(id, RefWithinGuard);
- Place::Local(index).deref()
- } else {
- let index = this.var_local_id(id, ValWithinGuard);
- Place::Local(index)
- }
+ let place = if this.is_bound_var_in_guard(id) &&
+ this.hir.tcx().all_pat_vars_are_implicit_refs_within_guards()
+ {
+ let index = this.var_local_id(id, RefWithinGuard);
+ Place::Local(index).deref()
} else {
let index = this.var_local_id(id, OutsideGuard);
Place::Local(index)
let body = self.hir.mirror(arm.body.clone());
let scope = self.declare_bindings(None, body.span,
LintLevel::Inherited,
- &arm.patterns[0],
+ &arm.patterns[..],
ArmHasGuard(arm.guard.is_some()),
Some((Some(&discriminant_place), discriminant_span)));
(body, scope.unwrap_or(self.source_scope))
arms.iter()
.enumerate()
.flat_map(|(arm_index, arm)| {
- arm.patterns.iter()
- .map(move |pat| (arm_index, pat, arm.guard.clone()))
+ arm.patterns.iter().enumerate()
+ .map(move |(pat_index, pat)| {
+ (arm_index, pat_index, pat, arm.guard.clone())
+ })
})
.zip(pre_binding_blocks.iter().zip(pre_binding_blocks.iter().skip(1)))
- .map(|((arm_index, pattern, guard),
+ .map(|((arm_index, pat_index, pattern, guard),
(pre_binding_block, next_candidate_pre_binding_block))| {
if let (true, Some(borrow_temp)) = (tcx.emit_read_for_match(),
bindings: vec![],
guard,
arm_index,
+ pat_index,
pre_binding_block: *pre_binding_block,
next_candidate_pre_binding_block: *next_candidate_pre_binding_block,
}
// since we don't call `match_candidates`, next fields is unused
arm_index: 0,
+ pat_index: 0,
pre_binding_block: block,
next_candidate_pre_binding_block: block
};
mut visibility_scope: Option<SourceScope>,
scope_span: Span,
lint_level: LintLevel,
- pattern: &Pattern<'tcx>,
+ patterns: &[Pattern<'tcx>],
has_guard: ArmHasGuard,
opt_match_place: Option<(Option<&Place<'tcx>>, Span)>)
-> Option<SourceScope> {
assert!(!(visibility_scope.is_some() && lint_level.is_explicit()),
"can't have both a visibility and a lint scope at the same time");
let mut scope = self.source_scope;
- self.visit_bindings(pattern, &mut |this, mutability, name, mode, var, span, ty| {
+ let num_patterns = patterns.len();
+ self.visit_bindings(&patterns[0], &mut |this, mutability, name, mode, var, span, ty| {
if visibility_scope.is_none() {
visibility_scope = Some(this.new_source_scope(scope_span,
LintLevel::Inherited,
scope,
};
let visibility_scope = visibility_scope.unwrap();
- this.declare_binding(source_info, visibility_scope, mutability, name, mode, var,
- ty, has_guard, opt_match_place.map(|(x, y)| (x.cloned(), y)));
+ this.declare_binding(source_info, visibility_scope, mutability, name, mode,
+ num_patterns, var, ty, has_guard,
+ opt_match_place.map(|(x, y)| (x.cloned(), y)));
});
visibility_scope
}
// ...and the blocks for add false edges between candidates
pre_binding_block: BasicBlock,
next_candidate_pre_binding_block: BasicBlock,
+
+ // This uniquely identifies this candidate *within* the arm.
+ pat_index: usize,
}
#[derive(Clone, Debug)]
let autoref = self.hir.tcx().all_pat_vars_are_implicit_refs_within_guards();
if let Some(guard) = candidate.guard {
if autoref {
- self.bind_matched_candidate_for_guard(block, &candidate.bindings);
+ self.bind_matched_candidate_for_guard(
+ block, candidate.pat_index, &candidate.bindings);
let guard_frame = GuardFrame {
locals: candidate.bindings.iter()
.map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode))
// and thus all code/comments assume we are in that context.
fn bind_matched_candidate_for_guard(&mut self,
block: BasicBlock,
+ pat_index: usize,
bindings: &[Binding<'tcx>]) {
- debug!("bind_matched_candidate_for_guard(block={:?}, bindings={:?})",
- block, bindings);
+ debug!("bind_matched_candidate_for_guard(block={:?}, pat_index={:?}, bindings={:?})",
+ block, pat_index, bindings);
// Assign each of the bindings. Since we are binding for a
// guard expression, this will never trigger moves out of the
// used by the arm body itself. This eases
// observing two-phase borrow restrictions.
let val_for_guard = self.storage_live_binding(
- block, binding.var_id, binding.span, ValWithinGuard);
- self.schedule_drop_for_binding(binding.var_id, binding.span, ValWithinGuard);
+ block, binding.var_id, binding.span, ValWithinGuard(pat_index));
+ self.schedule_drop_for_binding(
+ binding.var_id, binding.span, ValWithinGuard(pat_index));
// rust-lang/rust#27282: We reuse the two-phase
// borrow infrastructure so that the mutable
/// Each binding (`ref mut var`/`ref var`/`mut var`/`var`, where
/// the bound `var` has type `T` in the arm body) in a pattern
- /// maps to *two* locals. The first local is a binding for
+ /// maps to `2+N` locals. The first local is a binding for
/// occurrences of `var` in the guard, which will all have type
- /// `&T`. The second local is a binding for occurrences of `var`
- /// in the arm body, which will have type `T`.
+ /// `&T`. The N locals are bindings for the `T` that is referenced
+ /// by the first local; they are not used outside of the
+ /// guard. The last local is a binding for occurrences of `var` in
+ /// the arm body, which will have type `T`.
+ ///
+ /// The reason we have N locals rather than just 1 is to
+ /// accommodate rust-lang/rust#51348: If the arm has N candidate
+ /// patterns, then in general they can correspond to distinct
+ /// parts of the matched data, and we want them to be distinct
+ /// temps in order to simplify checks performed by our internal
+ /// leveraging of two-phase borrows).
fn declare_binding(&mut self,
source_info: SourceInfo,
visibility_scope: SourceScope,
mutability: Mutability,
name: Name,
mode: BindingMode,
+ num_patterns: usize,
var_id: NodeId,
var_ty: Ty<'tcx>,
has_guard: ArmHasGuard,
};
let for_arm_body = self.local_decls.push(local.clone());
let locals = if has_guard.0 && tcx.all_pat_vars_are_implicit_refs_within_guards() {
- let val_for_guard = self.local_decls.push(local);
+ let mut vals_for_guard = Vec::with_capacity(num_patterns);
+ for _ in 0..num_patterns {
+ let val_for_guard_idx = self.local_decls.push(local.clone());
+ vals_for_guard.push(val_for_guard_idx);
+ }
let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
mutability,
ty: tcx.mk_imm_ref(tcx.types.re_empty, var_ty),
internal: false,
is_user_variable: Some(ClearCrossCrate::Set(BindingForm::RefForGuard)),
});
- LocalsForNode::Three { val_for_guard, ref_for_guard, for_arm_body }
+ LocalsForNode::ForGuard { vals_for_guard, ref_for_guard, for_arm_body }
} else {
LocalsForNode::One(for_arm_body)
};
bindings: candidate.bindings.clone(),
guard: candidate.guard.clone(),
arm_index: candidate.arm_index,
+ pat_index: candidate.pat_index,
pre_binding_block: candidate.pre_binding_block,
next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block,
}
bindings: candidate.bindings.clone(),
guard: candidate.guard.clone(),
arm_index: candidate.arm_index,
+ pat_index: candidate.pat_index,
pre_binding_block: candidate.pre_binding_block,
next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block,
}
#[derive(Debug)]
enum LocalsForNode {
+ /// In the usual case, a node-id for an identifier maps to at most
+ /// one Local declaration.
One(Local),
- Three { val_for_guard: Local, ref_for_guard: Local, for_arm_body: Local },
+
+ /// The exceptional case is identifiers in a match arm's pattern
+ /// that are referenced in a guard of that match arm. For these,
+ /// we can have `2+k` Locals, where `k` is the number of candidate
+ /// patterns (separated by `|`) in the arm.
+ ///
+ /// * `for_arm_body` is the Local used in the arm body (which is
+ /// just like the `One` case above),
+ ///
+ /// * `ref_for_guard` is the Local used in the arm's guard (which
+ /// is a reference to a temp that is an alias of
+ /// `for_arm_body`).
+ ///
+ /// * `vals_for_guard` is the `k` Locals; at most one of them will
+ /// get initialized by the arm's execution, and after it is
+ /// initialized, `ref_for_guard` will be assigned a reference to
+ /// it.
+ ///
+ /// There reason we have `k` Locals rather than just 1 is to
+ /// accommodate some restrictions imposed by two-phase borrows,
+ /// which apply when we have a `ref mut` pattern.
+ ForGuard { vals_for_guard: Vec<Local>, ref_for_guard: Local, for_arm_body: Local },
}
#[derive(Debug)]
/// 3. the temp for use outside of guard expressions.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum ForGuard {
- ValWithinGuard,
+ /// The `usize` identifies for which candidate pattern we want the
+ /// local binding. We keep a temp per-candidate to accommodate
+ /// two-phase borrows (see `LocalsForNode` documentation).
+ ValWithinGuard(usize),
RefWithinGuard,
OutsideGuard,
}
fn local_id(&self, for_guard: ForGuard) -> Local {
match (self, for_guard) {
(&LocalsForNode::One(local_id), ForGuard::OutsideGuard) |
- (&LocalsForNode::Three { val_for_guard: local_id, .. }, ForGuard::ValWithinGuard) |
- (&LocalsForNode::Three { ref_for_guard: local_id, .. }, ForGuard::RefWithinGuard) |
- (&LocalsForNode::Three { for_arm_body: local_id, .. }, ForGuard::OutsideGuard) =>
+ (&LocalsForNode::ForGuard { ref_for_guard: local_id, .. }, ForGuard::RefWithinGuard) |
+ (&LocalsForNode::ForGuard { for_arm_body: local_id, .. }, ForGuard::OutsideGuard) =>
local_id,
- (&LocalsForNode::One(_), ForGuard::ValWithinGuard) |
+ (&LocalsForNode::ForGuard { ref vals_for_guard, .. },
+ ForGuard::ValWithinGuard(pat_idx)) =>
+ vals_for_guard[pat_idx],
+
+ (&LocalsForNode::One(_), ForGuard::ValWithinGuard(_)) |
(&LocalsForNode::One(_), ForGuard::RefWithinGuard) =>
bug!("anything with one local should never be within a guard."),
}
}
_ => {
scope = self.declare_bindings(scope, ast_body.span,
- LintLevel::Inherited, &pattern,
+ LintLevel::Inherited, &[pattern.clone()],
matches::ArmHasGuard(false),
Some((Some(&place), span)));
unpack!(block = self.place_into_pattern(block, pattern, &place, false));
*/
-#![deny(bare_trait_objects)]
-
#![feature(slice_patterns)]
#![feature(slice_sort_by_cached_key)]
#![feature(from_ref)]
let id = tcx.hir.as_local_node_id(src.def_id).unwrap();
let param_env = tcx.param_env(src.def_id).with_reveal_all();
- let move_data = MoveData::gather_moves(mir, tcx).unwrap();
+ let move_data = match MoveData::gather_moves(mir, tcx) {
+ Ok(move_data) => move_data,
+ Err((move_data, _move_errors)) => {
+ // The only way we should be allowing any move_errors
+ // in here is if we are in the migration path for the
+ // NLL-based MIR-borrowck.
+ //
+ // If we are in the migration path, we have already
+ // reported these errors as warnings to the user. So
+ // we will just ignore them here.
+ assert!(tcx.migrate_borrowck());
+ move_data
+ }
+ };
let elaborate_patch = {
let mir = &*mir;
let env = MoveDataParamEnv {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![sanitizer_runtime]
#![feature(alloc_system)]
#![feature(sanitizer_runtime)]
//!
//! This API is completely unstable and subject to change.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
// except according to those terms.
#![allow(bad_style)]
-#![deny(bare_trait_objects)]
pub struct Intrinsic {
pub inputs: &'static [&'static Type],
//! See the [`plugin` feature](../unstable-book/language-features/plugin.html) of
//! the Unstable Book for more examples.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(custom_attribute)]
#![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
#![recursion_limit="256"]
//! one that doesn't; the one that doesn't might get decent parallel
//! build speedups.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
--- /dev/null
+// Copyright 2016 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 {
+ let mut base = super::fuchsia_base::opts();
+ base.max_atomic_width = Some(128);
+
+ Ok(Target {
+ llvm_target: "aarch64-fuchsia".to_string(),
+ target_endian: "little".to_string(),
+ target_pointer_width: "64".to_string(),
+ target_c_int_width: "32".to_string(),
+ data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
+ arch: "aarch64".to_string(),
+ target_os: "fuchsia".to_string(),
+ target_env: "".to_string(),
+ target_vendor: "".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
+ options: TargetOptions {
+ abi_blacklist: super::arm_base::abi_blacklist(),
+ .. base
+ },
+ })
+}
+++ /dev/null
-// Copyright 2016 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 {
- let mut base = super::fuchsia_base::opts();
- base.max_atomic_width = Some(128);
-
- Ok(Target {
- llvm_target: "aarch64-unknown-fuchsia".to_string(),
- target_endian: "little".to_string(),
- target_pointer_width: "64".to_string(),
- target_c_int_width: "32".to_string(),
- data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
- arch: "aarch64".to_string(),
- target_os: "fuchsia".to_string(),
- target_env: "".to_string(),
- target_vendor: "unknown".to_string(),
- linker_flavor: LinkerFlavor::Gcc,
- options: TargetOptions {
- abi_blacklist: super::arm_base::abi_blacklist(),
- .. base
- },
- })
-}
executables: true,
target_family: Some("unix".to_string()),
linker_is_gnu: true,
- has_rpath: true,
+ has_rpath: false,
pre_link_args: args,
position_independent_executables: true,
has_elf_tls: true,
("x86_64-apple-darwin", x86_64_apple_darwin),
("i686-apple-darwin", i686_apple_darwin),
- ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia),
- ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),
+ ("aarch64-fuchsia", aarch64_fuchsia),
+ ("x86_64-fuchsia", x86_64_fuchsia),
("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),
--- /dev/null
+// Copyright 2016 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+ let mut base = super::fuchsia_base::opts();
+ base.cpu = "x86-64".to_string();
+ base.max_atomic_width = Some(64);
+ base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
+ base.stack_probes = true;
+
+ Ok(Target {
+ llvm_target: "x86_64-fuchsia".to_string(),
+ target_endian: "little".to_string(),
+ target_pointer_width: "64".to_string(),
+ target_c_int_width: "32".to_string(),
+ data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+ arch: "x86_64".to_string(),
+ target_os: "fuchsia".to_string(),
+ target_env: "".to_string(),
+ target_vendor: "".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
+ options: base,
+ })
+}
+++ /dev/null
-// Copyright 2016 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use spec::{LinkerFlavor, Target, TargetResult};
-
-pub fn target() -> TargetResult {
- let mut base = super::fuchsia_base::opts();
- base.cpu = "x86-64".to_string();
- base.max_atomic_width = Some(64);
- base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
- base.stack_probes = true;
-
- Ok(Target {
- llvm_target: "x86_64-unknown-fuchsia".to_string(),
- target_endian: "little".to_string(),
- target_pointer_width: "64".to_string(),
- target_c_int_width: "32".to_string(),
- data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
- arch: "x86_64".to_string(),
- target_os: "fuchsia".to_string(),
- target_env: "".to_string(),
- target_vendor: "unknown".to_string(),
- linker_flavor: LinkerFlavor::Gcc,
- options: base,
- })
-}
//! New recursive solver modeled on Chalk's recursive solver. Most of
//! the guts are broken up into modules; see the comments in those modules.
-#![deny(bare_trait_objects)]
-
#![feature(crate_in_paths)]
#![feature(crate_visibility_modifier)]
#![feature(extern_prelude)]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![sanitizer_runtime]
#![feature(alloc_system)]
#![feature(sanitizer_runtime)]
E0053,
"method `{}` has an incompatible type for trait",
trait_m.ident);
+ if let TypeError::Mutability = terr {
+ if let Some(trait_err_span) = trait_err_span {
+ if let Ok(trait_err_str) = tcx.sess.codemap().span_to_snippet(trait_err_span) {
+ diag.span_suggestion(
+ impl_err_span,
+ "consider change the type to match the mutability in trait",
+ format!("{}", trait_err_str),
+ );
+ }
+ }
+ }
infcx.note_type_err(&mut diag,
&cause,
}
}
ty::AssociatedKind::Existential => {
- // FIXME(oli-obk) implement existential types in trait impls
- unimplemented!()
+ // do nothing, existential types check themselves
}
}
tcx.mk_fn_def(def_id, substs)
}
ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
- ImplItemKind::Existential(ref _bounds) => {
+ ImplItemKind::Existential(_) => {
if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
report_assoc_ty_on_inherent_impl(tcx, item.span);
}
- // FIXME(oli-obk) implement existential types in trait impls
- unimplemented!()
+
+ find_existential_constraints(tcx, def_id)
}
ImplItemKind::Type(ref ty) => {
if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
}
impl<'a, 'tcx> ConstraintLocator<'a, 'tcx> {
fn check(&mut self, def_id: DefId) {
+ trace!("checking {:?}", def_id);
// don't try to check items that cannot possibly constrain the type
if !self.tcx.has_typeck_tables(def_id) {
+ trace!("no typeck tables for {:?}", def_id);
return;
}
let ty = self
let mut locator = ConstraintLocator { def_id, tcx, found: None };
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
let parent = tcx.hir.get_parent(node_id);
+ trace!("parent_id: {:?}", parent);
if parent == ast::CRATE_NODE_ID {
intravisit::walk_crate(&mut locator, tcx.hir.krate());
} else {
+ trace!("parent: {:?}", tcx.hir.get(parent));
match tcx.hir.get(parent) {
NodeItem(ref it) => intravisit::walk_item(&mut locator, it),
NodeImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it),
&item.generics
}
- NodeImplItem(item) => &item.generics,
+ NodeImplItem(item) => match item.node {
+ ImplItemKind::Existential(ref bounds) => {
+ let substs = Substs::identity_for_item(tcx, def_id);
+ let anon_ty = tcx.mk_anon(def_id, substs);
+
+ // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
+ let bounds = compute_bounds(&icx,
+ anon_ty,
+ bounds,
+ SizedByDefault::Yes,
+ tcx.def_span(def_id));
+
+ predicates.extend(bounds.predicates(tcx, anon_ty));
+ &item.generics
+ },
+ _ => &item.generics,
+ }
NodeItem(item) => {
match item.node {
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![allow(non_camel_case_types)]
-#![deny(bare_trait_objects)]
#![feature(box_patterns)]
#![feature(box_syntax)]
let fake = MAX_DEF_ID.with(|m| m.borrow().get(&self.def_id.krate)
.map(|id| self.def_id >= *id).unwrap_or(false));
- let def_id: &fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
+ let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
fmt.debug_struct("Item")
.field("source", &self.source)
/// The stack of module NodeIds up till this point
pub mod_ids: RefCell<Vec<NodeId>>,
pub crate_name: Option<String>,
- pub cstore: Rc<CrateStore>,
+ pub cstore: Rc<dyn CrateStore>,
pub populated_all_crate_impls: Cell<bool>,
// Note that external items for which `doc(hidden)` applies to are shown as
// non-reachable while local items aren't. This is because we're reusing
fn write_header(class: Option<&str>,
id: Option<&str>,
- out: &mut Write)
+ out: &mut dyn Write)
-> io::Result<()> {
write!(out, "<pre ")?;
if let Some(id) = id {
write!(out, "class=\"rust {}\">\n", class.unwrap_or(""))
}
-fn write_footer(out: &mut Write) -> io::Result<()> {
+fn write_footer(out: &mut dyn Write) -> io::Result<()> {
write!(out, "</pre>\n")
}
}
pub fn render<T: fmt::Display, S: fmt::Display>(
- dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
+ dst: &mut dyn io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
css_file_extension: bool, themes: &[PathBuf])
-> io::Result<()>
{
)
}
-pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
+pub fn redirect(dst: &mut dyn io::Write, url: &str) -> io::Result<()> {
// <script> triggers a redirect before refresh, so this is fine.
write!(dst,
r##"<!DOCTYPE html>
}
fn render_item(&self,
- writer: &mut io::Write,
+ writer: &mut dyn io::Write,
it: &clean::Item,
pushname: bool)
-> io::Result<()> {
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
- struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>);
+ struct Bomb(Arc<Mutex<Vec<u8>>>, Box<dyn Write+Send>);
impl Drop for Bomb {
fn drop(&mut self) {
let _ = self.1.write_all(&self.0.lock().unwrap());
Core encoding and decoding interfaces.
*/
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/",
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- fn cause(&self) -> Option<&Error> { None }
+ fn cause(&self) -> Option<&dyn Error> { None }
/// Get the `TypeId` of `self`
#[doc(hidden)]
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
- fn from(err: E) -> Box<Error + 'a> {
+impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
+ fn from(err: E) -> Box<dyn Error + 'a> {
Box::new(err)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<Error + Send + Sync + 'a> {
- fn from(err: E) -> Box<Error + Send + Sync + 'a> {
+impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
+ fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
Box::new(err)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl From<String> for Box<Error + Send + Sync> {
- fn from(err: String) -> Box<Error + Send + Sync> {
+impl From<String> for Box<dyn Error + Send + Sync> {
+ fn from(err: String) -> Box<dyn Error + Send + Sync> {
#[derive(Debug)]
struct StringError(String);
}
#[stable(feature = "string_box_error", since = "1.6.0")]
-impl From<String> for Box<Error> {
- fn from(str_err: String) -> Box<Error> {
- let err1: Box<Error + Send + Sync> = From::from(str_err);
- let err2: Box<Error> = err1;
+impl From<String> for Box<dyn Error> {
+ fn from(str_err: String) -> Box<dyn Error> {
+ let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
+ let err2: Box<dyn Error> = err1;
err2
}
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
- fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
+impl<'a, 'b> From<&'b str> for Box<dyn Error + Send + Sync + 'a> {
+ fn from(err: &'b str) -> Box<dyn Error + Send + Sync + 'a> {
From::from(String::from(err))
}
}
#[stable(feature = "string_box_error", since = "1.6.0")]
-impl<'a> From<&'a str> for Box<Error> {
- fn from(err: &'a str) -> Box<Error> {
+impl<'a> From<&'a str> for Box<dyn Error> {
+ fn from(err: &'a str) -> Box<dyn Error> {
From::from(String::from(err))
}
}
#[stable(feature = "cow_box_error", since = "1.22.0")]
-impl<'a, 'b> From<Cow<'b, str>> for Box<Error + Send + Sync + 'a> {
- fn from(err: Cow<'b, str>) -> Box<Error + Send + Sync + 'a> {
+impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
+ fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
From::from(String::from(err))
}
}
#[stable(feature = "cow_box_error", since = "1.22.0")]
-impl<'a> From<Cow<'a, str>> for Box<Error> {
- fn from(err: Cow<'a, str>) -> Box<Error> {
+impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
+ fn from(err: Cow<'a, str>) -> Box<dyn Error> {
From::from(String::from(err))
}
}
Error::description(&**self)
}
- fn cause(&self) -> Option<&Error> {
+ fn cause(&self) -> Option<&dyn Error> {
Error::cause(&**self)
}
}
}
// copied from any.rs
-impl Error + 'static {
+impl dyn Error + 'static {
/// Returns true if the boxed type is the same as `T`
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
if self.is::<T>() {
unsafe {
- Some(&*(self as *const Error as *const T))
+ Some(&*(self as *const dyn Error as *const T))
}
} else {
None
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
unsafe {
- Some(&mut *(self as *mut Error as *mut T))
+ Some(&mut *(self as *mut dyn Error as *mut T))
}
} else {
None
}
}
-impl Error + 'static + Send {
+impl dyn Error + 'static + Send {
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
- <Error + 'static>::is::<T>(self)
+ <dyn Error + 'static>::is::<T>(self)
}
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
- <Error + 'static>::downcast_ref::<T>(self)
+ <dyn Error + 'static>::downcast_ref::<T>(self)
}
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
- <Error + 'static>::downcast_mut::<T>(self)
+ <dyn Error + 'static>::downcast_mut::<T>(self)
}
}
-impl Error + 'static + Send + Sync {
+impl dyn Error + 'static + Send + Sync {
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
- <Error + 'static>::is::<T>(self)
+ <dyn Error + 'static>::is::<T>(self)
}
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
- <Error + 'static>::downcast_ref::<T>(self)
+ <dyn Error + 'static>::downcast_ref::<T>(self)
}
/// Forwards to the method defined on the type `Any`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
- <Error + 'static>::downcast_mut::<T>(self)
+ <dyn Error + 'static>::downcast_mut::<T>(self)
}
}
-impl Error {
+impl dyn Error {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
- pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
+ pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
if self.is::<T>() {
unsafe {
- let raw: *mut Error = Box::into_raw(self);
+ let raw: *mut dyn Error = Box::into_raw(self);
Ok(Box::from_raw(raw as *mut T))
}
} else {
}
}
-impl Error + Send {
+impl dyn Error + Send {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>)
- -> Result<Box<T>, Box<Error + Send>> {
- let err: Box<Error> = self;
- <Error>::downcast(err).map_err(|s| unsafe {
+ -> Result<Box<T>, Box<dyn Error + Send>> {
+ let err: Box<dyn Error> = self;
+ <dyn Error>::downcast(err).map_err(|s| unsafe {
// reapply the Send marker
- transmute::<Box<Error>, Box<Error + Send>>(s)
+ transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
})
}
}
-impl Error + Send + Sync {
+impl dyn Error + Send + Sync {
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
/// Attempt to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>)
-> Result<Box<T>, Box<Self>> {
- let err: Box<Error> = self;
- <Error>::downcast(err).map_err(|s| unsafe {
+ let err: Box<dyn Error> = self;
+ <dyn Error>::downcast(err).map_err(|s| unsafe {
// reapply the Send+Sync marker
- transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
+ transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
})
}
}
#[test]
fn downcasting() {
let mut a = A;
- let a = &mut a as &mut (Error + 'static);
+ let a = &mut a as &mut (dyn Error + 'static);
assert_eq!(a.downcast_ref::<A>(), Some(&A));
assert_eq!(a.downcast_ref::<B>(), None);
assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
assert_eq!(a.downcast_mut::<B>(), None);
- let a: Box<Error> = Box::new(A);
+ let a: Box<dyn Error> = Box::new(A);
match a.downcast::<B>() {
Ok(..) => panic!("expected error"),
Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
"C string contained non-utf8 bytes"
}
- fn cause(&self) -> Option<&Error> {
+ fn cause(&self) -> Option<&dyn Error> {
Some(&self.error)
}
}
#[derive(Debug)]
struct Custom {
kind: ErrorKind,
- error: Box<error::Error+Send+Sync>,
+ error: Box<dyn error::Error+Send+Sync>,
}
/// A list specifying general categories of I/O error.
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<E>(kind: ErrorKind, error: E) -> Error
- where E: Into<Box<error::Error+Send+Sync>>
+ where E: Into<Box<dyn error::Error+Send+Sync>>
{
Self::_new(kind, error.into())
}
- fn _new(kind: ErrorKind, error: Box<error::Error+Send+Sync>) -> Error {
+ fn _new(kind: ErrorKind, error: Box<dyn error::Error+Send+Sync>) -> Error {
Error {
repr: Repr::Custom(Box::new(Custom {
kind,
/// }
/// ```
#[stable(feature = "io_error_inner", since = "1.3.0")]
- pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
+ pub fn get_ref(&self) -> Option<&(dyn error::Error+Send+Sync+'static)> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
/// }
/// ```
#[stable(feature = "io_error_inner", since = "1.3.0")]
- pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
+ pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error+Send+Sync+'static)> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
/// }
/// ```
#[stable(feature = "io_error_inner", since = "1.3.0")]
- pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
+ pub fn into_inner(self) -> Option<Box<dyn error::Error+Send+Sync>> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
}
}
- fn cause(&self) -> Option<&error::Error> {
+ fn cause(&self) -> Option<&dyn error::Error> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
}
}
-fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
+fn read_one_byte(reader: &mut dyn Read) -> Option<Result<u8>> {
let mut buf = [0];
loop {
return match reader.read(&mut buf) {
CharsError::Other(ref e) => std_error::Error::description(e),
}
}
- fn cause(&self) -> Option<&std_error::Error> {
+ fn cause(&self) -> Option<&dyn std_error::Error> {
match *self {
CharsError::NotUtf8 => None,
CharsError::Other(ref e) => e.cause(),
/// Stdout used by print! and println! macros
thread_local! {
- static LOCAL_STDOUT: RefCell<Option<Box<Write + Send>>> = {
+ static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = {
RefCell::new(None)
}
}
with a more general mechanism",
issue = "0")]
#[doc(hidden)]
-pub fn set_panic(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
+pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
use panicking::LOCAL_STDERR;
use mem;
LOCAL_STDERR.with(move |slot| {
with a more general mechanism",
issue = "0")]
#[doc(hidden)]
-pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
+pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
use mem;
LOCAL_STDOUT.with(move |slot| {
mem::replace(&mut *slot.borrow_mut(), sink)
/// However, if the actual I/O causes an error, this function does panic.
fn print_to<T>(
args: fmt::Arguments,
- local_s: &'static LocalKey<RefCell<Option<Box<Write+Send>>>>,
+ local_s: &'static LocalKey<RefCell<Option<Box<dyn Write+Send>>>>,
global_s: fn() -> T,
label: &str,
)
assert_eq!(copy(&mut r, &mut w).unwrap(), 4);
let mut r = repeat(0).take(1 << 17);
- assert_eq!(copy(&mut r as &mut Read, &mut w as &mut Write).unwrap(), 1 << 17);
+ assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17);
}
#[test]
}
// Return result of first successful parser
- fn read_or<T>(&mut self, parsers: &mut [Box<FnMut(&mut Parser) -> Option<T> + 'static>])
+ fn read_or<T>(&mut self, parsers: &mut [Box<dyn FnMut(&mut Parser) -> Option<T> + 'static>])
-> Option<T> {
for pf in parsers {
if let Some(r) = self.read_atomically(|p: &mut Parser| pf(p)) {
use time::{Instant, Duration};
use thread;
- fn each_ip(f: &mut FnMut(SocketAddr)) {
+ fn each_ip(f: &mut dyn FnMut(SocketAddr)) {
f(next_test_ip4());
f(next_test_ip6());
}
use time::{Instant, Duration};
use thread;
- fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) {
+ fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) {
f(next_test_ip4(), next_test_ip4());
f(next_test_ip6(), next_test_ip6());
}
/// }
/// ```
#[stable(feature = "resume_unwind", since = "1.9.0")]
-pub fn resume_unwind(payload: Box<Any + Send>) -> ! {
+pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
panicking::update_count_then_panic(payload)
}
use thread;
thread_local! {
- pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
+ pub static LOCAL_STDERR: RefCell<Option<Box<dyn Write + Send>>> = {
RefCell::new(None)
}
}
#[derive(Copy, Clone)]
enum Hook {
Default,
- Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)),
+ Custom(*mut (dyn Fn(&PanicInfo) + 'static + Sync + Send)),
}
static HOOK_LOCK: RWLock = RWLock::new();
/// panic!("Normal panic");
/// ```
#[stable(feature = "panic_hooks", since = "1.10.0")]
-pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
+pub fn set_hook(hook: Box<dyn Fn(&PanicInfo) + 'static + Sync + Send>) {
if thread::panicking() {
panic!("cannot modify the panic hook from a panicking thread");
}
/// panic!("Normal panic");
/// ```
#[stable(feature = "panic_hooks", since = "1.10.0")]
-pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
+pub fn take_hook() -> Box<dyn Fn(&PanicInfo) + 'static + Sync + Send> {
if thread::panicking() {
panic!("cannot modify the panic hook from a panicking thread");
}
let thread = thread_info::current_thread();
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
- let write = |err: &mut ::io::Write| {
+ let write = |err: &mut dyn (::io::Write)| {
let _ = writeln!(err, "thread '{}' panicked at '{}', {}",
name, msg, location);
pub use realstd::rt::update_panic_count;
/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
-pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
+pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>> {
#[allow(unions_with_drop_fields)]
union Data<F, R> {
f: F,
}
unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
- fn box_me_up(&mut self) -> *mut (Any + Send) {
+ fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
let contents = mem::replace(self.fill(), String::new());
Box::into_raw(Box::new(contents))
}
- fn get(&mut self) -> &(Any + Send) {
+ fn get(&mut self) -> &(dyn Any + Send) {
self.fill()
}
}
}
unsafe impl<A: Send + 'static> BoxMeUp for PanicPayload<A> {
- fn box_me_up(&mut self) -> *mut (Any + Send) {
+ fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
let data = match self.inner.take() {
- Some(a) => Box::new(a) as Box<Any + Send>,
+ Some(a) => Box::new(a) as Box<dyn Any + Send>,
None => Box::new(()),
};
Box::into_raw(data)
}
- fn get(&mut self) -> &(Any + Send) {
+ fn get(&mut self) -> &(dyn Any + Send) {
match self.inner {
Some(ref a) => a,
None => &(),
/// Executes the primary logic for a panic, including checking for recursive
/// panics, panic hooks, and finally dispatching to the panic runtime to either
/// abort or unwind.
-fn rust_panic_with_hook(payload: &mut BoxMeUp,
+fn rust_panic_with_hook(payload: &mut dyn BoxMeUp,
message: Option<&fmt::Arguments>,
file_line_col: &(&str, u32, u32)) -> ! {
let (file, line, col) = *file_line_col;
}
/// Shim around rust_panic. Called by resume_unwind.
-pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! {
+pub fn update_count_then_panic(msg: Box<dyn Any + Send>) -> ! {
update_panic_count(1);
- struct RewrapBox(Box<Any + Send>);
+ struct RewrapBox(Box<dyn Any + Send>);
unsafe impl BoxMeUp for RewrapBox {
- fn box_me_up(&mut self) -> *mut (Any + Send) {
+ fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
Box::into_raw(mem::replace(&mut self.0, Box::new(())))
}
- fn get(&mut self) -> &(Any + Send) {
+ fn get(&mut self) -> &(dyn Any + Send) {
&*self.0
}
}
/// A private no-mangle function on which to slap yer breakpoints.
#[no_mangle]
#[allow(private_no_mangle_fns)] // yes we get it, but we like breakpoints
-pub fn rust_panic(mut msg: &mut BoxMeUp) -> ! {
+pub fn rust_panic(mut msg: &mut dyn BoxMeUp) -> ! {
let code = unsafe {
- let obj = &mut msg as *mut &mut BoxMeUp;
+ let obj = &mut msg as *mut &mut dyn BoxMeUp;
__rust_start_panic(obj as usize)
};
rtabort!("failed to initiate panic, error {}", code)
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let stdout_utf8 = str::from_utf8(&self.stdout);
- let stdout_debug: &fmt::Debug = match stdout_utf8 {
+ let stdout_debug: &dyn fmt::Debug = match stdout_utf8 {
Ok(ref str) => str,
Err(_) => &self.stdout
};
let stderr_utf8 = str::from_utf8(&self.stderr);
- let stderr_debug: &fmt::Debug = match stderr_utf8 {
+ let stderr_debug: &dyn fmt::Debug = match stderr_utf8 {
Ok(ref str) => str,
Err(_) => &self.stderr
};
// To reduce the generated code of the new `lang_start`, this function is doing
// the real work.
#[cfg(not(test))]
-fn lang_start_internal(main: &(Fn() -> i32 + Sync + ::panic::RefUnwindSafe),
+fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + ::panic::RefUnwindSafe),
argc: isize, argv: *const *const u8) -> isize {
use panic;
use sys;
"sending on a closed channel"
}
- fn cause(&self) -> Option<&error::Error> {
+ fn cause(&self) -> Option<&dyn error::Error> {
None
}
}
}
}
- fn cause(&self) -> Option<&error::Error> {
+ fn cause(&self) -> Option<&dyn error::Error> {
None
}
}
"receiving on a closed channel"
}
- fn cause(&self) -> Option<&error::Error> {
+ fn cause(&self) -> Option<&dyn error::Error> {
None
}
}
}
}
- fn cause(&self) -> Option<&error::Error> {
+ fn cause(&self) -> Option<&dyn error::Error> {
None
}
}
}
}
- fn cause(&self) -> Option<&error::Error> {
+ fn cause(&self) -> Option<&dyn error::Error> {
None
}
}
next: *mut Handle<'static, ()>,
prev: *mut Handle<'static, ()>,
added: bool,
- packet: &'rx (Packet+'rx),
+ packet: &'rx (dyn Packet+'rx),
// due to our fun transmutes, we be sure to place this at the end. (nothing
// previous relies on T)
#[cold]
fn call_inner(&self,
ignore_poisoning: bool,
- init: &mut FnMut(bool)) {
+ init: &mut dyn FnMut(bool)) {
let mut state = self.state.load(Ordering::SeqCst);
'outer: loop {
unsafe impl Sync for Thread {}
impl Thread {
- pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>) -> io::Result<Thread> {
+ pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> {
let p = box p;
let mut native: libc::pthread_t = mem::zeroed();
let mut attr: libc::pthread_attr_t = mem::zeroed();
uid: Option<u32>,
gid: Option<u32>,
saw_nul: bool,
- closures: Vec<Box<FnMut() -> io::Result<()> + Send + Sync>>,
+ closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>,
stdin: Option<Stdio>,
stdout: Option<Stdio>,
stderr: Option<Stdio>,
}
pub fn before_exec(&mut self,
- f: Box<FnMut() -> io::Result<()> + Send + Sync>) {
+ f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
self.closures.push(f);
}
unsafe impl Sync for Thread {}
impl Thread {
- pub unsafe fn new<'a>(_stack: usize, p: Box<FnBox() + 'a>) -> io::Result<Thread> {
+ pub unsafe fn new<'a>(_stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> {
let p = box p;
let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?;
uid: Option<uid_t>,
gid: Option<gid_t>,
saw_nul: bool,
- closures: Vec<Box<FnMut() -> io::Result<()> + Send + Sync>>,
+ closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>,
stdin: Option<Stdio>,
stdout: Option<Stdio>,
stderr: Option<Stdio>,
self.gid
}
- pub fn get_closures(&mut self) -> &mut Vec<Box<FnMut() -> io::Result<()> + Send + Sync>> {
+ pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> {
&mut self.closures
}
pub fn before_exec(&mut self,
- f: Box<FnMut() -> io::Result<()> + Send + Sync>) {
+ f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
self.closures.push(f);
}
}
impl Thread {
- pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>)
+ pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
-> io::Result<Thread> {
let p = box p;
let mut native: libc::pthread_t = mem::zeroed();
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
impl Thread {
- pub unsafe fn new<'a>(_stack: usize, _p: Box<FnBox() + 'a>)
+ pub unsafe fn new<'a>(_stack: usize, _p: Box<dyn FnBox() + 'a>)
-> io::Result<Thread>
{
unsupported()
}
impl Thread {
- pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>)
+ pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
-> io::Result<Thread> {
let p = box p;
use mem;
use sys_common::mutex::Mutex;
-type Queue = Vec<Box<FnBox()>>;
+type Queue = Vec<Box<dyn FnBox()>>;
// NB these are specifically not types from `std::sync` as they currently rely
// on poisoning and this module needs to operate at a lower level than requiring
}
}
-pub fn push(f: Box<FnBox()>) -> bool {
+pub fn push(f: Box<dyn FnBox()>) -> bool {
unsafe {
let _guard = LOCK.lock();
if init() {
const MAX_NB_FRAMES: usize = 100;
/// Prints the current backtrace.
-pub fn print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
+pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
static LOCK: Mutex = Mutex::new();
// Use a lock to prevent mixed output in multithreading context.
}
}
-fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
+fn _print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
let mut frames = [Frame {
exact_position: ptr::null(),
symbol_addr: ptr::null(),
///
/// These output functions should now be used everywhere to ensure consistency.
/// You may want to also use `output_fileline`.
-fn output(w: &mut Write, idx: usize, frame: Frame,
+fn output(w: &mut dyn Write, idx: usize, frame: Frame,
s: Option<&str>, format: PrintFormat) -> io::Result<()> {
// Remove the `17: 0x0 - <unknown>` line.
if format == PrintFormat::Short && frame.exact_position == ptr::null() {
///
/// See also `output`.
#[allow(dead_code)]
-fn output_fileline(w: &mut Write,
+fn output_fileline(w: &mut dyn Write,
file: &[u8],
line: u32,
format: PrintFormat) -> io::Result<()> {
// Note that this demangler isn't quite as fancy as it could be. We have lots
// of other information in our symbols like hashes, version, type information,
// etc. Additionally, this doesn't handle glue symbols at all.
-pub fn demangle(writer: &mut Write, mut s: &str, format: PrintFormat) -> io::Result<()> {
+pub fn demangle(writer: &mut dyn Write, mut s: &str, format: PrintFormat) -> io::Result<()> {
// During ThinLTO LLVM may import and rename internal symbols, so strip out
// those endings first as they're one of the last manglings applied to
// symbol names.
}
}
- fn cause(&self) -> Option<&Error> {
+ fn cause(&self) -> Option<&dyn Error> {
match *self {
TryLockError::Poisoned(ref p) => Some(p),
_ => None
let _handler = stack_overflow::Handler::new();
// Finally, let's run some code.
- Box::from_raw(main as *mut Box<FnBox()>)()
+ Box::from_raw(main as *mut Box<dyn FnBox()>)()
}
pub fn min_stack() -> usize {
///
/// [`Result`]: ../../std/result/enum.Result.html
#[stable(feature = "rust1", since = "1.0.0")]
-pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
+pub type Result<T> = ::result::Result<T, Box<dyn Any + Send + 'static>>;
// This packet is used to communicate the return value between the child thread
// and the parent thread. Memory is shared through the `Arc` within and there's
#[stable(feature = "rust1", since = "1.0.0")]
pub struct JoinHandle<T>(JoinInner<T>);
+#[stable(feature = "joinhandle_impl_send_sync", since = "1.29.0")]
+unsafe impl<T> Send for JoinHandle<T> {}
+#[stable(feature = "joinhandle_impl_send_sync", since = "1.29.0")]
+unsafe impl<T> Sync for JoinHandle<T> {}
+
impl<T> JoinHandle<T> {
/// Extracts a handle to the underlying thread.
///
rx.recv().unwrap();
}
- fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Box<Fn() + Send>) {
+ fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Box<dyn Fn() + Send>) {
let (tx, rx) = channel();
let x: Box<_> = box 1;
// (well, it would if the constant were 8000+ - I lowered it to be more
// valgrind-friendly. try this at home, instead..!)
const GENERATIONS: u32 = 16;
- fn child_no(x: u32) -> Box<Fn() + Send> {
+ fn child_no(x: u32) -> Box<dyn Fn() + Send> {
return Box::new(move|| {
if x < GENERATIONS {
thread::spawn(move|| child_no(x+1)());
#[test]
fn test_try_panic_message_any() {
match thread::spawn(move|| {
- panic!(box 413u16 as Box<Any + Send>);
+ panic!(box 413u16 as Box<dyn Any + Send>);
}).join() {
Err(e) => {
- type T = Box<Any + Send>;
+ type T = Box<dyn Any + Send>;
assert!(e.is::<T>());
let any = e.downcast::<T>().unwrap();
assert!(any.is::<u16>());
//!
//! This API is completely unstable and subject to change.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/",
})
}
+ fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
+ let error_msg = "crate name using dashes are not valid in `extern crate` statements";
+ let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
+ in the code";
+ let mut ident = self.parse_ident()?;
+ let mut idents = vec![];
+ let mut replacement = vec![];
+ let mut fixed_crate_name = false;
+ // Accept `extern crate name-like-this` for better diagnostics
+ let dash = token::Token::BinOp(token::BinOpToken::Minus);
+ if self.token == dash { // Do not include `-` as part of the expected tokens list
+ while self.eat(&dash) {
+ fixed_crate_name = true;
+ replacement.push((self.prev_span, "_".to_string()));
+ idents.push(self.parse_ident()?);
+ }
+ }
+ if fixed_crate_name {
+ let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
+ let mut fixed_name = format!("{}", ident.name);
+ for part in idents {
+ fixed_name.push_str(&format!("_{}", part.name));
+ }
+ ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp);
+
+ let mut err = self.struct_span_err(fixed_name_sp, error_msg);
+ err.span_label(fixed_name_sp, "dash-separated idents are not valid");
+ err.multipart_suggestion(suggestion_msg, replacement);
+ err.emit();
+ }
+ Ok(ident)
+ }
+
/// Parse extern crate links
///
/// # Examples
visibility: Visibility,
attrs: Vec<Attribute>)
-> PResult<'a, P<Item>> {
- let orig_name = self.parse_ident()?;
+ // Accept `extern crate name-like-this` for better diagnostics
+ let orig_name = self.parse_crate_name_with_dashes()?;
let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
(rename, Some(orig_name.name))
} else {
//! Syntax extensions in the Rust compiler.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
//!
//! This API is completely unstable and subject to change.
-#![deny(bare_trait_objects)]
-
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
/// `SpanLabel` instances with empty labels.
pub fn span_labels(&self) -> Vec<SpanLabel> {
let is_primary = |span| self.primary_spans.contains(&span);
- let mut span_labels = vec![];
- for &(span, ref label) in &self.span_labels {
- span_labels.push(SpanLabel {
+ let mut span_labels = self.span_labels.iter().map(|&(span, ref label)|
+ SpanLabel {
span,
is_primary: is_primary(span),
label: Some(label.clone())
- });
- }
+ }
+ ).collect::<Vec<_>>();
for &span in &self.primary_spans {
if !span_labels.iter().any(|sl| sl.span == span) {
mod win;
/// Alias for stdout terminals.
-pub type StdoutTerminal = Terminal<Output = Stdout> + Send;
+pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
/// Alias for stderr terminals.
-pub type StderrTerminal = Terminal<Output = Stderr> + Send;
+pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
#[cfg(not(windows))]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
"failed to create TermInfo"
}
- fn cause(&self) -> Option<&error::Error> {
+ fn cause(&self) -> Option<&dyn error::Error> {
use self::Error::*;
match self {
&IoError(ref e) => Some(e),
"OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
"box1"];
-fn read_le_u16(r: &mut io::Read) -> io::Result<u16> {
+fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
let mut b = [0; 2];
let mut amt = 0;
while amt < b.len() {
Ok((b[0] as u16) | ((b[1] as u16) << 8))
}
-fn read_byte(r: &mut io::Read) -> io::Result<u8> {
+fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
match r.bytes().next() {
Some(s) => s,
None => Err(io::Error::new(io::ErrorKind::Other, "end of file")),
/// Parse a compiled terminfo entry, using long capability names if `longnames`
/// is true
-pub fn parse(file: &mut io::Read, longnames: bool) -> Result<TermInfo, String> {
+pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
macro_rules! t( ($e:expr) => (
match $e {
Ok(e) => e,
// this crate, which relies on this attribute (rather than the value of `--crate-name` passed by
// cargo) to detect this crate.
-#![deny(bare_trait_objects)]
-
#![crate_name = "test"]
#![unstable(feature = "test", issue = "27812")]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(bare_trait_objects)]
-
#![no_std]
#![unstable(feature = "panic_unwind", issue = "32837")]
# source tarball for a stable release you'll likely see `1.x.0` for rustc and
# `0.x.0` for Cargo where they were released on `date`.
-date: 2018-07-13
+date: 2018-07-27
rustc: beta
cargo: beta
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate krate-name-here;
+//~^ ERROR crate name using dashes are not valid in `extern crate` statements
+//~| ERROR can't find crate for `krate_name_here`
+
+fn main() {}
--- /dev/null
+error: crate name using dashes are not valid in `extern crate` statements
+ --> $DIR/bad-crate-name.rs:11:14
+ |
+LL | extern crate krate-name-here;
+ | ^^^^^^^^^^^^^^^ dash-separated idents are not valid
+help: if the original crate name uses dashes you need to use underscores in the code
+ |
+LL | extern crate krate_name_here;
+ | ^ ^
+
+error[E0463]: can't find crate for `krate_name_here`
+ --> $DIR/bad-crate-name.rs:11:1
+ |
+LL | extern crate krate-name-here;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0463`.
--- /dev/null
+error[E0507]: cannot move out of borrowed content
+ --> $DIR/borrowck-feature-nll-overrides-migrate.rs:32:17
+ |
+LL | (|| { let bar = foo; bar.take() })();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
--- /dev/null
+// Copyright 2017 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This is a test that the `#![feature(nll)]` opt-in overrides the
+// migration mode. The intention here is to emulate the goal behavior
+// that `--edition 2018` effects on borrowck (modeled here by `-Z
+// borrowck=migrate`) are themselves overridden by the
+// `#![feature(nll)]` opt-in.
+//
+// Therefore, for developer convenience, under `#[feature(nll)]` the
+// NLL checks will be emitted as errors *even* in the presence of `-Z
+// borrowck=migrate`.
+
+// revisions: zflag edition
+// [zflag]compile-flags: -Z borrowck=migrate
+// [edition]compile-flags: --edition 2018
+
+#![feature(nll)]
+
+fn main() {
+ match Some(&4) {
+ None => {},
+ ref mut foo
+ if {
+ (|| { let bar = foo; bar.take() })();
+ //[zflag]~^ ERROR cannot move out of borrowed content [E0507]
+ //[edition]~^^ ERROR cannot move out of borrowed content [E0507]
+ false
+ } => {},
+ Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
+ _ => println!("Here is some supposedly unreachable code."),
+ }
+}
--- /dev/null
+error[E0507]: cannot move out of borrowed content
+ --> $DIR/borrowck-feature-nll-overrides-migrate.rs:32:17
+ |
+LL | (|| { let bar = foo; bar.take() })();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
--- /dev/null
+warning[E0507]: cannot move out of borrowed content
+ --> $DIR/borrowck-migrate-to-nll.rs:35:17
+ |
+LL | (|| { let bar = foo; bar.take() })();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+ |
+ = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+ It represents potential unsoundness in your code.
+ This warning will become a hard error in the future.
+
+warning[E0507]: cannot move out of `foo`, as it is immutable for the pattern guard
+ --> $DIR/borrowck-migrate-to-nll.rs:35:17
+ |
+LL | (|| { let bar = foo; bar.take() })();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | cannot move out of `foo`, as it is immutable for the pattern guard
+ | cannot move
+ |
+ = note: variables bound in patterns are immutable until the end of the pattern guard
+ = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+ It represents potential unsoundness in your code.
+ This warning will become a hard error in the future.
+
--- /dev/null
+// Copyright 2017 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This is a test of the borrowck migrate mode. It leverages #27282, a
+// bug that is fixed by NLL: this code is (unsoundly) accepted by
+// AST-borrowck, but is correctly rejected by the NLL borrowck.
+//
+// Therefore, for backwards-compatiblity, under borrowck=migrate the
+// NLL checks will be emitted as *warnings*.
+
+// NLL mode makes this compile-fail; we cannot currently encode a
+// test that is run-pass or compile-fail based on compare-mode. So
+// just ignore it instead:
+
+// ignore-compare-mode-nll
+
+// revisions: zflag edition
+//[zflag]compile-flags: -Z borrowck=migrate
+//[edition]compile-flags: --edition 2018
+//[zflag] run-pass
+//[edition] run-pass
+
+fn main() {
+ match Some(&4) {
+ None => {},
+ ref mut foo
+ if {
+ (|| { let bar = foo; bar.take() })();
+ false
+ } => {},
+ Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
+ _ => println!("Here is some supposedly unreachable code."),
+ }
+}
--- /dev/null
+warning[E0507]: cannot move out of borrowed content
+ --> $DIR/borrowck-migrate-to-nll.rs:35:17
+ |
+LL | (|| { let bar = foo; bar.take() })();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+ |
+ = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+ It represents potential unsoundness in your code.
+ This warning will become a hard error in the future.
+
+warning[E0507]: cannot move out of `foo`, as it is immutable for the pattern guard
+ --> $DIR/borrowck-migrate-to-nll.rs:35:17
+ |
+LL | (|| { let bar = foo; bar.take() })();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | cannot move out of `foo`, as it is immutable for the pattern guard
+ | cannot move
+ |
+ = note: variables bound in patterns are immutable until the end of the pattern guard
+ = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+ It represents potential unsoundness in your code.
+ This warning will become a hard error in the future.
+
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// We used to ICE if you had a single match arm with multiple
+// candidate patterns with `ref mut` identifiers used in the arm's
+// guard.
+//
+// Also, this test expands on the original bug's example by actually
+// trying to double check that we are matching against the right part
+// of the input data based on which candidate pattern actually fired.
+
+// run-pass
+
+#![feature(nll)]
+
+fn foo(x: &mut Result<(u32, u32), (u32, u32)>) -> u32 {
+ match *x {
+ Ok((ref mut v, _)) | Err((_, ref mut v)) if *v > 0 => { *v }
+ _ => { 0 }
+ }
+}
+
+fn main() {
+ assert_eq!(foo(&mut Ok((3, 4))), 3);
+ assert_eq!(foo(&mut Err((3, 4))), 4);
+}
LL | invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495
| ----------^^^^^-----------------
| | | |
- | | | free region requires that `'1` must outlive `'2`
- | | lifetime `'1` appears in this argument
+ | | | requires that `'1` must outlive `'2`
+ | | has type `&'1 i32`
| lifetime `'2` appears in return type
error: aborting due to previous error
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// compile-flags: -Z borrowck=compare
-
#![feature(generators)]
#![feature(nll)]
fn main() {
|| {
// The reference in `_a` is a Legal with NLL since it ends before the yield
- let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
- let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
- //~^ borrow may still be in use when generator yields (Mir)
+ let _a = &mut true;
+ let b = &mut true;
+ //~^ borrow may still be in use when generator yields
yield ();
println!("{}", b);
};
-error[E0626]: borrow may still be in use when generator yields (Ast)
- --> $DIR/generator-with-nll.rs:19:23
+error[E0626]: borrow may still be in use when generator yields
+ --> $DIR/generator-with-nll.rs:18:17
|
-LL | let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
- | ^^^^
-...
-LL | yield ();
- | -------- possible yield occurs here
-
-error[E0626]: borrow may still be in use when generator yields (Ast)
- --> $DIR/generator-with-nll.rs:20:22
- |
-LL | let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
- | ^^^^
-LL | //~^ borrow may still be in use when generator yields (Mir)
-LL | yield ();
- | -------- possible yield occurs here
-
-error[E0626]: borrow may still be in use when generator yields (Mir)
- --> $DIR/generator-with-nll.rs:20:17
- |
-LL | let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
+LL | let b = &mut true;
| ^^^^^^^^^
-LL | //~^ borrow may still be in use when generator yields (Mir)
+LL | //~^ borrow may still be in use when generator yields
LL | yield ();
| -------- possible yield occurs here
-error: aborting due to 3 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0626`.
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(existential_type)]
+// compile-pass
+
+trait Bar {}
+struct Dummy<U>(U);
+impl<V> Bar for Dummy<V> {}
+
+trait Foo<T> {
+ type Assoc: Bar;
+ fn foo(t: T) -> Self::Assoc;
+}
+
+impl<W> Foo<W> for i32 {
+ existential type Assoc: Bar;
+ fn foo(w: W) -> Self::Assoc {
+ Dummy(w)
+ }
+}
+
+struct NonGeneric;
+impl Bar for NonGeneric {}
+
+impl<W> Foo<W> for u32 {
+ existential type Assoc: Bar;
+ fn foo(_: W) -> Self::Assoc {
+ NonGeneric
+ }
+}
+
+fn main() {}
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(existential_type)]
+// compile-pass
+
+trait Bar {}
+struct Dummy;
+impl Bar for Dummy {}
+
+trait Foo {
+ type Assoc: Bar;
+ fn foo() -> Self::Assoc;
+}
+
+impl Foo for i32 {
+ existential type Assoc: Bar;
+ fn foo() -> Self::Assoc {
+ Dummy
+ }
+}
+
+fn main() {}
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(existential_type)]
+// compile-pass
+
+trait Bar {}
+struct Dummy;
+impl Bar for Dummy {}
+
+trait Foo {
+ type Assoc: Bar;
+ fn foo() -> Self::Assoc;
+ fn bar() -> Self::Assoc;
+}
+
+impl Foo for i32 {
+ existential type Assoc: Bar;
+ fn foo() -> Self::Assoc {
+ Dummy
+ }
+ fn bar() -> Self::Assoc {
+ Dummy
+ }
+}
+
+fn main() {}
LL | self.x.iter().map(|a| a.0)
| ^^^^
-error: borrowed data escapes outside of closure
+error: unsatisfied lifetime constraints
--> $DIR/static-return-lifetime-infered.rs:17:9
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
- | ----- `self` is a reference that is only valid in the closure body
+ | - let's call the lifetime of this reference `'1`
LL | self.x.iter().map(|a| a.0)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here
+ | ^^^^^^^^^^^^^ requires that `'1` must outlive `'static`
-error: borrowed data escapes outside of closure
+error: unsatisfied lifetime constraints
--> $DIR/static-return-lifetime-infered.rs:21:9
|
-LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
- | -------- `self` is a reference that is only valid in the closure body
LL | self.x.iter().map(|a| a.0)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here
+ | ^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: aborting due to 2 previous errors
LL | static_val(x); //~ ERROR cannot infer
| ^
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
--> $DIR/dyn-trait.rs:32:5
|
LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
- | - `x` is a reference that is only valid in the closure body
+ | - `x` is a reference that is only valid in the function body
LL | static_val(x); //~ ERROR cannot infer
- | ^^^^^^^^^^^^^ `x` escapes the closure body here
+ | ^^^^^^^^^^^^^ `x` escapes the function body here
error: aborting due to previous error
--> $DIR/issue-10291.rs:12:5
|
LL | drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ free region requires that `'x` must outlive `'static`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
error: aborting due to previous error
|
= note: expected type `fn(&mut Baz, &mut dyn Foo)`
found type `fn(&mut Baz, &dyn Foo)`
+help: consider change the type to match the mutability in trait
+ |
+LL | fn bar(&mut self, other: &mut Foo) {}
+ | ^^^^^^^^
error: aborting due to previous error
LL | self.a(); //~ ERROR cannot infer
| ^
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
--> $DIR/issue-16683.rs:14:9
|
LL | fn b(&self) {
- | ----- `self` is a reference that is only valid in the closure body
+ | ----- `self` is a reference that is only valid in the function body
LL | self.a(); //~ ERROR cannot infer
- | ^^^^^^^^ `self` escapes the closure body here
+ | ^^^^^^^^ `self` escapes the function body here
error: aborting due to previous error
LL | self.foo();
| ^^^
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
--> $DIR/issue-17758.rs:17:9
|
LL | fn bar(&self) {
- | ----- `self` is a reference that is only valid in the closure body
+ | ----- `self` is a reference that is only valid in the function body
LL | self.foo();
- | ^^^^^^^^^^ `self` escapes the closure body here
+ | ^^^^^^^^^^ `self` escapes the function body here
error: aborting due to previous error
| |_____|
| ||
LL | || &mut x
- | || ^^^^^^ free region requires that `'1` must outlive `'2`
+ | || ^^^^^^ return requires that `'1` must outlive `'2`
LL | || };
| || -
| ||_____|
| ||_________^
LL | ||| x.push(())
LL | ||| }
- | |||_________^ free region requires that `'1` must outlive `'2`
+ | |||_________^ requires that `'1` must outlive `'2`
LL | || };
| || -
| ||_____|
--> $DIR/issue-52213.rs:13:11
|
LL | ((u,),) => u,
- | ^ free region requires that `'a` must outlive `'b`
+ | ^ requires that `'a` must outlive `'b`
error: aborting due to previous error
--- /dev/null
+warning: not reporting region error due to nll
+ --> $DIR/issue-52533-1.rs:19:18
+ |
+LL | gimme(|x, y| y)
+ | ^
+
+error: unsatisfied lifetime constraints
+ --> $DIR/issue-52533-1.rs:19:18
+ |
+LL | gimme(|x, y| y)
+ | - - ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`
+ | | |
+ | | has type `&Foo<'_, '1, u32>`
+ | has type `&Foo<'_, '2, u32>`
+
+error: aborting due to previous error
+
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(warnings)]
+
+struct Foo<'a, 'b, T: 'a + 'b> { x: &'a T, y: &'b T }
+
+fn gimme(_: impl for<'a, 'b, 'c> FnOnce(&'a Foo<'a, 'b, u32>,
+ &'a Foo<'a, 'c, u32>) -> &'a Foo<'a, 'b, u32>) { }
+
+fn main() {
+ gimme(|x, y| y)
+ //~^ ERROR mismatched types [E0308]
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-52533-1.rs:19:18
+ |
+LL | gimme(|x, y| y)
+ | ^ lifetime mismatch
+ |
+ = note: expected type `&Foo<'_, '_, u32>`
+ found type `&Foo<'_, '_, u32>`
+note: the anonymous lifetime #4 defined on the body at 19:11...
+ --> $DIR/issue-52533-1.rs:19:11
+ |
+LL | gimme(|x, y| y)
+ | ^^^^^^^^
+note: ...does not necessarily outlive the anonymous lifetime #3 defined on the body at 19:11
+ --> $DIR/issue-52533-1.rs:19:11
+ |
+LL | gimme(|x, y| y)
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+warning: not reporting region error due to nll
+ --> $DIR/issue-52533.rs:15:16
+ |
+LL | foo(|a, b| b)
+ | ^
+
+error: unsatisfied lifetime constraints
+ --> $DIR/issue-52533.rs:15:16
+ |
+LL | foo(|a, b| b)
+ | - - ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`
+ | | |
+ | | has type `&'1 u32`
+ | has type `&'2 u32`
+
+error: aborting due to previous error
+
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo(_: impl for<'a> FnOnce(&'a u32, &u32) -> &'a u32) {
+}
+
+fn main() {
+ foo(|a, b| b)
+ //~^ ERROR lifetime of reference outlives lifetime of borrowed content...
+}
--- /dev/null
+error[E0312]: lifetime of reference outlives lifetime of borrowed content...
+ --> $DIR/issue-52533.rs:15:16
+ |
+LL | foo(|a, b| b)
+ | ^
+ |
+note: ...the reference is valid for the anonymous lifetime #2 defined on the body at 15:9...
+ --> $DIR/issue-52533.rs:15:9
+ |
+LL | foo(|a, b| b)
+ | ^^^^^^^^
+note: ...but the borrowed content is only valid for the anonymous lifetime #3 defined on the body at 15:9
+ --> $DIR/issue-52533.rs:15:9
+ |
+LL | foo(|a, b| b)
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0312`.
|
= note: expected type `fn(&Bar)`
found type `fn(&mut Bar)`
+help: consider change the type to match the mutability in trait
+ |
+LL | fn bar(&self) { }
+ | ^^^^^
error: aborting due to 2 previous errors
|
= note: expected type `fn(&mut Bar, &mut Bar)`
found type `fn(&mut Bar, &Bar)`
+help: consider change the type to match the mutability in trait
+ |
+LL | fn bar(&mut self, bar: &mut Bar) { } //~ ERROR incompatible type
+ | ^^^^^^^^
error: aborting due to 2 previous errors
--> $DIR/escape-argument-callee.rs:36:45
|
LL | let mut closure = expect_sig(|p, y| *p = y);
- | - - ^^^^^^ free region requires that `'1` must outlive `'2`
+ | - - ^^^^^^ requires that `'1` must outlive `'2`
| | |
- | | lifetime `'1` appears in this argument
- | lifetime `'2` appears in this argument
+ | | has type `&'1 i32`
+ | has type `&mut &'2 i32`
note: No external requirements
--> $DIR/escape-argument-callee.rs:36:38
--> $DIR/propagate-approximated-fail-no-postdom.rs:57:13
|
LL | |_outlives1, _outlives2, _outlives3, x, y| {
- | ---------- ---------- lifetime `'2` appears in this argument
+ | ---------- ---------- has type `std::cell::Cell<&'2 &u32>`
| |
- | lifetime `'1` appears in this argument
+ | has type `std::cell::Cell<&&'1 u32>`
...
LL | demand_y(x, y, p) //~ ERROR
| ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
= note: number of external vids: 2
= note: where '_#1r: '_#0r
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
--> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5
|
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
- | ------ `cell_a` is a reference that is only valid in the closure body
+ | ------ `cell_a` is a reference that is only valid in the function body
LL | / establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
LL | | //~^ ERROR
LL | |
LL | | // Only works if 'x: 'y:
LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
LL | | });
- | |______^ `cell_a` escapes the closure body here
+ | |______^ `cell_a` escapes the function body here
note: No external requirements
--> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1
= note: number of external vids: 3
= note: where '_#1r: '_#0r
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
--> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5
|
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
- | ------ `cell_a` is a reference that is only valid in the closure body
+ | ------ `cell_a` is a reference that is only valid in the function body
LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
LL | | //~^ ERROR
LL | | // Only works if 'x: 'y:
LL | | demand_y(x, y, x.get())
LL | | //~^ WARNING not reporting region error due to nll
LL | | });
- | |______^ `cell_a` escapes the closure body here
+ | |______^ `cell_a` escapes the function body here
note: No external requirements
--> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
|
LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
- | --------- - lifetime `'1` appears in this argument
+ | --------- - has type `&std::cell::Cell<&'1 u32>`
| |
- | lifetime `'2` appears in this argument
+ | has type `&std::cell::Cell<&'2 &u32>`
LL | // Only works if 'x: 'y:
LL | demand_y(x, y, x.get())
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
|
LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
- | ---------- ---------- lifetime `'2` appears in this argument
+ | ---------- ---------- has type `&std::cell::Cell<&'2 &u32>`
| |
- | lifetime `'1` appears in this argument
+ | has type `&std::cell::Cell<&'1 &u32>`
LL | // Only works if 'x: 'y:
LL | demand_y(x, y, x.get())
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
--> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5
|
LL | &*x
- | ^^^ free region requires that `'a` must outlive `'static`
+ | ^^^ requires that `'a` must outlive `'static`
error: aborting due to previous error
--> $DIR/return-wrong-bound-region.rs:21:23
|
LL | expect_sig(|a, b| b); // ought to return `a`
- | - - ^ free region requires that `'1` must outlive `'2`
+ | - - ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`
| | |
- | | lifetime `'1` appears in this argument
- | lifetime `'2` appears in this argument
+ | | has type `&'1 i32`
+ | has type `&'2 i32`
note: No external requirements
--> $DIR/return-wrong-bound-region.rs:21:16
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
--> $DIR/issue-50716.rs:25:14
|
LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
- | - `s` is a reference that is only valid in the closure body
+ | - `s` is a reference that is only valid in the function body
...
LL | let _x = *s; //~ ERROR
- | ^^ `s` escapes the closure body here
+ | ^^ `s` escapes the function body here
error: aborting due to previous error
LL | let f: fn(_) -> _ = foo;
| ^^^
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
--> $DIR/mir_check_cast_reify.rs:48:5
|
LL | fn bar<'a>(x: &'a u32) -> &'static u32 {
- | - `x` is a reference that is only valid in the closure body
+ | - `x` is a reference that is only valid in the function body
...
LL | f(x)
- | ^^^^ `x` escapes the closure body here
+ | ^^^^ `x` escapes the function body here
error: aborting due to previous error
LL | let g: unsafe fn(_) -> _ = f;
| ^
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
--> $DIR/mir_check_cast_unsafe_fn.rs:20:14
|
LL | fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
- | ----- `input` is a reference that is only valid in the closure body
+ | ----- `input` is a reference that is only valid in the function body
...
LL | unsafe { g(input) }
- | ^^^^^^^^ `input` escapes the closure body here
+ | ^^^^^^^^ `input` escapes the function body here
error: aborting due to previous error
static TARGETS: &'static [&'static str] = &[
"aarch64-apple-ios",
+ "aarch64-fuchsia",
"aarch64-linux-android",
"aarch64-unknown-cloudabi",
- "aarch64-unknown-fuchsia",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"arm-linux-androideabi",
"wasm32-unknown-unknown",
"x86_64-apple-darwin",
"x86_64-apple-ios",
+ "x86_64-fuchsia",
"x86_64-linux-android",
"x86_64-pc-windows-gnu",
"x86_64-pc-windows-msvc",
"x86_64-sun-solaris",
"x86_64-unknown-cloudabi",
"x86_64-unknown-freebsd",
- "x86_64-unknown-fuchsia",
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-gnux32",
"x86_64-unknown-linux-musl",
use std::io::BufReader;
use std::path::{Path, PathBuf};
-use common::{self, Config, Mode};
+use common::{self, CompareMode, Config, Mode};
use util;
use extract_gdb_version;
}
}
-fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut FnMut(&str)) {
+fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
if testfile.is_dir() {
return;
}
common::DebugInfoLldb => name == "lldb",
common::Pretty => name == "pretty",
_ => false,
- } || (self.target != self.host && name == "cross-compile")
+ } || (self.target != self.host && name == "cross-compile") ||
+ match self.compare_mode {
+ Some(CompareMode::Nll) => name == "compare-mode-nll",
+ Some(CompareMode::Polonius) => name == "compare-mode-polonius",
+ None => false,
+ }
} else {
false
}
pub fn read2(
out_pipe: ChildStdout,
err_pipe: ChildStderr,
- data: &mut FnMut(bool, &mut Vec<u8>, bool),
+ data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
) -> io::Result<()> {
let mut buffer = Vec::new();
out_pipe.read_to_end(&mut buffer)?;
pub fn read2(
mut out_pipe: ChildStdout,
mut err_pipe: ChildStderr,
- data: &mut FnMut(bool, &mut Vec<u8>, bool),
+ data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
) -> io::Result<()> {
unsafe {
libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
pub fn read2(
out_pipe: ChildStdout,
err_pipe: ChildStderr,
- data: &mut FnMut(bool, &mut Vec<u8>, bool),
+ data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
) -> io::Result<()> {
let mut out = Vec::new();
let mut err = Vec::new();
}
trait Formatter {
- fn header(&self, output: &mut Write) -> Result<(), Box<Error>>;
- fn title(&self, output: &mut Write) -> Result<(), Box<Error>>;
- fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
- err_code: &str) -> Result<(), Box<Error>>;
- fn footer(&self, output: &mut Write) -> Result<(), Box<Error>>;
+ fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
+ fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
+ fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata,
+ err_code: &str) -> Result<(), Box<dyn Error>>;
+ fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
}
struct HTMLFormatter;
struct MarkdownFormatter;
impl Formatter for HTMLFormatter {
- fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
+ fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
write!(output, r##"<!DOCTYPE html>
<html>
<head>
Ok(())
}
- fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
+ fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
write!(output, "<h1>Rust Compiler Error Index</h1>\n")?;
Ok(())
}
- fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
- err_code: &str) -> Result<(), Box<Error>> {
+ fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata,
+ err_code: &str) -> Result<(), Box<dyn Error>> {
// Enclose each error in a div so they can be shown/hidden en masse.
let desc_desc = match info.description {
Some(_) => "error-described",
Ok(())
}
- fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
+ fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
write!(output, r##"<script>
function onEach(arr, func) {{
if (arr && arr.length > 0 && func) {{
impl Formatter for MarkdownFormatter {
#[allow(unused_variables)]
- fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
+ fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
Ok(())
}
- fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
+ fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
write!(output, "# Rust Compiler Error Index\n")?;
Ok(())
}
- fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
- err_code: &str) -> Result<(), Box<Error>> {
+ fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata,
+ err_code: &str) -> Result<(), Box<dyn Error>> {
Ok(match info.description {
Some(ref desc) => write!(output, "## {}\n{}\n", err_code, desc)?,
None => (),
}
#[allow(unused_variables)]
- fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
+ fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
Ok(())
}
}
/// Load all the metadata files from `metadata_dir` into an in-memory map.
-fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
+fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<dyn Error>> {
let mut all_errors = BTreeMap::new();
for entry in read_dir(metadata_dir)? {
/// Output an HTML page for the errors in `err_map` to `output_path`.
fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
- formatter: T) -> Result<(), Box<Error>> {
+ formatter: T) -> Result<(), Box<dyn Error>> {
let mut output_file = File::create(output_path)?;
formatter.header(&mut output_file)?;
formatter.footer(&mut output_file)
}
-fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<Error>> {
+fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> {
let build_arch = env::var("CFG_BUILD")?;
let metadata_dir = get_metadata_dir(&build_arch);
let err_map = load_all_errors(&metadata_dir)?;
_ => panic!("cannot start emulator for: {}"< target),
}
- fn add_files(w: &mut Write, root: &Path, cur: &Path) {
+ fn add_files(w: &mut dyn Write, root: &Path, cur: &Path) {
for entry in t!(cur.read_dir()) {
let entry = t!(entry);
let path = entry.path();
}
}
-fn send(path: &Path, dst: &mut Write) {
+fn send(path: &Path, dst: &mut dyn Write) {
t!(dst.write_all(path.file_name().unwrap().to_str().unwrap().as_bytes()));
t!(dst.write_all(&[0]));
let mut file = t!(File::open(&path));
return dst
}
-fn my_copy(src: &mut Read, which: u8, dst: &Mutex<Write>) {
+fn my_copy(src: &mut dyn Read, which: u8, dst: &Mutex<dyn Write>) {
let mut b = [0; 1024];
loop {
let n = t!(src.read(&mut b));
}
}
-fn read_u32(r: &mut Read) -> u32 {
+fn read_u32(r: &mut dyn Read) -> u32 {
let mut len = [0; 4];
t!(r.read_exact(&mut len));
((len[0] as u32) << 24) |
}
fn map_lib_features(base_src_path: &Path,
- mf: &mut FnMut(Result<(&str, Feature), &str>, &Path, usize)) {
+ mf: &mut dyn FnMut(Result<(&str, Feature), &str>, &Path, usize)) {
let mut contents = String::new();
super::walk(base_src_path,
&mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
skip.iter().any(|p| path.ends_with(p))
}
-fn walk_many(paths: &[&Path], skip: &mut FnMut(&Path) -> bool, f: &mut FnMut(&Path)) {
+fn walk_many(paths: &[&Path], skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) {
for path in paths {
walk(path, skip, f);
}
}
-fn walk(path: &Path, skip: &mut FnMut(&Path) -> bool, f: &mut FnMut(&Path)) {
+fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) {
for entry in t!(fs::read_dir(path), path) {
let entry = t!(entry);
let kind = t!(entry.file_type());