From 9292c0bc91a9165a2dc7baa4d154079ad0a5f5c9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 17 Jul 2016 00:15:15 +0300 Subject: [PATCH 01/21] Properly feature gate all unstable ABIs --- src/doc/book/closures.md | 1 + src/libsyntax/feature_gate.rs | 73 +++++++++++-------- src/test/compile-fail/E0045.rs | 2 +- .../feature-gate-abi-vectorcall.rs | 19 ----- src/test/compile-fail/feature-gate-abi.rs | 60 +++++++++++++++ .../compile-fail/feature-gate-rust-call.rs | 21 ------ 6 files changed, 103 insertions(+), 73 deletions(-) delete mode 100644 src/test/compile-fail/feature-gate-abi-vectorcall.rs create mode 100644 src/test/compile-fail/feature-gate-abi.rs delete mode 100644 src/test/compile-fail/feature-gate-rust-call.rs diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index 666d0946ecc80..defa63b916928 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -223,6 +223,7 @@ trait system to overload operators. Calling functions is no different. We have three separate traits to overload with: ```rust +# #![feature(unboxed_closures)] # mod foo { pub trait Fn : FnMut { extern "rust-call" fn call(&self, args: Args) -> Self::Output; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 27485ee65fcc0..2b79a7012e31f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -800,6 +800,29 @@ macro_rules! gate_feature_post { }} } +impl<'a> PostExpansionVisitor<'a> { + fn check_abi(&self, abi: Abi, span: Span) { + match abi { + Abi::RustIntrinsic => + gate_feature_post!(&self, intrinsics, span, + "intrinsics are subject to change"), + Abi::PlatformIntrinsic => { + gate_feature_post!(&self, platform_intrinsics, span, + "platform intrinsics are experimental and possibly buggy") + }, + Abi::Vectorcall => { + gate_feature_post!(&self, abi_vectorcall, span, + "vectorcall is experimental and subject to change") + } + Abi::RustCall => { + gate_feature_post!(&self, unboxed_closures, span, + "rust-call ABI is subject to change"); + } + _ => {} + } + } +} + impl<'a> Visitor for PostExpansionVisitor<'a> { fn visit_attribute(&mut self, attr: &ast::Attribute) { if !self.context.cm.span_allows_unstable(attr.span) { @@ -831,21 +854,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { across platforms, it is recommended to \ use `#[link(name = \"foo\")]` instead") } - match foreign_module.abi { - Abi::RustIntrinsic => - gate_feature_post!(&self, intrinsics, i.span, - "intrinsics are subject to change"), - Abi::PlatformIntrinsic => { - gate_feature_post!(&self, platform_intrinsics, i.span, - "platform intrinsics are experimental \ - and possibly buggy") - }, - Abi::Vectorcall => { - gate_feature_post!(&self, abi_vectorcall, i.span, - "vectorcall is experimental and subject to change") - } - _ => () - } + self.check_abi(foreign_module.abi, i.span); } ast::ItemKind::Fn(..) => { @@ -928,6 +937,16 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { visit::walk_foreign_item(self, i) } + fn visit_ty(&mut self, ty: &ast::Ty) { + match ty.node { + ast::TyKind::BareFn(ref bare_fn_ty) => { + self.check_abi(bare_fn_ty.abi, ty.span); + } + _ => {} + } + visit::walk_ty(self, ty) + } + fn visit_expr(&mut self, e: &ast::Expr) { match e.node { ast::ExprKind::Box(_) => { @@ -1015,23 +1034,10 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { } match fn_kind { - FnKind::ItemFn(_, _, _, _, abi, _) if abi == Abi::RustIntrinsic => { - gate_feature_post!(&self, intrinsics, - span, - "intrinsics are subject to change") - } FnKind::ItemFn(_, _, _, _, abi, _) | - FnKind::Method(_, &ast::MethodSig { abi, .. }, _) => match abi { - Abi::RustCall => { - gate_feature_post!(&self, unboxed_closures, span, - "rust-call ABI is subject to change"); - }, - Abi::Vectorcall => { - gate_feature_post!(&self, abi_vectorcall, span, - "vectorcall is experimental and subject to change"); - }, - _ => {} - }, + FnKind::Method(_, &ast::MethodSig { abi, .. }, _) => { + self.check_abi(abi, span); + } _ => {} } visit::walk_fn(self, fn_kind, fn_decl, block, span); @@ -1044,7 +1050,10 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { ti.span, "associated constants are experimental") } - ast::TraitItemKind::Method(ref sig, _) => { + ast::TraitItemKind::Method(ref sig, ref block) => { + if block.is_none() { + self.check_abi(sig.abi, ti.span); + } if sig.constness == ast::Constness::Const { gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable"); } diff --git a/src/test/compile-fail/E0045.rs b/src/test/compile-fail/E0045.rs index edec911d3c070..2a731596b4be8 100644 --- a/src/test/compile-fail/E0045.rs +++ b/src/test/compile-fail/E0045.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern "rust-call" { fn foo(x: u8, ...); } //~ ERROR E0045 +extern "Rust" { fn foo(x: u8, ...); } //~ ERROR E0045 fn main() { } diff --git a/src/test/compile-fail/feature-gate-abi-vectorcall.rs b/src/test/compile-fail/feature-gate-abi-vectorcall.rs deleted file mode 100644 index 79f3c8dc77625..0000000000000 --- a/src/test/compile-fail/feature-gate-abi-vectorcall.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern "vectorcall" { //~ ERROR vectorcall is experimental and subject to change - fn bar(); -} - -extern "vectorcall" fn baz() { //~ ERROR vectorcall is experimental and subject to change -} - -fn main() { -} diff --git a/src/test/compile-fail/feature-gate-abi.rs b/src/test/compile-fail/feature-gate-abi.rs new file mode 100644 index 0000000000000..0c01f955c063b --- /dev/null +++ b/src/test/compile-fail/feature-gate-abi.rs @@ -0,0 +1,60 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Functions +extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change +extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental +extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change +extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change + +// Methods in trait definition +trait Tr { + extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change + extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental + extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change + extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change + + extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change + extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental + extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change + extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change +} + +struct S; + +// Methods in trait impl +impl Tr for S { + extern "rust-intrinsic" fn m1() {} //~ ERROR intrinsics are subject to change + extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental + extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change + extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change +} + +// Methods in inherent impl +impl S { + extern "rust-intrinsic" fn im1() {} //~ ERROR intrinsics are subject to change + extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental + extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change + extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change +} + +// Function pointer types +type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change +type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental +type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and subject to change +type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change + +// Foreign modules +extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change +extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental +extern "vectorcall" {} //~ ERROR vectorcall is experimental and subject to change +extern "rust-call" {} //~ ERROR rust-call ABI is subject to change + +fn main() {} diff --git a/src/test/compile-fail/feature-gate-rust-call.rs b/src/test/compile-fail/feature-gate-rust-call.rs deleted file mode 100644 index 029a9cad65fcf..0000000000000 --- a/src/test/compile-fail/feature-gate-rust-call.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern "rust-call" fn foo() { } //~ ERROR rust-call ABI is subject to change - -trait Foo { - extern "rust-call" fn foo(); -} - -impl Foo for i32 { - extern "rust-call" fn foo() { } //~ ERROR rust-call ABI is subject to change -} - -fn main() { } From 1afb17ed5f9206e1e04c5d72ea724c5fadadd46c Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 24 Jul 2016 04:48:26 +0000 Subject: [PATCH 02/21] Fix build of compiler-rt on FreeBSD Broken since ee6011fc71e02485f2dffcc25be64631c2008775 removed cmake from the process. There are likely other platforms still broken, but I didn't test on them. --- mk/rt.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mk/rt.mk b/mk/rt.mk index 067721fab4fa8..e86aec60893e9 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -384,7 +384,11 @@ COMPRT_OBJS_$(1) += emutls.o endif ifeq ($$(findstring msvc,$(1)),) + +ifeq ($$(findstring freebsd,$(1)),) COMPRT_OBJS_$(1) += gcc_personality_v0.o +endif + COMPRT_OBJS_$(1) += emutls.o ifeq ($$(findstring x86_64,$(1)),x86_64) From 8604c5494eed8d111757f23a874d9ce8ca673e2c Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 24 Jul 2016 18:03:01 +0000 Subject: [PATCH 03/21] Follow-up to 1afb17ed5f9206e1e04c5d72ea724c5fadadd46c Disable gcc_personality_v0.c in rustbuild as well as the normal build. Rustbuild now gets further on FreeBSD, but it still fails due to other problems. --- src/bootstrap/native.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 05ecbc0cadaa9..a78cef4f409b4 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -348,7 +348,9 @@ pub fn compiler_rt(build: &Build, target: &str) { ]); } } else { - sources.push("gcc_personality_v0.c"); + if !target.contains("freebsd") { + sources.push("gcc_personality_v0.c"); + } if target.contains("x86_64") { sources.extend(vec![ From ccfec65043ac0a4dfd7a31ac4804927a0cbbabe3 Mon Sep 17 00:00:00 2001 From: Timon Van Overveldt Date: Wed, 27 Apr 2016 18:02:31 -0700 Subject: [PATCH 04/21] Update gcc crate dependency to 0.3.27. This is to pull in changes to support ARM MUSL targets. This change also commits a couple of other cargo-generated changes to other dependencies in the various Cargo.toml files. --- src/bootstrap/Cargo.lock | 12 ++++++------ src/liballoc_jemalloc/Cargo.toml | 2 +- src/libflate/Cargo.toml | 2 +- src/librustc_llvm/Cargo.toml | 2 +- src/librustdoc/Cargo.toml | 2 +- src/libstd/Cargo.toml | 2 +- src/rustc/std_shim/Cargo.lock | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 1290f2a404b22..02698d6f7a123 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -7,8 +7,8 @@ dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.31 (git+https://github.com/alexcrichton/gcc-rs)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -33,7 +33,7 @@ name = "filetime" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -53,7 +53,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "kernel32-sys" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -62,7 +62,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -75,7 +75,7 @@ name = "num_cpus" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/src/liballoc_jemalloc/Cargo.toml b/src/liballoc_jemalloc/Cargo.toml index 768a0c2c0a54d..25b3c8a3a0a83 100644 --- a/src/liballoc_jemalloc/Cargo.toml +++ b/src/liballoc_jemalloc/Cargo.toml @@ -16,7 +16,7 @@ libc = { path = "../rustc/libc_shim" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3.17" +gcc = "0.3.27" [features] debug = [] diff --git a/src/libflate/Cargo.toml b/src/libflate/Cargo.toml index 52aa6bb86ef90..5423da9c81c02 100644 --- a/src/libflate/Cargo.toml +++ b/src/libflate/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["dylib"] [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3" +gcc = "0.3.27" diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index 05d20911a5dc3..f97daa22ff662 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -17,4 +17,4 @@ rustc_bitflags = { path = "../librustc_bitflags" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3" +gcc = "0.3.27" diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index a41d3b0253a36..3e510bdc9002e 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -28,4 +28,4 @@ log = { path = "../liblog" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3" +gcc = "0.3.27" diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index eded6e24f3ef5..12fff8c8c671e 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,7 +24,7 @@ unwind = { path = "../libunwind" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3" +gcc = "0.3.27" [features] jemalloc = ["alloc_jemalloc"] diff --git a/src/rustc/std_shim/Cargo.lock b/src/rustc/std_shim/Cargo.lock index bad46966ffa6b..70aef55d799c1 100644 --- a/src/rustc/std_shim/Cargo.lock +++ b/src/rustc/std_shim/Cargo.lock @@ -18,7 +18,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "core 0.0.0", - "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", ] @@ -49,7 +49,7 @@ version = "0.0.0" [[package]] name = "gcc" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -101,7 +101,7 @@ dependencies = [ "build_helper 0.1.0", "collections 0.0.0", "core 0.0.0", - "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", "panic_abort 0.0.0", "panic_unwind 0.0.0", From 627d98047d949389237b164ee117c55e09d14a64 Mon Sep 17 00:00:00 2001 From: Timon Van Overveldt Date: Wed, 27 Apr 2016 18:02:31 -0700 Subject: [PATCH 05/21] Add ARM MUSL targets. The targets are: - `arm-unknown-linux-musleabi` - `arm-unknown-linux-musleabihf` - `armv7-unknown-linux-musleabihf` These mirror the existing `gnueabi` targets. All of these targets produce fully static binaries, similar to the x86 MUSL targets. For now these targets can only be used with `--rustbuild` builds, as https://github.com/rust-lang/compiler-rt/pull/22 only made the necessary compiler-rt changes in the CMake configs, not the plain GNU Make configs. I've tested these targets GCC 5.3.0 compiled again musl-1.1.12 (downloaded from http://musl.codu.org/). An example `./configure` invocation is: ``` ./configure \ --enable-rustbuild --target=arm-unknown-linux-musleabi \ --musl-root="$MUSL_ROOT" ``` where `MUSL_ROOT` points to the `arm-linux-musleabi` prefix. Usually that path will be of the form `/foobar/arm-linux-musleabi/arm-linux-musleabi`. Usually the cross-compile toolchain will live under `/foobar/arm-linux-musleabi/bin`. That path should either by added to your `PATH` variable, or you should add a section to your `config.toml` as follows: ``` [target.arm-unknown-linux-musleabi] cc = "/foobar/arm-linux-musleabi/bin/arm-linux-musleabi-gcc" cxx = "/foobar/arm-linux-musleabi/bin/arm-linux-musleabi-g++" ``` As a prerequisite you'll also have to put a cross-compiled static `libunwind.a` library in `$MUSL_ROOT/lib`. This is similar to [how the x86_64 MUSL targets are built] (https://doc.rust-lang.org/book/advanced-linking.html). --- configure | 2 +- mk/cfg/arm-unknown-linux-musleabi.mk | 3 + mk/cfg/arm-unknown-linux-musleabihf.mk | 3 + mk/cfg/armv7-unknown-linux-musleabihf.mk | 3 + src/bootstrap/compile.rs | 3 +- src/bootstrap/sanity.rs | 2 +- src/liballoc_jemalloc/build.rs | 11 ++- src/liballoc_jemalloc/lib.rs | 4 +- .../target/arm_unknown_linux_musleabi.rs | 33 +++++++++ .../target/arm_unknown_linux_musleabihf.rs | 33 +++++++++ .../target/armv7_unknown_linux_musleabihf.rs | 34 +++++++++ src/librustc_back/target/mod.rs | 4 ++ src/librustc_back/target/musl_base.rs | 72 +++++++++++++++++++ src/libstd/rtdeps.rs | 4 +- src/libstd/sys/unix/thread.rs | 8 ++- 15 files changed, 210 insertions(+), 9 deletions(-) create mode 100644 mk/cfg/arm-unknown-linux-musleabi.mk create mode 100644 mk/cfg/arm-unknown-linux-musleabihf.mk create mode 100644 mk/cfg/armv7-unknown-linux-musleabihf.mk create mode 100644 src/librustc_back/target/arm_unknown_linux_musleabi.rs create mode 100644 src/librustc_back/target/arm_unknown_linux_musleabihf.rs create mode 100644 src/librustc_back/target/armv7_unknown_linux_musleabihf.rs create mode 100644 src/librustc_back/target/musl_base.rs diff --git a/configure b/configure index d2ec457a1c8bc..a7e24a506fbef 100755 --- a/configure +++ b/configure @@ -1192,7 +1192,7 @@ do ;; - x86_64-*-musl) + x86_64-*-musl | arm-*-musleabi) if [ ! -f $CFG_MUSL_ROOT/lib/libc.a ] then err "musl libc $CFG_MUSL_ROOT/lib/libc.a not found" diff --git a/mk/cfg/arm-unknown-linux-musleabi.mk b/mk/cfg/arm-unknown-linux-musleabi.mk new file mode 100644 index 0000000000000..8120250150d43 --- /dev/null +++ b/mk/cfg/arm-unknown-linux-musleabi.mk @@ -0,0 +1,3 @@ +# This file is intentially left empty to indicate that, while this target is +# supported, it's not supported using plain GNU Make builds. Use a --rustbuild +# instead. \ No newline at end of file diff --git a/mk/cfg/arm-unknown-linux-musleabihf.mk b/mk/cfg/arm-unknown-linux-musleabihf.mk new file mode 100644 index 0000000000000..8120250150d43 --- /dev/null +++ b/mk/cfg/arm-unknown-linux-musleabihf.mk @@ -0,0 +1,3 @@ +# This file is intentially left empty to indicate that, while this target is +# supported, it's not supported using plain GNU Make builds. Use a --rustbuild +# instead. \ No newline at end of file diff --git a/mk/cfg/armv7-unknown-linux-musleabihf.mk b/mk/cfg/armv7-unknown-linux-musleabihf.mk new file mode 100644 index 0000000000000..8120250150d43 --- /dev/null +++ b/mk/cfg/armv7-unknown-linux-musleabihf.mk @@ -0,0 +1,3 @@ +# This file is intentially left empty to indicate that, while this target is +# supported, it's not supported using plain GNU Make builds. Use a --rustbuild +# instead. \ No newline at end of file diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8ec9c7f0109f3..061192ebd1340 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -92,8 +92,7 @@ pub fn std_link(build: &Build, } add_to_sysroot(&out_dir, &libdir); - if target.contains("musl") && - (target.contains("x86_64") || target.contains("i686")) { + if target.contains("musl") && !target.contains("mips") { copy_third_party_objects(build, target, &libdir); } } diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 7c0f09c322f24..71b9c1db608cd 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -100,7 +100,7 @@ pub fn check(build: &mut Build) { } // Make sure musl-root is valid if specified - if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) { + if target.contains("musl") && !target.contains("mips") { match build.config.musl_root { Some(ref root) => { if fs::metadata(root.join("lib/libc.a")).is_err() { diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs index d1b3583d256b6..dc1b8d6ea9835 100644 --- a/src/liballoc_jemalloc/build.rs +++ b/src/liballoc_jemalloc/build.rs @@ -73,7 +73,16 @@ fn main() { .replace("\\", "/")) .current_dir(&build_dir) .env("CC", compiler.path()) - .env("EXTRA_CFLAGS", cflags) + .env("EXTRA_CFLAGS", cflags.clone()) + // jemalloc generates Makefile deps using GCC's "-MM" flag. This means + // that GCC will run the preprocessor, and only the preprocessor, over + // jemalloc's source files. If we don't specify CPPFLAGS, then at least + // on ARM that step fails with a "Missing implementation for 32-bit + // atomic operations" error. This is because no "-march" flag will be + // passed to GCC, and then GCC won't define the + // "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4" macro that jemalloc needs to + // select an atomic operation implementation. + .env("CPPFLAGS", cflags.clone()) .env("AR", &ar) .env("RANLIB", format!("{} s", ar.display())); diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 347e97e6ffc0a..ccf3d978fe434 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -36,7 +36,9 @@ use libc::{c_int, c_void, size_t}; #[cfg_attr(target_os = "android", link(name = "gcc"))] #[cfg_attr(all(not(windows), not(target_os = "android"), - not(target_env = "musl")), + not(target_env = "musl"), + not(target_env = "musleabi"), + not(target_env = "musleabihf")), link(name = "pthread"))] #[cfg(not(cargobuild))] extern "C" {} diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_back/target/arm_unknown_linux_musleabi.rs new file mode 100644 index 0000000000000..906f60f1c9a18 --- /dev/null +++ b/src/librustc_back/target/arm_unknown_linux_musleabi.rs @@ -0,0 +1,33 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::Target; + +pub fn target() -> Target { + let mut base = super::musl_base::opts(); + + // Most of these settings are copied from the arm_unknown_linux_gnueabi + // target. + base.features = "+v6".to_string(); + Target { + // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it + // to determine the calling convention and float ABI, and it doesn't + // support the "musleabi" value. + llvm_target: "arm-unknown-linux-gnueabi".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + target_os: "linux".to_string(), + target_env: "musleabi".to_string(), + target_vendor: "unknown".to_string(), + options: base, + } +} diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs new file mode 100644 index 0000000000000..3051721b8c21f --- /dev/null +++ b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs @@ -0,0 +1,33 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::Target; + +pub fn target() -> Target { + let mut base = super::musl_base::opts(); + + // Most of these settings are copied from the arm_unknown_linux_gnueabihf + // target. + base.features = "+v6,+vfp2".to_string(); + Target { + // It's important we use "gnueabihf" and not "musleabihf" here. LLVM + // uses it to determine the calling convention and float ABI, and it + // doesn't support the "musleabihf" value. + llvm_target: "arm-unknown-linux-gnueabihf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + target_os: "linux".to_string(), + target_env: "musleabi".to_string(), + target_vendor: "unknown".to_string(), + options: base, + } +} diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs new file mode 100644 index 0000000000000..8732681fb4929 --- /dev/null +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -0,0 +1,34 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::Target; + +pub fn target() -> Target { + let mut base = super::musl_base::opts(); + + // Most of these settings are copied from the armv7_unknown_linux_gnueabihf + // target. + base.features = "+v7,+vfp3,+neon".to_string(); + base.cpu = "cortex-a8".to_string(); + Target { + // It's important we use "gnueabihf" and not "musleabihf" here. LLVM + // uses it to determine the calling convention and float ABI, and LLVM + // doesn't support the "musleabihf" value. + llvm_target: "armv7-unknown-linux-gnueabihf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + target_os: "linux".to_string(), + target_env: "musleabi".to_string(), + target_vendor: "unknown".to_string(), + options: base, + } +} diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 2163a8a1689b6..1e2329aba1b49 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -58,6 +58,7 @@ mod freebsd_base; mod linux_base; mod linux_musl_base; mod openbsd_base; +mod musl_base; mod netbsd_base; mod solaris_base; mod windows_base; @@ -99,7 +100,10 @@ supported_targets! { ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), ("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi), ("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf), + ("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi), + ("arm-unknown-linux-musleabihf", arm_unknown_linux_musleabihf), ("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf), + ("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf), ("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu), ("x86_64-unknown-linux-musl", x86_64_unknown_linux_musl), ("i686-unknown-linux-musl", i686_unknown_linux_musl), diff --git a/src/librustc_back/target/musl_base.rs b/src/librustc_back/target/musl_base.rs new file mode 100644 index 0000000000000..77cf015e1d9b3 --- /dev/null +++ b/src/librustc_back/target/musl_base.rs @@ -0,0 +1,72 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::TargetOptions; + +pub fn opts() -> TargetOptions { + let mut base = super::linux_base::opts(); + + // Make sure that the linker/gcc really don't pull in anything, including + // default objects, libs, etc. + base.pre_link_args.push("-nostdlib".to_string()); + base.pre_link_args.push("-static".to_string()); + + // At least when this was tested, the linker would not add the + // `GNU_EH_FRAME` program header to executables generated, which is required + // when unwinding to locate the unwinding information. I'm not sure why this + // argument is *not* necessary for normal builds, but it can't hurt! + base.pre_link_args.push("-Wl,--eh-frame-hdr".to_string()); + + // There's a whole bunch of circular dependencies when dealing with MUSL + // unfortunately. To put this in perspective libc is statically linked to + // liblibc and libunwind is statically linked to libstd: + // + // * libcore depends on `fmod` which is in libc (transitively in liblibc). + // liblibc, however, depends on libcore. + // * compiler-rt has personality symbols that depend on libunwind, but + // libunwind is in libstd which depends on compiler-rt. + // + // Recall that linkers discard libraries and object files as much as + // possible, and with all the static linking and archives flying around with + // MUSL the linker is super aggressively stripping out objects. For example + // the first case has fmod stripped from liblibc (it's in its own object + // file) so it's not there when libcore needs it. In the second example all + // the unused symbols from libunwind are stripped (each is in its own object + // file in libstd) before we end up linking compiler-rt which depends on + // those symbols. + // + // To deal with these circular dependencies we just force the compiler to + // link everything as a group, not stripping anything out until everything + // is processed. The linker will still perform a pass to strip out object + // files but it won't do so until all objects/archives have been processed. + base.pre_link_args.push("-Wl,-(".to_string()); + base.post_link_args.push("-Wl,-)".to_string()); + + // When generating a statically linked executable there's generally some + // small setup needed which is listed in these files. These are provided by + // a musl toolchain and are linked by default by the `musl-gcc` script. Note + // that `gcc` also does this by default, it just uses some different files. + // + // Each target directory for musl has these object files included in it so + // they'll be included from there. + base.pre_link_objects_exe.push("crt1.o".to_string()); + base.pre_link_objects_exe.push("crti.o".to_string()); + base.post_link_objects.push("crtn.o".to_string()); + + // MUSL support doesn't currently include dynamic linking, so there's no + // need for dylibs or rpath business. Additionally `-pie` is incompatible + // with `-static`, so we can't pass `-pie`. + base.dynamic_linking = false; + base.has_rpath = false; + base.position_independent_executables = false; + + return base; +} + diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index a11200873d500..f23ac32f51c39 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -19,7 +19,9 @@ // // On Linux, librt and libdl are indirect dependencies via std, // and binutils 2.22+ won't add them automatically -#[cfg(all(target_os = "linux", not(target_env = "musl")))] +#[cfg(all(target_os = "linux", not(any(target_env = "musl", + target_env = "musleabi", + target_env = "musleabihf"))))] #[link(name = "dl")] #[link(name = "pthread")] extern {} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 1061ca87f6470..7f05aec4e6ea9 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -171,7 +171,9 @@ impl Drop for Thread { } } -#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))), +#[cfg(all(not(all(target_os = "linux", not(any(target_env = "musl", + target_env = "musleabi", + target_env = "musleabihf")))), not(target_os = "freebsd"), not(target_os = "macos"), not(target_os = "bitrig"), @@ -185,7 +187,9 @@ pub mod guard { } -#[cfg(any(all(target_os = "linux", not(target_env = "musl")), +#[cfg(any(all(target_os = "linux", not(any(target_env = "musl", + target_env = "musleabi", + target_env = "musleabihf"))), target_os = "freebsd", target_os = "macos", target_os = "bitrig", From 28a23d8c63e7eb37b8d604ac3e0a3254f476f0cb Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 16:17:14 -0500 Subject: [PATCH 06/21] arm-musl targets now use cfg(env = "musl") --- .gitmodules | 2 +- src/liballoc_jemalloc/lib.rs | 4 +--- src/liblibc | 2 +- src/librustc_back/target/arm_unknown_linux_musleabi.rs | 2 +- src/librustc_back/target/arm_unknown_linux_musleabihf.rs | 2 +- .../target/armv7_unknown_linux_musleabihf.rs | 2 +- src/libstd/rtdeps.rs | 4 +--- src/libstd/sys/unix/thread.rs | 8 ++------ 8 files changed, 9 insertions(+), 17 deletions(-) diff --git a/.gitmodules b/.gitmodules index 39288a7ae4907..61697a37960eb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,4 +16,4 @@ url = https://github.com/rust-lang/rust-installer.git [submodule "src/liblibc"] path = src/liblibc - url = https://github.com/rust-lang/libc.git + url = https://github.com/japaric/libc.git diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index ccf3d978fe434..347e97e6ffc0a 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -36,9 +36,7 @@ use libc::{c_int, c_void, size_t}; #[cfg_attr(target_os = "android", link(name = "gcc"))] #[cfg_attr(all(not(windows), not(target_os = "android"), - not(target_env = "musl"), - not(target_env = "musleabi"), - not(target_env = "musleabihf")), + not(target_env = "musl")), link(name = "pthread"))] #[cfg(not(cargobuild))] extern "C" {} diff --git a/src/liblibc b/src/liblibc index b0d62534d48b7..23a5092adcecc 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit b0d62534d48b711c8978d1bbe8cca0558ae7b1cb +Subproject commit 23a5092adcecc8c755e7887337e52f357353cad7 diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_back/target/arm_unknown_linux_musleabi.rs index 906f60f1c9a18..f2dff16a2842f 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabi.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabi.rs @@ -26,7 +26,7 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), - target_env: "musleabi".to_string(), + target_env: "musl".to_string(), target_vendor: "unknown".to_string(), options: base, } diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs index 3051721b8c21f..89da0213198b7 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs @@ -26,7 +26,7 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), - target_env: "musleabi".to_string(), + target_env: "musl".to_string(), target_vendor: "unknown".to_string(), options: base, } diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs index 8732681fb4929..3b9ac8e21f2e7 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -27,7 +27,7 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), - target_env: "musleabi".to_string(), + target_env: "musl".to_string(), target_vendor: "unknown".to_string(), options: base, } diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index f23ac32f51c39..c2572dfa5e152 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -19,9 +19,7 @@ // // On Linux, librt and libdl are indirect dependencies via std, // and binutils 2.22+ won't add them automatically -#[cfg(all(target_os = "linux", not(any(target_env = "musl", - target_env = "musleabi", - target_env = "musleabihf"))))] +#[cfg(all(target_os = "linux", not(any(target_env = "musl"))))] #[link(name = "dl")] #[link(name = "pthread")] extern {} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 7f05aec4e6ea9..65ebce0baa28b 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -171,9 +171,7 @@ impl Drop for Thread { } } -#[cfg(all(not(all(target_os = "linux", not(any(target_env = "musl", - target_env = "musleabi", - target_env = "musleabihf")))), +#[cfg(all(not(all(target_os = "linux", not(any(target_env = "musl")))), not(target_os = "freebsd"), not(target_os = "macos"), not(target_os = "bitrig"), @@ -187,9 +185,7 @@ pub mod guard { } -#[cfg(any(all(target_os = "linux", not(any(target_env = "musl", - target_env = "musleabi", - target_env = "musleabihf"))), +#[cfg(any(all(target_os = "linux", not(any(target_env = "musl"))), target_os = "freebsd", target_os = "macos", target_os = "bitrig", From 925e1df307d09076a4153fa86766d6612770c2ab Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 19:27:43 -0500 Subject: [PATCH 07/21] arm-musl: set max_atomic_width --- src/librustc_back/target/arm_unknown_linux_musleabi.rs | 1 + src/librustc_back/target/arm_unknown_linux_musleabihf.rs | 1 + src/librustc_back/target/armv7_unknown_linux_musleabihf.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_back/target/arm_unknown_linux_musleabi.rs index f2dff16a2842f..825fc45f2be6f 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabi.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabi.rs @@ -16,6 +16,7 @@ pub fn target() -> Target { // Most of these settings are copied from the arm_unknown_linux_gnueabi // target. base.features = "+v6".to_string(); + base.max_atomic_width = 64; Target { // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it // to determine the calling convention and float ABI, and it doesn't diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs index 89da0213198b7..6694c6a2795b7 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs @@ -16,6 +16,7 @@ pub fn target() -> Target { // Most of these settings are copied from the arm_unknown_linux_gnueabihf // target. base.features = "+v6,+vfp2".to_string(); + base.max_atomic_width = 64; Target { // It's important we use "gnueabihf" and not "musleabihf" here. LLVM // uses it to determine the calling convention and float ABI, and it diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs index 3b9ac8e21f2e7..a7ef70edf4811 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -17,6 +17,7 @@ pub fn target() -> Target { // target. base.features = "+v7,+vfp3,+neon".to_string(); base.cpu = "cortex-a8".to_string(); + base.max_atomic_width = 64; Target { // It's important we use "gnueabihf" and not "musleabihf" here. LLVM // uses it to determine the calling convention and float ABI, and LLVM From e8917aeffba526c4f4baa5792e3dfec7e5fc377c Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 20:09:50 -0500 Subject: [PATCH 08/21] arm-musl: statically link to libunwind --- src/libunwind/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index ebe6fd54799ee..fd446f5a4f942 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -16,7 +16,7 @@ fn main() { let target = env::var("TARGET").unwrap(); if target.contains("linux") { - if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) { + if target.contains("musl") && !target.contains("mips") { println!("cargo:rustc-link-lib=static=unwind"); } else if !target.contains("android") { println!("cargo:rustc-link-lib=gcc_s"); From 24dc3cee81388bc12d4badbbad0cf833889e3629 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 21:30:02 -0500 Subject: [PATCH 09/21] rustc_back/target: remove musl_base it's the same as linux_musl_base --- .../target/arm_unknown_linux_musleabi.rs | 2 +- .../target/arm_unknown_linux_musleabihf.rs | 2 +- .../target/armv7_unknown_linux_musleabihf.rs | 2 +- src/librustc_back/target/mod.rs | 1 - src/librustc_back/target/musl_base.rs | 72 ------------------- 5 files changed, 3 insertions(+), 76 deletions(-) delete mode 100644 src/librustc_back/target/musl_base.rs diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_back/target/arm_unknown_linux_musleabi.rs index 825fc45f2be6f..4bc363d0ffda1 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabi.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabi.rs @@ -11,7 +11,7 @@ use target::Target; pub fn target() -> Target { - let mut base = super::musl_base::opts(); + let mut base = super::linux_musl_base::opts(); // Most of these settings are copied from the arm_unknown_linux_gnueabi // target. diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs index 6694c6a2795b7..d96f7443dd9c6 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs @@ -11,7 +11,7 @@ use target::Target; pub fn target() -> Target { - let mut base = super::musl_base::opts(); + let mut base = super::linux_musl_base::opts(); // Most of these settings are copied from the arm_unknown_linux_gnueabihf // target. diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs index a7ef70edf4811..6cb75cbf04cbf 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -11,7 +11,7 @@ use target::Target; pub fn target() -> Target { - let mut base = super::musl_base::opts(); + let mut base = super::linux_musl_base::opts(); // Most of these settings are copied from the armv7_unknown_linux_gnueabihf // target. diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 1e2329aba1b49..f992fd529c7f4 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -58,7 +58,6 @@ mod freebsd_base; mod linux_base; mod linux_musl_base; mod openbsd_base; -mod musl_base; mod netbsd_base; mod solaris_base; mod windows_base; diff --git a/src/librustc_back/target/musl_base.rs b/src/librustc_back/target/musl_base.rs deleted file mode 100644 index 77cf015e1d9b3..0000000000000 --- a/src/librustc_back/target/musl_base.rs +++ /dev/null @@ -1,72 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use target::TargetOptions; - -pub fn opts() -> TargetOptions { - let mut base = super::linux_base::opts(); - - // Make sure that the linker/gcc really don't pull in anything, including - // default objects, libs, etc. - base.pre_link_args.push("-nostdlib".to_string()); - base.pre_link_args.push("-static".to_string()); - - // At least when this was tested, the linker would not add the - // `GNU_EH_FRAME` program header to executables generated, which is required - // when unwinding to locate the unwinding information. I'm not sure why this - // argument is *not* necessary for normal builds, but it can't hurt! - base.pre_link_args.push("-Wl,--eh-frame-hdr".to_string()); - - // There's a whole bunch of circular dependencies when dealing with MUSL - // unfortunately. To put this in perspective libc is statically linked to - // liblibc and libunwind is statically linked to libstd: - // - // * libcore depends on `fmod` which is in libc (transitively in liblibc). - // liblibc, however, depends on libcore. - // * compiler-rt has personality symbols that depend on libunwind, but - // libunwind is in libstd which depends on compiler-rt. - // - // Recall that linkers discard libraries and object files as much as - // possible, and with all the static linking and archives flying around with - // MUSL the linker is super aggressively stripping out objects. For example - // the first case has fmod stripped from liblibc (it's in its own object - // file) so it's not there when libcore needs it. In the second example all - // the unused symbols from libunwind are stripped (each is in its own object - // file in libstd) before we end up linking compiler-rt which depends on - // those symbols. - // - // To deal with these circular dependencies we just force the compiler to - // link everything as a group, not stripping anything out until everything - // is processed. The linker will still perform a pass to strip out object - // files but it won't do so until all objects/archives have been processed. - base.pre_link_args.push("-Wl,-(".to_string()); - base.post_link_args.push("-Wl,-)".to_string()); - - // When generating a statically linked executable there's generally some - // small setup needed which is listed in these files. These are provided by - // a musl toolchain and are linked by default by the `musl-gcc` script. Note - // that `gcc` also does this by default, it just uses some different files. - // - // Each target directory for musl has these object files included in it so - // they'll be included from there. - base.pre_link_objects_exe.push("crt1.o".to_string()); - base.pre_link_objects_exe.push("crti.o".to_string()); - base.post_link_objects.push("crtn.o".to_string()); - - // MUSL support doesn't currently include dynamic linking, so there's no - // need for dylibs or rpath business. Additionally `-pie` is incompatible - // with `-static`, so we can't pass `-pie`. - base.dynamic_linking = false; - base.has_rpath = false; - base.position_independent_executables = false; - - return base; -} - From 132bff9933e90e07a2f993882dca9fc674116f5b Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 25 Jul 2016 23:04:42 +0000 Subject: [PATCH 10/21] If a single import resolves to an inaccessible name in some but not all namespaces, avoid importing the name in the inaccessible namespaces. Currently, the inaccessible namespaces are imported but cause a privacy error when used. --- src/librustc_resolve/lib.rs | 11 +--- src/librustc_resolve/resolve_imports.rs | 74 +++++++++++-------------- 2 files changed, 35 insertions(+), 50 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index aa8c706ea1e27..7a0a417d0274a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -825,8 +825,6 @@ enum NameBindingKind<'a> { Import { binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>, - // Some(error) if using this imported name causes the import to be a privacy error - privacy_error: Option>>, }, } @@ -1206,16 +1204,11 @@ impl<'a> Resolver<'a> { self.used_crates.insert(krate); } - let (directive, privacy_error) = match binding.kind { - NameBindingKind::Import { directive, ref privacy_error, .. } => - (directive, privacy_error), + let directive = match binding.kind { + NameBindingKind::Import { directive, .. } => directive, _ => return, }; - if let Some(error) = privacy_error.as_ref() { - self.privacy_errors.push((**error).clone()); - } - if !self.make_glob_map { return; } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 681d9ec735b4f..fc5e2a48e876c 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -73,13 +73,11 @@ pub struct ImportDirective<'a> { impl<'a> ImportDirective<'a> { // Given the binding to which this directive resolves in a particular namespace, // this returns the binding for the name this directive defines in that namespace. - fn import(&'a self, binding: &'a NameBinding<'a>, privacy_error: Option>>) - -> NameBinding<'a> { + fn import(&'a self, binding: &'a NameBinding<'a>) -> NameBinding<'a> { NameBinding { kind: NameBindingKind::Import { binding: binding, directive: self, - privacy_error: privacy_error, }, span: self.span, vis: self.vis, @@ -328,7 +326,7 @@ impl<'a> ::ModuleS<'a> { fn define_in_glob_importers(&self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) { if !binding.is_importable() || !binding.is_pseudo_public() { return } for &(importer, directive) in self.glob_importers.borrow_mut().iter() { - let _ = importer.try_define_child(name, ns, directive.import(binding, None)); + let _ = importer.try_define_child(name, ns, directive.import(binding)); } } } @@ -409,7 +407,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { span: DUMMY_SP, vis: ty::Visibility::Public, }); - let dummy_binding = directive.import(dummy_binding, None); + let dummy_binding = directive.import(dummy_binding); let _ = source_module.try_define_child(target, ValueNS, dummy_binding.clone()); let _ = source_module.try_define_child(target, TypeNS, dummy_binding); @@ -494,14 +492,17 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { self.resolver.resolve_name_in_module(target_module, source, TypeNS, false, true); let module_ = self.resolver.current_module; + let mut privacy_error = true; for &(ns, result, determined) in &[(ValueNS, &value_result, value_determined), (TypeNS, &type_result, type_determined)] { - if determined.get() { continue } - if let Indeterminate = *result { continue } - - determined.set(true); - if let Success(binding) = *result { - if !binding.is_importable() { + match *result { + Failed(..) if !determined.get() => { + determined.set(true); + module_.update_resolution(target, ns, |resolution| { + resolution.single_imports.directive_failed() + }); + } + Success(binding) if !binding.is_importable() => { let msg = format!("`{}` is not directly importable", target); span_err!(self.resolver.session, directive.span, E0253, "{}", &msg); // Do not import this illegal binding. Import a dummy binding and pretend @@ -509,23 +510,19 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { self.import_dummy_binding(module_, directive); return Success(()); } - - let privacy_error = if !self.resolver.is_accessible(binding.vis) { - Some(Box::new(PrivacyError(directive.span, source, binding))) - } else { - None - }; - - let imported_binding = directive.import(binding, privacy_error); - let conflict = module_.try_define_child(target, ns, imported_binding); - if let Err(old_binding) = conflict { - let binding = &directive.import(binding, None); - self.resolver.report_conflict(module_, target, ns, binding, old_binding); + Success(binding) if !self.resolver.is_accessible(binding.vis) => {} + Success(binding) if !determined.get() => { + determined.set(true); + let imported_binding = directive.import(binding); + let conflict = module_.try_define_child(target, ns, imported_binding); + if let Err(old_binding) = conflict { + let binding = &directive.import(binding); + self.resolver.report_conflict(module_, target, ns, binding, old_binding); + } + privacy_error = false; } - } else { - module_.update_resolution(target, ns, |resolution| { - resolution.single_imports.directive_failed(); - }); + Success(_) => privacy_error = false, + _ => {} } } @@ -556,6 +553,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { _ => (), } + if privacy_error { + for &(ns, result) in &[(ValueNS, &value_result), (TypeNS, &type_result)] { + let binding = match *result { Success(binding) => binding, _ => continue }; + self.resolver.privacy_errors.push(PrivacyError(directive.span, source, binding)); + let _ = module_.try_define_child(target, ns, directive.import(binding)); + } + } + match (&value_result, &type_result) { (&Success(binding), _) if !binding.pseudo_vis() .is_at_least(directive.vis, self.resolver) && @@ -592,19 +597,6 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { _ => {} } - // Report a privacy error here if all successful namespaces are privacy errors. - let mut privacy_error = None; - for &ns in &[ValueNS, TypeNS] { - privacy_error = match module_.resolve_name(target, ns, true) { - Success(&NameBinding { - kind: NameBindingKind::Import { ref privacy_error, .. }, .. - }) => privacy_error.as_ref().map(|error| (**error).clone()), - _ => continue, - }; - if privacy_error.is_none() { break } - } - privacy_error.map(|error| self.resolver.privacy_errors.push(error)); - // Record what this import resolves to for later uses in documentation, // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. @@ -652,7 +644,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { }).collect::>(); for ((name, ns), binding) in bindings { if binding.is_importable() && binding.is_pseudo_public() { - let _ = module_.try_define_child(name, ns, directive.import(binding, None)); + let _ = module_.try_define_child(name, ns, directive.import(binding)); } } From 8205691929bc545430f1fa73e61a4f5f77fbbdc7 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 26 Jul 2016 04:16:48 +0000 Subject: [PATCH 11/21] Fix fallout in tests. --- src/test/compile-fail/privacy-ns2.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/compile-fail/privacy-ns2.rs b/src/test/compile-fail/privacy-ns2.rs index bf296220d2a2b..7accf0ca8201c 100644 --- a/src/test/compile-fail/privacy-ns2.rs +++ b/src/test/compile-fail/privacy-ns2.rs @@ -25,15 +25,15 @@ pub mod foo1 { } fn test_single1() { - use foo1::Bar; //~ ERROR function `Bar` is private + use foo1::Bar; - Bar(); + Bar(); //~ ERROR unresolved name `Bar` } fn test_list1() { - use foo1::{Bar,Baz}; //~ ERROR `Bar` is private + use foo1::{Bar,Baz}; - Bar(); + Bar(); //~ ERROR unresolved name `Bar` } // private type, public value @@ -46,15 +46,15 @@ pub mod foo2 { } fn test_single2() { - use foo2::Bar; //~ ERROR trait `Bar` is private + use foo2::Bar; - let _x : Box; + let _x : Box; //~ ERROR type name `Bar` is undefined } fn test_list2() { - use foo2::{Bar,Baz}; //~ ERROR `Bar` is private + use foo2::{Bar,Baz}; - let _x: Box; + let _x: Box; //~ ERROR type name `Bar` is undefined } // neither public From fbdf4cb91e69d5ca34160f221acab70f4ef9647b Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 27 Jul 2016 11:37:15 -0500 Subject: [PATCH 12/21] remove some `any`s that are no longer necessary --- src/libstd/rtdeps.rs | 2 +- src/libstd/sys/unix/thread.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index c2572dfa5e152..a11200873d500 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -19,7 +19,7 @@ // // On Linux, librt and libdl are indirect dependencies via std, // and binutils 2.22+ won't add them automatically -#[cfg(all(target_os = "linux", not(any(target_env = "musl"))))] +#[cfg(all(target_os = "linux", not(target_env = "musl")))] #[link(name = "dl")] #[link(name = "pthread")] extern {} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 65ebce0baa28b..1061ca87f6470 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -171,7 +171,7 @@ impl Drop for Thread { } } -#[cfg(all(not(all(target_os = "linux", not(any(target_env = "musl")))), +#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))), not(target_os = "freebsd"), not(target_os = "macos"), not(target_os = "bitrig"), @@ -185,7 +185,7 @@ pub mod guard { } -#[cfg(any(all(target_os = "linux", not(any(target_env = "musl"))), +#[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "freebsd", target_os = "macos", target_os = "bitrig", From 3b955b0c09233ac4f2568c9893a3c84da1e83cb1 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 27 Jul 2016 11:39:58 -0500 Subject: [PATCH 13/21] point the libc submodule back to rust-lang/libc --- .gitmodules | 2 +- src/liblibc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 61697a37960eb..39288a7ae4907 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,4 +16,4 @@ url = https://github.com/rust-lang/rust-installer.git [submodule "src/liblibc"] path = src/liblibc - url = https://github.com/japaric/libc.git + url = https://github.com/rust-lang/libc.git diff --git a/src/liblibc b/src/liblibc index 23a5092adcecc..5066b7dcab7e7 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 23a5092adcecc8c755e7887337e52f357353cad7 +Subproject commit 5066b7dcab7e700844b0e2ba71b8af9dc627a59b From 6ac83de691c5eb180e2007fcbe3236fd359d2ab7 Mon Sep 17 00:00:00 2001 From: Knight Date: Wed, 27 Jul 2016 02:30:50 +0800 Subject: [PATCH 14/21] Add test for string AddAssign --- src/libcollectionstest/string.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libcollectionstest/string.rs b/src/libcollectionstest/string.rs index 7f0fd282ae5e9..1652fb5a88d80 100644 --- a/src/libcollectionstest/string.rs +++ b/src/libcollectionstest/string.rs @@ -192,6 +192,17 @@ fn test_push_str() { assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam"); } +#[test] +fn test_add_assign() { + let mut s = String::new(); + s += ""; + assert_eq!(s.as_str(), ""); + s += "abc"; + assert_eq!(s.as_str(), "abc"); + s += "ประเทศไทย中华Việt Nam"; + assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam"); +} + #[test] fn test_push() { let mut data = String::from("ประเทศไทย中"); From cfdaca049a2451b62d3d403ef13b78d7a2f60816 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Wed, 27 Jul 2016 16:59:33 -0700 Subject: [PATCH 15/21] Rename _ to {numerics} for unknown numeric types --- src/librustc/util/ppaux.rs | 3 ++- src/test/compile-fail/array-not-vector.rs | 2 +- src/test/compile-fail/bad-const-type.rs | 2 +- src/test/compile-fail/coerce-mut.rs | 2 +- src/test/compile-fail/coercion-slice.rs | 2 +- src/test/compile-fail/fully-qualified-type-name1.rs | 2 +- src/test/compile-fail/if-let-arm-types.rs | 2 +- src/test/compile-fail/indexing-requires-a-uint.rs | 2 +- src/test/compile-fail/integral-variable-unification-error.rs | 4 ++-- src/test/compile-fail/issue-13466.rs | 4 ++-- src/test/compile-fail/issue-17651.rs | 2 +- src/test/compile-fail/issue-19991.rs | 2 +- src/test/compile-fail/issue-26237.rs | 2 +- src/test/compile-fail/issue-4201.rs | 2 +- src/test/compile-fail/issue-4968.rs | 2 +- src/test/compile-fail/issue-7867.rs | 4 ++-- src/test/compile-fail/kindck-impl-type-params-2.rs | 2 +- src/test/compile-fail/match-range-fail.rs | 2 +- src/test/compile-fail/match-vec-mismatch.rs | 2 +- src/test/compile-fail/method-self-arg-1.rs | 2 +- src/test/compile-fail/mut-pattern-mismatched.rs | 4 ++-- src/test/compile-fail/no_send-rc.rs | 2 +- src/test/compile-fail/range-1.rs | 2 +- src/test/compile-fail/repeat_count.rs | 2 +- .../compile-fail/slightly-nice-generic-literal-messages.rs | 4 ++-- src/test/compile-fail/str-idx.rs | 2 +- src/test/compile-fail/struct-base-wrong-type-2.rs | 2 +- src/test/compile-fail/struct-base-wrong-type.rs | 2 +- .../compile-fail/traits-inductive-overflow-simultaneous.rs | 2 +- src/test/compile-fail/tuple-arity-mismatch.rs | 2 +- src/test/compile-fail/tuple-index-out-of-bounds.rs | 2 +- src/test/compile-fail/type-mismatch-multiple.rs | 2 +- src/test/compile-fail/typeck-unsafe-always-share.rs | 2 +- src/test/compile-fail/vtable-res-trait-param.rs | 2 +- src/test/ui/mismatched_types/issue-26480.stderr | 2 +- 35 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0bfb7c1ed5532..a33d914e7cf7a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -974,7 +974,8 @@ impl fmt::Display for ty::InferTy { ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), - ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => write!(f, "_"), + ty::TyVar(_) => write!(f, "_"), + ty::IntVar(_) | ty::FloatVar(_) => write!(f, "{}", "{numeric}"), ty::FreshTy(v) => write!(f, "FreshTy({})", v), ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) diff --git a/src/test/compile-fail/array-not-vector.rs b/src/test/compile-fail/array-not-vector.rs index 1bbccae53a44d..b8883e4661eaa 100644 --- a/src/test/compile-fail/array-not-vector.rs +++ b/src/test/compile-fail/array-not-vector.rs @@ -12,7 +12,7 @@ fn main() { let _x: i32 = [1, 2, 3]; //~^ ERROR mismatched types //~| expected type `i32` - //~| found type `[_; 3]` + //~| found type `[{numeric}; 3]` //~| expected i32, found array of 3 elements let x: &[i32] = &[1, 2, 3]; diff --git a/src/test/compile-fail/bad-const-type.rs b/src/test/compile-fail/bad-const-type.rs index ee6ac33072792..3b6221f0df5b8 100644 --- a/src/test/compile-fail/bad-const-type.rs +++ b/src/test/compile-fail/bad-const-type.rs @@ -11,6 +11,6 @@ static i: String = 10; //~^ ERROR mismatched types //~| expected type `std::string::String` -//~| found type `_` +//~| found type `{numeric}` //~| expected struct `std::string::String`, found integral variable fn main() { println!("{}", i); } diff --git a/src/test/compile-fail/coerce-mut.rs b/src/test/compile-fail/coerce-mut.rs index 634d12441a120..91222e58b78cc 100644 --- a/src/test/compile-fail/coerce-mut.rs +++ b/src/test/compile-fail/coerce-mut.rs @@ -15,6 +15,6 @@ fn main() { f(&x); //~^ ERROR mismatched types //~| expected type `&mut i32` - //~| found type `&_` + //~| found type `&{numeric}` //~| values differ in mutability } diff --git a/src/test/compile-fail/coercion-slice.rs b/src/test/compile-fail/coercion-slice.rs index bd7e6c2a2131d..bfec84993961e 100644 --- a/src/test/compile-fail/coercion-slice.rs +++ b/src/test/compile-fail/coercion-slice.rs @@ -14,6 +14,6 @@ fn main() { let _: &[i32] = [0]; //~^ ERROR mismatched types //~| expected type `&[i32]` - //~| found type `[_; 1]` + //~| found type `[{numeric}; 1]` //~| expected &-ptr, found array of 1 elements } diff --git a/src/test/compile-fail/fully-qualified-type-name1.rs b/src/test/compile-fail/fully-qualified-type-name1.rs index 5ea8ce2264438..3ae95a72abdd9 100644 --- a/src/test/compile-fail/fully-qualified-type-name1.rs +++ b/src/test/compile-fail/fully-qualified-type-name1.rs @@ -15,6 +15,6 @@ fn main() { x = 5; //~^ ERROR mismatched types //~| expected type `std::option::Option` - //~| found type `_` + //~| found type `{numeric}` //~| expected enum `std::option::Option`, found integral variable } diff --git a/src/test/compile-fail/if-let-arm-types.rs b/src/test/compile-fail/if-let-arm-types.rs index c7b1e1a62c209..394a6fb30d7e9 100644 --- a/src/test/compile-fail/if-let-arm-types.rs +++ b/src/test/compile-fail/if-let-arm-types.rs @@ -12,7 +12,7 @@ fn main() { if let Some(b) = None { //~ ERROR: `if let` arms have incompatible types //~^ expected (), found integral variable //~| expected type `()` - //~| found type `_` + //~| found type `{numeric}` () } else { //~ NOTE: `if let` arm with an incompatible type 1 diff --git a/src/test/compile-fail/indexing-requires-a-uint.rs b/src/test/compile-fail/indexing-requires-a-uint.rs index 354d7b936485b..fe29a840f28c7 100644 --- a/src/test/compile-fail/indexing-requires-a-uint.rs +++ b/src/test/compile-fail/indexing-requires-a-uint.rs @@ -13,7 +13,7 @@ fn main() { fn bar(_: T) {} - [0][0u8]; //~ ERROR: `[_]: std::ops::Index` is not satisfied + [0][0u8]; //~ ERROR: `[{numeric}]: std::ops::Index` is not satisfied [0][0]; // should infer to be a usize diff --git a/src/test/compile-fail/integral-variable-unification-error.rs b/src/test/compile-fail/integral-variable-unification-error.rs index 99f2d25166891..9dd3772c10cd9 100644 --- a/src/test/compile-fail/integral-variable-unification-error.rs +++ b/src/test/compile-fail/integral-variable-unification-error.rs @@ -12,7 +12,7 @@ fn main() { let mut x = 2; x = 5.0; //~^ ERROR mismatched types - //~| expected type `_` - //~| found type `_` + //~| expected type `{numeric}` + //~| found type `{numeric}` //~| expected integral variable, found floating-point variable } diff --git a/src/test/compile-fail/issue-13466.rs b/src/test/compile-fail/issue-13466.rs index 17b96411603ef..b1a5adb313fac 100644 --- a/src/test/compile-fail/issue-13466.rs +++ b/src/test/compile-fail/issue-13466.rs @@ -17,13 +17,13 @@ pub fn main() { let _x: usize = match Some(1) { Ok(u) => u, //~^ ERROR mismatched types - //~| expected type `std::option::Option<_>` + //~| expected type `std::option::Option<{numeric}>` //~| found type `std::result::Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` Err(e) => panic!(e) //~^ ERROR mismatched types - //~| expected type `std::option::Option<_>` + //~| expected type `std::option::Option<{numeric}>` //~| found type `std::result::Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` }; diff --git a/src/test/compile-fail/issue-17651.rs b/src/test/compile-fail/issue-17651.rs index 0fe01ece558ee..2438c86a57c7f 100644 --- a/src/test/compile-fail/issue-17651.rs +++ b/src/test/compile-fail/issue-17651.rs @@ -14,5 +14,5 @@ fn main() { // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. (|| Box::new(*(&[0][..])))(); - //~^ ERROR `[_]: std::marker::Sized` is not satisfied + //~^ ERROR `[{numeric}]: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/issue-19991.rs b/src/test/compile-fail/issue-19991.rs index b368daaaf587c..77a83a608213d 100644 --- a/src/test/compile-fail/issue-19991.rs +++ b/src/test/compile-fail/issue-19991.rs @@ -14,7 +14,7 @@ fn main() { if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause //~| expected type `()` - //~| found type `_` + //~| found type `{numeric}` //~| expected (), found integral variable 765 }; diff --git a/src/test/compile-fail/issue-26237.rs b/src/test/compile-fail/issue-26237.rs index 11e236d22126b..f2d24f3998cc2 100644 --- a/src/test/compile-fail/issue-26237.rs +++ b/src/test/compile-fail/issue-26237.rs @@ -11,7 +11,7 @@ macro_rules! macro_panic { ($not_a_function:expr, $some_argument:ident) => { $not_a_function($some_argument) - //~^ ERROR expected function, found `_` + //~^ ERROR expected function, found `{numeric}` } } diff --git a/src/test/compile-fail/issue-4201.rs b/src/test/compile-fail/issue-4201.rs index 58423341cc6f0..65bfeed20eaa0 100644 --- a/src/test/compile-fail/issue-4201.rs +++ b/src/test/compile-fail/issue-4201.rs @@ -14,7 +14,7 @@ fn main() { } else if false { //~^ ERROR if may be missing an else clause //~| expected type `()` -//~| found type `_` +//~| found type `{numeric}` //~| expected (), found integral variable 1 }; diff --git a/src/test/compile-fail/issue-4968.rs b/src/test/compile-fail/issue-4968.rs index 7c0905873df89..e929f0cb3113d 100644 --- a/src/test/compile-fail/issue-4968.rs +++ b/src/test/compile-fail/issue-4968.rs @@ -14,7 +14,7 @@ const A: (isize,isize) = (4,2); fn main() { match 42 { A => () } //~^ ERROR mismatched types - //~| expected type `_` + //~| expected type `{numeric}` //~| found type `(isize, isize)` //~| expected integral variable, found tuple } diff --git a/src/test/compile-fail/issue-7867.rs b/src/test/compile-fail/issue-7867.rs index e0de860b0eac3..95ba2308bfb90 100644 --- a/src/test/compile-fail/issue-7867.rs +++ b/src/test/compile-fail/issue-7867.rs @@ -25,12 +25,12 @@ fn main() { match &Some(42) { Some(x) => (), //~^ ERROR mismatched types - //~| expected type `&std::option::Option<_>` + //~| expected type `&std::option::Option<{numeric}>` //~| found type `std::option::Option<_>` //~| expected &-ptr, found enum `std::option::Option` None => () //~^ ERROR mismatched types - //~| expected type `&std::option::Option<_>` + //~| expected type `&std::option::Option<{numeric}>` //~| found type `std::option::Option<_>` //~| expected &-ptr, found enum `std::option::Option` } diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs index 1cf970e150d70..93723ae9f237c 100644 --- a/src/test/compile-fail/kindck-impl-type-params-2.rs +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -21,5 +21,5 @@ fn take_param(foo: &T) { } fn main() { let x: Box<_> = box 3; take_param(&x); - //~^ ERROR `Box<_>: std::marker::Copy` is not satisfied + //~^ ERROR `Box<{numeric}>: std::marker::Copy` is not satisfied } diff --git a/src/test/compile-fail/match-range-fail.rs b/src/test/compile-fail/match-range-fail.rs index 2c4c256302186..30386a589837a 100644 --- a/src/test/compile-fail/match-range-fail.rs +++ b/src/test/compile-fail/match-range-fail.rs @@ -20,7 +20,7 @@ fn main() { 10 ... "what" => () }; //~^^ ERROR only char and numeric types are allowed in range - //~| start type: _ + //~| start type: {numeric} //~| end type: &'static str match 5 { diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs index 3ac4958e7db0f..94ac49e8f60d3 100644 --- a/src/test/compile-fail/match-vec-mismatch.rs +++ b/src/test/compile-fail/match-vec-mismatch.rs @@ -18,7 +18,7 @@ fn main() { }; match &[0, 1, 2] { - [..] => {} //~ ERROR expected an array or slice, found `&[_; 3]` + [..] => {} //~ ERROR expected an array or slice, found `&[{numeric}; 3]` }; match &[0, 1, 2] { diff --git a/src/test/compile-fail/method-self-arg-1.rs b/src/test/compile-fail/method-self-arg-1.rs index ffa5287d4b2c3..5596fb7c80799 100644 --- a/src/test/compile-fail/method-self-arg-1.rs +++ b/src/test/compile-fail/method-self-arg-1.rs @@ -24,6 +24,6 @@ fn main() { //~| expected &-ptr, found struct `Foo` Foo::bar(&42); //~ ERROR mismatched types //~| expected type `&Foo` - //~| found type `&_` + //~| found type `&{numeric}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/mut-pattern-mismatched.rs b/src/test/compile-fail/mut-pattern-mismatched.rs index 63e7dbd30def2..d1fd0057d2947 100644 --- a/src/test/compile-fail/mut-pattern-mismatched.rs +++ b/src/test/compile-fail/mut-pattern-mismatched.rs @@ -14,7 +14,7 @@ fn main() { // (separate lines to ensure the spans are accurate) let &_ //~ ERROR mismatched types - //~| expected type `&mut _` + //~| expected type `&mut {numeric}` //~| found type `&_` //~| values differ in mutability = foo; @@ -23,7 +23,7 @@ fn main() { let bar = &1; let &_ = bar; let &mut _ //~ ERROR mismatched types - //~| expected type `&_` + //~| expected type `&{numeric}` //~| found type `&mut _` //~| values differ in mutability = bar; diff --git a/src/test/compile-fail/no_send-rc.rs b/src/test/compile-fail/no_send-rc.rs index 69f6fcdc4afa6..7c364e8d6fb56 100644 --- a/src/test/compile-fail/no_send-rc.rs +++ b/src/test/compile-fail/no_send-rc.rs @@ -15,5 +15,5 @@ fn bar(_: T) {} fn main() { let x = Rc::new(5); bar(x); - //~^ ERROR `std::rc::Rc<_>: std::marker::Send` is not satisfied + //~^ ERROR `std::rc::Rc<{numeric}>: std::marker::Send` is not satisfied } diff --git a/src/test/compile-fail/range-1.rs b/src/test/compile-fail/range-1.rs index c00be91a2d74d..7d69eca5ad58f 100644 --- a/src/test/compile-fail/range-1.rs +++ b/src/test/compile-fail/range-1.rs @@ -23,5 +23,5 @@ pub fn main() { // Unsized type. let arr: &[_] = &[1, 2, 3]; let range = *arr..; - //~^ ERROR `[_]: std::marker::Sized` is not satisfied + //~^ ERROR `[{numeric}]: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 3a7e9cc4191ec..1bdd24abe8183 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -28,7 +28,7 @@ fn main() { let d = [0; 0.5]; //~^ ERROR mismatched types //~| expected type `usize` - //~| found type `_` + //~| found type `{numeric}` //~| expected usize, found floating-point variable //~| ERROR expected usize for repeat count, found float [E0306] let e = [0; "foo"]; diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs index 3140bb6e5731d..589876a7f5ff1 100644 --- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs +++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs @@ -16,8 +16,8 @@ fn main() { match Foo(1.1, marker::PhantomData) { 1 => {} //~^ ERROR mismatched types - //~| expected type `Foo<_, _>` - //~| found type `_` + //~| expected type `Foo<{numeric}, _>` + //~| found type `{numeric}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/str-idx.rs b/src/test/compile-fail/str-idx.rs index b972a09b5c490..1fb93bd790912 100644 --- a/src/test/compile-fail/str-idx.rs +++ b/src/test/compile-fail/str-idx.rs @@ -10,5 +10,5 @@ pub fn main() { let s: &str = "hello"; - let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<_>` is not satisfied + let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<{numeric}>` is not satisfied } diff --git a/src/test/compile-fail/struct-base-wrong-type-2.rs b/src/test/compile-fail/struct-base-wrong-type-2.rs index 1250d0dabcd9a..9624af488dd89 100644 --- a/src/test/compile-fail/struct-base-wrong-type-2.rs +++ b/src/test/compile-fail/struct-base-wrong-type-2.rs @@ -24,6 +24,6 @@ fn main() { //~| expected struct `Foo`, found struct `Bar` let f__isize = Foo { a: 2, ..4 }; //~ ERROR mismatched types //~| expected type `Foo` - //~| found type `_` + //~| found type `{numeric}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/struct-base-wrong-type.rs b/src/test/compile-fail/struct-base-wrong-type.rs index 4503e465840fe..89b57f3dcd325 100644 --- a/src/test/compile-fail/struct-base-wrong-type.rs +++ b/src/test/compile-fail/struct-base-wrong-type.rs @@ -23,7 +23,7 @@ static foo: Foo = Foo { a: 2, ..bar }; //~ ERROR mismatched types //~| expected struct `Foo`, found struct `Bar` static foo_i: Foo = Foo { a: 2, ..4 }; //~ ERROR mismatched types //~| expected type `Foo` - //~| found type `_` + //~| found type `{numeric}` //~| expected struct `Foo`, found integral variable fn main() { diff --git a/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs b/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs index 2968e8a7ca996..97a99cb3ce7cc 100644 --- a/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs +++ b/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs @@ -26,5 +26,5 @@ fn is_ee(t: T) { fn main() { is_ee(4); - //~^ ERROR overflow evaluating the requirement `_: Tweedle + //~^ ERROR overflow evaluating the requirement `{numeric}: Tweedle } diff --git a/src/test/compile-fail/tuple-arity-mismatch.rs b/src/test/compile-fail/tuple-arity-mismatch.rs index e62255a4e77d4..09dc9aaf000e8 100644 --- a/src/test/compile-fail/tuple-arity-mismatch.rs +++ b/src/test/compile-fail/tuple-arity-mismatch.rs @@ -16,7 +16,7 @@ fn main() { let y = first ((1,2.0,3)); //~^ ERROR mismatched types //~| expected type `(isize, f64)` - //~| found type `(isize, f64, _)` + //~| found type `(isize, f64, {numeric})` //~| expected a tuple with 2 elements, found one with 3 elements let y = first ((1,)); diff --git a/src/test/compile-fail/tuple-index-out-of-bounds.rs b/src/test/compile-fail/tuple-index-out-of-bounds.rs index c2c41fbbb2aaf..4a9d59ea0ed7f 100644 --- a/src/test/compile-fail/tuple-index-out-of-bounds.rs +++ b/src/test/compile-fail/tuple-index-out-of-bounds.rs @@ -20,5 +20,5 @@ fn main() { tuple.0; tuple.1; tuple.2; - //~^ ERROR attempted out-of-bounds tuple index `2` on type `(_, _)` + //~^ ERROR attempted out-of-bounds tuple index `2` on type `({numeric}, {numeric})` } diff --git a/src/test/compile-fail/type-mismatch-multiple.rs b/src/test/compile-fail/type-mismatch-multiple.rs index 0f174d99fefcb..681b3a559c2b8 100644 --- a/src/test/compile-fail/type-mismatch-multiple.rs +++ b/src/test/compile-fail/type-mismatch-multiple.rs @@ -13,7 +13,7 @@ fn main() { let a: bool = 1; let b: i32 = true; } //~^ ERROR mismatched types //~| expected type `bool` -//~| found type `_` +//~| found type `{numeric}` //~| expected bool, found integral variable //~| ERROR mismatched types //~| expected i32, found bool diff --git a/src/test/compile-fail/typeck-unsafe-always-share.rs b/src/test/compile-fail/typeck-unsafe-always-share.rs index 6047f6770a7bd..50b8ae7e48cdc 100644 --- a/src/test/compile-fail/typeck-unsafe-always-share.rs +++ b/src/test/compile-fail/typeck-unsafe-always-share.rs @@ -27,7 +27,7 @@ fn test(s: T) {} fn main() { let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)}); test(us); - //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied let uns = UnsafeCell::new(NoSync); test(uns); diff --git a/src/test/compile-fail/vtable-res-trait-param.rs b/src/test/compile-fail/vtable-res-trait-param.rs index eb0baff0005dd..936b23075eb98 100644 --- a/src/test/compile-fail/vtable-res-trait-param.rs +++ b/src/test/compile-fail/vtable-res-trait-param.rs @@ -24,7 +24,7 @@ impl TraitB for isize { fn call_it(b: B) -> isize { let y = 4; - b.gimme_an_a(y) //~ ERROR `_: TraitA` is not satisfied + b.gimme_an_a(y) //~ ERROR `{numeric}: TraitA` is not satisfied } fn main() { diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index ff6920d28ccf9..3a8d9a16398d1 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -5,7 +5,7 @@ error[E0308]: mismatched types | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize $DIR/issue-26480.rs:38:5: 38:19 note: in this expansion of write! (defined in $DIR/issue-26480.rs) -error: non-scalar cast: `_` as `()` +error: non-scalar cast: `{numeric}` as `()` --> $DIR/issue-26480.rs:33:19 | 33 | ($x:expr) => ($x as ()) From cdc6afed389ecdcea0955eadae59ea6b008a58fe Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 26 Jul 2016 16:31:39 -0700 Subject: [PATCH 16/21] Add non-panicking abs() functions to all signed integer types. Currently, calling abs() on one of the signed integer types might panic (in debug mode at least) because the absolute value of the largest negative value can not be represented in that signed type. Unlike all other integer operations, there is currently not a non-panicking version on this function. This seems to just be an oversight in the design, therefore just adding it now. --- src/libcore/num/mod.rs | 84 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 97648cc34699a..4636811aa46da 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -611,6 +611,31 @@ macro_rules! int_impl { if b {None} else {Some(a)} } + /// Checked absolute value. Computes `self.abs()`, returning `None` if + /// `self == MIN`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # #![feature(no_panic_abs)] + /// + /// use std::i32; + /// + /// assert_eq!((-5i32).checked_abs(), Some(5)); + /// assert_eq!(i32::MIN.checked_abs(), None); + /// ``` + #[unstable(feature = "no_panic_abs", issue = "35057")] + #[inline] + pub fn checked_abs(self) -> Option { + if self.is_negative() { + self.checked_neg() + } else { + Some(self) + } + } + /// Saturating integer addition. Computes `self + other`, saturating at /// the numeric bounds instead of overflowing. /// @@ -863,6 +888,36 @@ macro_rules! int_impl { self.overflowing_shr(rhs).0 } + /// Wrapping (modular) absolute value. Computes `self.abs()`, + /// wrapping around at the boundary of the type. + /// + /// The only case where such wrapping can occur is when one takes + /// the absolute value of the negative minimal value for the type + /// this is a positive value that is too large to represent in the + /// type. In such a case, this function returns `MIN` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # #![feature(no_panic_abs)] + /// + /// assert_eq!(100i8.wrapping_abs(), 100); + /// assert_eq!((-100i8).wrapping_abs(), 100); + /// assert_eq!((-128i8).wrapping_abs(), -128); + /// assert_eq!((-128i8).wrapping_abs() as u8, 128); + /// ``` + #[unstable(feature = "no_panic_abs", issue = "35057")] + #[inline(always)] + pub fn wrapping_abs(self) -> Self { + if self.is_negative() { + self.wrapping_neg() + } else { + self + } + } + /// Calculates `self` + `rhs` /// /// Returns a tuple of the addition along with a boolean indicating @@ -1071,6 +1126,35 @@ macro_rules! int_impl { (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) } + /// Computes the absolute value of `self`. + /// + /// Returns a tuple of the absolute version of self along with a + /// boolean indicating whether an overflow happened. If self is the + /// minimum value (e.g. i32::MIN for values of type i32), then the + /// minimum value will be returned again and true will be returned for + /// an overflow happening. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # #![feature(no_panic_abs)] + /// + /// assert_eq!(10i8.overflowing_abs(), (10,false)); + /// assert_eq!((-10i8).overflowing_abs(), (10,false)); + /// assert_eq!((-128i8).overflowing_abs(), (-128,true)); + /// ``` + #[unstable(feature = "no_panic_abs", issue = "35057")] + #[inline] + pub fn overflowing_abs(self) -> (Self, bool) { + if self.is_negative() { + self.overflowing_neg() + } else { + (self, false) + } + } + /// Raises self to the power of `exp`, using exponentiation by squaring. /// /// # Examples From ea77049cfa72358d6a2d6370a3f7a6a70d93b8e8 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 28 Jul 2016 09:49:31 -0700 Subject: [PATCH 17/21] Move to {integer} and {float} --- src/librustc/util/ppaux.rs | 3 ++- src/test/compile-fail/array-not-vector.rs | 2 +- src/test/compile-fail/bad-const-type.rs | 2 +- src/test/compile-fail/coerce-mut.rs | 2 +- src/test/compile-fail/coercion-slice.rs | 2 +- src/test/compile-fail/fully-qualified-type-name1.rs | 2 +- src/test/compile-fail/if-let-arm-types.rs | 2 +- src/test/compile-fail/indexing-requires-a-uint.rs | 2 +- src/test/compile-fail/integral-variable-unification-error.rs | 4 ++-- src/test/compile-fail/issue-13466.rs | 4 ++-- src/test/compile-fail/issue-17651.rs | 2 +- src/test/compile-fail/issue-19991.rs | 2 +- src/test/compile-fail/issue-26237.rs | 2 +- src/test/compile-fail/issue-4201.rs | 2 +- src/test/compile-fail/issue-4968.rs | 2 +- src/test/compile-fail/issue-7867.rs | 4 ++-- src/test/compile-fail/kindck-impl-type-params-2.rs | 2 +- src/test/compile-fail/match-range-fail.rs | 4 ++-- src/test/compile-fail/match-vec-mismatch.rs | 2 +- src/test/compile-fail/method-self-arg-1.rs | 2 +- src/test/compile-fail/mut-pattern-mismatched.rs | 4 ++-- src/test/compile-fail/no_send-rc.rs | 2 +- src/test/compile-fail/range-1.rs | 2 +- src/test/compile-fail/repeat_count.rs | 2 +- .../compile-fail/slightly-nice-generic-literal-messages.rs | 4 ++-- src/test/compile-fail/str-idx.rs | 2 +- src/test/compile-fail/struct-base-wrong-type-2.rs | 2 +- src/test/compile-fail/struct-base-wrong-type.rs | 2 +- .../compile-fail/traits-inductive-overflow-simultaneous.rs | 2 +- src/test/compile-fail/tuple-arity-mismatch.rs | 2 +- src/test/compile-fail/tuple-index-out-of-bounds.rs | 2 +- src/test/compile-fail/type-mismatch-multiple.rs | 2 +- src/test/compile-fail/typeck-unsafe-always-share.rs | 2 +- src/test/compile-fail/vtable-res-trait-param.rs | 2 +- src/test/ui/mismatched_types/issue-26480.stderr | 2 +- 35 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index a33d914e7cf7a..60977a80946ff 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -975,7 +975,8 @@ impl fmt::Display for ty::InferTy { ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), ty::TyVar(_) => write!(f, "_"), - ty::IntVar(_) | ty::FloatVar(_) => write!(f, "{}", "{numeric}"), + ty::IntVar(_) => write!(f, "{}", "{integer}"), + ty::FloatVar(_) => write!(f, "{}", "{float}"), ty::FreshTy(v) => write!(f, "FreshTy({})", v), ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) diff --git a/src/test/compile-fail/array-not-vector.rs b/src/test/compile-fail/array-not-vector.rs index b8883e4661eaa..47e1c09f380b8 100644 --- a/src/test/compile-fail/array-not-vector.rs +++ b/src/test/compile-fail/array-not-vector.rs @@ -12,7 +12,7 @@ fn main() { let _x: i32 = [1, 2, 3]; //~^ ERROR mismatched types //~| expected type `i32` - //~| found type `[{numeric}; 3]` + //~| found type `[{integer}; 3]` //~| expected i32, found array of 3 elements let x: &[i32] = &[1, 2, 3]; diff --git a/src/test/compile-fail/bad-const-type.rs b/src/test/compile-fail/bad-const-type.rs index 3b6221f0df5b8..5547d19868d34 100644 --- a/src/test/compile-fail/bad-const-type.rs +++ b/src/test/compile-fail/bad-const-type.rs @@ -11,6 +11,6 @@ static i: String = 10; //~^ ERROR mismatched types //~| expected type `std::string::String` -//~| found type `{numeric}` +//~| found type `{integer}` //~| expected struct `std::string::String`, found integral variable fn main() { println!("{}", i); } diff --git a/src/test/compile-fail/coerce-mut.rs b/src/test/compile-fail/coerce-mut.rs index 91222e58b78cc..86702a7463fd0 100644 --- a/src/test/compile-fail/coerce-mut.rs +++ b/src/test/compile-fail/coerce-mut.rs @@ -15,6 +15,6 @@ fn main() { f(&x); //~^ ERROR mismatched types //~| expected type `&mut i32` - //~| found type `&{numeric}` + //~| found type `&{integer}` //~| values differ in mutability } diff --git a/src/test/compile-fail/coercion-slice.rs b/src/test/compile-fail/coercion-slice.rs index bfec84993961e..a619f33468f4a 100644 --- a/src/test/compile-fail/coercion-slice.rs +++ b/src/test/compile-fail/coercion-slice.rs @@ -14,6 +14,6 @@ fn main() { let _: &[i32] = [0]; //~^ ERROR mismatched types //~| expected type `&[i32]` - //~| found type `[{numeric}; 1]` + //~| found type `[{integer}; 1]` //~| expected &-ptr, found array of 1 elements } diff --git a/src/test/compile-fail/fully-qualified-type-name1.rs b/src/test/compile-fail/fully-qualified-type-name1.rs index 3ae95a72abdd9..1a7ceb2e7639e 100644 --- a/src/test/compile-fail/fully-qualified-type-name1.rs +++ b/src/test/compile-fail/fully-qualified-type-name1.rs @@ -15,6 +15,6 @@ fn main() { x = 5; //~^ ERROR mismatched types //~| expected type `std::option::Option` - //~| found type `{numeric}` + //~| found type `{integer}` //~| expected enum `std::option::Option`, found integral variable } diff --git a/src/test/compile-fail/if-let-arm-types.rs b/src/test/compile-fail/if-let-arm-types.rs index 394a6fb30d7e9..40013a7ee43bb 100644 --- a/src/test/compile-fail/if-let-arm-types.rs +++ b/src/test/compile-fail/if-let-arm-types.rs @@ -12,7 +12,7 @@ fn main() { if let Some(b) = None { //~ ERROR: `if let` arms have incompatible types //~^ expected (), found integral variable //~| expected type `()` - //~| found type `{numeric}` + //~| found type `{integer}` () } else { //~ NOTE: `if let` arm with an incompatible type 1 diff --git a/src/test/compile-fail/indexing-requires-a-uint.rs b/src/test/compile-fail/indexing-requires-a-uint.rs index fe29a840f28c7..61d54b3f8e4fd 100644 --- a/src/test/compile-fail/indexing-requires-a-uint.rs +++ b/src/test/compile-fail/indexing-requires-a-uint.rs @@ -13,7 +13,7 @@ fn main() { fn bar(_: T) {} - [0][0u8]; //~ ERROR: `[{numeric}]: std::ops::Index` is not satisfied + [0][0u8]; //~ ERROR: `[{integer}]: std::ops::Index` is not satisfied [0][0]; // should infer to be a usize diff --git a/src/test/compile-fail/integral-variable-unification-error.rs b/src/test/compile-fail/integral-variable-unification-error.rs index 9dd3772c10cd9..f2686ae4d196b 100644 --- a/src/test/compile-fail/integral-variable-unification-error.rs +++ b/src/test/compile-fail/integral-variable-unification-error.rs @@ -12,7 +12,7 @@ fn main() { let mut x = 2; x = 5.0; //~^ ERROR mismatched types - //~| expected type `{numeric}` - //~| found type `{numeric}` + //~| expected type `{integer}` + //~| found type `{float}` //~| expected integral variable, found floating-point variable } diff --git a/src/test/compile-fail/issue-13466.rs b/src/test/compile-fail/issue-13466.rs index b1a5adb313fac..abddf6ba7a38d 100644 --- a/src/test/compile-fail/issue-13466.rs +++ b/src/test/compile-fail/issue-13466.rs @@ -17,13 +17,13 @@ pub fn main() { let _x: usize = match Some(1) { Ok(u) => u, //~^ ERROR mismatched types - //~| expected type `std::option::Option<{numeric}>` + //~| expected type `std::option::Option<{integer}>` //~| found type `std::result::Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` Err(e) => panic!(e) //~^ ERROR mismatched types - //~| expected type `std::option::Option<{numeric}>` + //~| expected type `std::option::Option<{integer}>` //~| found type `std::result::Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` }; diff --git a/src/test/compile-fail/issue-17651.rs b/src/test/compile-fail/issue-17651.rs index 2438c86a57c7f..3ea136aca4bec 100644 --- a/src/test/compile-fail/issue-17651.rs +++ b/src/test/compile-fail/issue-17651.rs @@ -14,5 +14,5 @@ fn main() { // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. (|| Box::new(*(&[0][..])))(); - //~^ ERROR `[{numeric}]: std::marker::Sized` is not satisfied + //~^ ERROR `[{integer}]: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/issue-19991.rs b/src/test/compile-fail/issue-19991.rs index 77a83a608213d..e07dfaf9fe59e 100644 --- a/src/test/compile-fail/issue-19991.rs +++ b/src/test/compile-fail/issue-19991.rs @@ -14,7 +14,7 @@ fn main() { if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause //~| expected type `()` - //~| found type `{numeric}` + //~| found type `{integer}` //~| expected (), found integral variable 765 }; diff --git a/src/test/compile-fail/issue-26237.rs b/src/test/compile-fail/issue-26237.rs index f2d24f3998cc2..22772e596b19e 100644 --- a/src/test/compile-fail/issue-26237.rs +++ b/src/test/compile-fail/issue-26237.rs @@ -11,7 +11,7 @@ macro_rules! macro_panic { ($not_a_function:expr, $some_argument:ident) => { $not_a_function($some_argument) - //~^ ERROR expected function, found `{numeric}` + //~^ ERROR expected function, found `{integer}` } } diff --git a/src/test/compile-fail/issue-4201.rs b/src/test/compile-fail/issue-4201.rs index 65bfeed20eaa0..b1f668d9c5e21 100644 --- a/src/test/compile-fail/issue-4201.rs +++ b/src/test/compile-fail/issue-4201.rs @@ -14,7 +14,7 @@ fn main() { } else if false { //~^ ERROR if may be missing an else clause //~| expected type `()` -//~| found type `{numeric}` +//~| found type `{integer}` //~| expected (), found integral variable 1 }; diff --git a/src/test/compile-fail/issue-4968.rs b/src/test/compile-fail/issue-4968.rs index e929f0cb3113d..77588e5c221fd 100644 --- a/src/test/compile-fail/issue-4968.rs +++ b/src/test/compile-fail/issue-4968.rs @@ -14,7 +14,7 @@ const A: (isize,isize) = (4,2); fn main() { match 42 { A => () } //~^ ERROR mismatched types - //~| expected type `{numeric}` + //~| expected type `{integer}` //~| found type `(isize, isize)` //~| expected integral variable, found tuple } diff --git a/src/test/compile-fail/issue-7867.rs b/src/test/compile-fail/issue-7867.rs index 95ba2308bfb90..ed465117344d4 100644 --- a/src/test/compile-fail/issue-7867.rs +++ b/src/test/compile-fail/issue-7867.rs @@ -25,12 +25,12 @@ fn main() { match &Some(42) { Some(x) => (), //~^ ERROR mismatched types - //~| expected type `&std::option::Option<{numeric}>` + //~| expected type `&std::option::Option<{integer}>` //~| found type `std::option::Option<_>` //~| expected &-ptr, found enum `std::option::Option` None => () //~^ ERROR mismatched types - //~| expected type `&std::option::Option<{numeric}>` + //~| expected type `&std::option::Option<{integer}>` //~| found type `std::option::Option<_>` //~| expected &-ptr, found enum `std::option::Option` } diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs index 93723ae9f237c..a455a7b2d5d0f 100644 --- a/src/test/compile-fail/kindck-impl-type-params-2.rs +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -21,5 +21,5 @@ fn take_param(foo: &T) { } fn main() { let x: Box<_> = box 3; take_param(&x); - //~^ ERROR `Box<{numeric}>: std::marker::Copy` is not satisfied + //~^ ERROR `Box<{integer}>: std::marker::Copy` is not satisfied } diff --git a/src/test/compile-fail/match-range-fail.rs b/src/test/compile-fail/match-range-fail.rs index 30386a589837a..f89b3e39390d3 100644 --- a/src/test/compile-fail/match-range-fail.rs +++ b/src/test/compile-fail/match-range-fail.rs @@ -20,7 +20,7 @@ fn main() { 10 ... "what" => () }; //~^^ ERROR only char and numeric types are allowed in range - //~| start type: {numeric} + //~| start type: {integer} //~| end type: &'static str match 5 { @@ -28,6 +28,6 @@ fn main() { _ => { } }; //~^^^ ERROR mismatched types - //~| expected type `_` + //~| expected type `{integer}` //~| found type `char` } diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs index 94ac49e8f60d3..596cec167c218 100644 --- a/src/test/compile-fail/match-vec-mismatch.rs +++ b/src/test/compile-fail/match-vec-mismatch.rs @@ -18,7 +18,7 @@ fn main() { }; match &[0, 1, 2] { - [..] => {} //~ ERROR expected an array or slice, found `&[{numeric}; 3]` + [..] => {} //~ ERROR expected an array or slice, found `&[{integer}; 3]` }; match &[0, 1, 2] { diff --git a/src/test/compile-fail/method-self-arg-1.rs b/src/test/compile-fail/method-self-arg-1.rs index 5596fb7c80799..03816362d46c3 100644 --- a/src/test/compile-fail/method-self-arg-1.rs +++ b/src/test/compile-fail/method-self-arg-1.rs @@ -24,6 +24,6 @@ fn main() { //~| expected &-ptr, found struct `Foo` Foo::bar(&42); //~ ERROR mismatched types //~| expected type `&Foo` - //~| found type `&{numeric}` + //~| found type `&{integer}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/mut-pattern-mismatched.rs b/src/test/compile-fail/mut-pattern-mismatched.rs index d1fd0057d2947..318d121e4c2df 100644 --- a/src/test/compile-fail/mut-pattern-mismatched.rs +++ b/src/test/compile-fail/mut-pattern-mismatched.rs @@ -14,7 +14,7 @@ fn main() { // (separate lines to ensure the spans are accurate) let &_ //~ ERROR mismatched types - //~| expected type `&mut {numeric}` + //~| expected type `&mut {integer}` //~| found type `&_` //~| values differ in mutability = foo; @@ -23,7 +23,7 @@ fn main() { let bar = &1; let &_ = bar; let &mut _ //~ ERROR mismatched types - //~| expected type `&{numeric}` + //~| expected type `&{integer}` //~| found type `&mut _` //~| values differ in mutability = bar; diff --git a/src/test/compile-fail/no_send-rc.rs b/src/test/compile-fail/no_send-rc.rs index 7c364e8d6fb56..f31d378733491 100644 --- a/src/test/compile-fail/no_send-rc.rs +++ b/src/test/compile-fail/no_send-rc.rs @@ -15,5 +15,5 @@ fn bar(_: T) {} fn main() { let x = Rc::new(5); bar(x); - //~^ ERROR `std::rc::Rc<{numeric}>: std::marker::Send` is not satisfied + //~^ ERROR `std::rc::Rc<{integer}>: std::marker::Send` is not satisfied } diff --git a/src/test/compile-fail/range-1.rs b/src/test/compile-fail/range-1.rs index 7d69eca5ad58f..dc6833163a478 100644 --- a/src/test/compile-fail/range-1.rs +++ b/src/test/compile-fail/range-1.rs @@ -23,5 +23,5 @@ pub fn main() { // Unsized type. let arr: &[_] = &[1, 2, 3]; let range = *arr..; - //~^ ERROR `[{numeric}]: std::marker::Sized` is not satisfied + //~^ ERROR `[{integer}]: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 1bdd24abe8183..1758b28a32482 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -28,7 +28,7 @@ fn main() { let d = [0; 0.5]; //~^ ERROR mismatched types //~| expected type `usize` - //~| found type `{numeric}` + //~| found type `{float}` //~| expected usize, found floating-point variable //~| ERROR expected usize for repeat count, found float [E0306] let e = [0; "foo"]; diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs index 589876a7f5ff1..2eba7c2e534e1 100644 --- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs +++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs @@ -16,8 +16,8 @@ fn main() { match Foo(1.1, marker::PhantomData) { 1 => {} //~^ ERROR mismatched types - //~| expected type `Foo<{numeric}, _>` - //~| found type `{numeric}` + //~| expected type `Foo<{float}, _>` + //~| found type `{integer}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/str-idx.rs b/src/test/compile-fail/str-idx.rs index 1fb93bd790912..2b2c23a3ce4e9 100644 --- a/src/test/compile-fail/str-idx.rs +++ b/src/test/compile-fail/str-idx.rs @@ -10,5 +10,5 @@ pub fn main() { let s: &str = "hello"; - let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<{numeric}>` is not satisfied + let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<{integer}>` is not satisfied } diff --git a/src/test/compile-fail/struct-base-wrong-type-2.rs b/src/test/compile-fail/struct-base-wrong-type-2.rs index 9624af488dd89..7e5510edb2c33 100644 --- a/src/test/compile-fail/struct-base-wrong-type-2.rs +++ b/src/test/compile-fail/struct-base-wrong-type-2.rs @@ -24,6 +24,6 @@ fn main() { //~| expected struct `Foo`, found struct `Bar` let f__isize = Foo { a: 2, ..4 }; //~ ERROR mismatched types //~| expected type `Foo` - //~| found type `{numeric}` + //~| found type `{integer}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/struct-base-wrong-type.rs b/src/test/compile-fail/struct-base-wrong-type.rs index 89b57f3dcd325..3703b15d4db83 100644 --- a/src/test/compile-fail/struct-base-wrong-type.rs +++ b/src/test/compile-fail/struct-base-wrong-type.rs @@ -23,7 +23,7 @@ static foo: Foo = Foo { a: 2, ..bar }; //~ ERROR mismatched types //~| expected struct `Foo`, found struct `Bar` static foo_i: Foo = Foo { a: 2, ..4 }; //~ ERROR mismatched types //~| expected type `Foo` - //~| found type `{numeric}` + //~| found type `{integer}` //~| expected struct `Foo`, found integral variable fn main() { diff --git a/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs b/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs index 97a99cb3ce7cc..777746a189c5f 100644 --- a/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs +++ b/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs @@ -26,5 +26,5 @@ fn is_ee(t: T) { fn main() { is_ee(4); - //~^ ERROR overflow evaluating the requirement `{numeric}: Tweedle + //~^ ERROR overflow evaluating the requirement `{integer}: Tweedle } diff --git a/src/test/compile-fail/tuple-arity-mismatch.rs b/src/test/compile-fail/tuple-arity-mismatch.rs index 09dc9aaf000e8..a71f441029472 100644 --- a/src/test/compile-fail/tuple-arity-mismatch.rs +++ b/src/test/compile-fail/tuple-arity-mismatch.rs @@ -16,7 +16,7 @@ fn main() { let y = first ((1,2.0,3)); //~^ ERROR mismatched types //~| expected type `(isize, f64)` - //~| found type `(isize, f64, {numeric})` + //~| found type `(isize, f64, {integer})` //~| expected a tuple with 2 elements, found one with 3 elements let y = first ((1,)); diff --git a/src/test/compile-fail/tuple-index-out-of-bounds.rs b/src/test/compile-fail/tuple-index-out-of-bounds.rs index 4a9d59ea0ed7f..4597cf3d350c4 100644 --- a/src/test/compile-fail/tuple-index-out-of-bounds.rs +++ b/src/test/compile-fail/tuple-index-out-of-bounds.rs @@ -20,5 +20,5 @@ fn main() { tuple.0; tuple.1; tuple.2; - //~^ ERROR attempted out-of-bounds tuple index `2` on type `({numeric}, {numeric})` + //~^ ERROR attempted out-of-bounds tuple index `2` on type `({integer}, {integer})` } diff --git a/src/test/compile-fail/type-mismatch-multiple.rs b/src/test/compile-fail/type-mismatch-multiple.rs index 681b3a559c2b8..9359c03595669 100644 --- a/src/test/compile-fail/type-mismatch-multiple.rs +++ b/src/test/compile-fail/type-mismatch-multiple.rs @@ -13,7 +13,7 @@ fn main() { let a: bool = 1; let b: i32 = true; } //~^ ERROR mismatched types //~| expected type `bool` -//~| found type `{numeric}` +//~| found type `{integer}` //~| expected bool, found integral variable //~| ERROR mismatched types //~| expected i32, found bool diff --git a/src/test/compile-fail/typeck-unsafe-always-share.rs b/src/test/compile-fail/typeck-unsafe-always-share.rs index 50b8ae7e48cdc..f0172777cdabb 100644 --- a/src/test/compile-fail/typeck-unsafe-always-share.rs +++ b/src/test/compile-fail/typeck-unsafe-always-share.rs @@ -27,7 +27,7 @@ fn test(s: T) {} fn main() { let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)}); test(us); - //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied let uns = UnsafeCell::new(NoSync); test(uns); diff --git a/src/test/compile-fail/vtable-res-trait-param.rs b/src/test/compile-fail/vtable-res-trait-param.rs index 936b23075eb98..8b3e9369ece46 100644 --- a/src/test/compile-fail/vtable-res-trait-param.rs +++ b/src/test/compile-fail/vtable-res-trait-param.rs @@ -24,7 +24,7 @@ impl TraitB for isize { fn call_it(b: B) -> isize { let y = 4; - b.gimme_an_a(y) //~ ERROR `{numeric}: TraitA` is not satisfied + b.gimme_an_a(y) //~ ERROR `{integer}: TraitA` is not satisfied } fn main() { diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 3a8d9a16398d1..45638a65915c4 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -5,7 +5,7 @@ error[E0308]: mismatched types | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize $DIR/issue-26480.rs:38:5: 38:19 note: in this expansion of write! (defined in $DIR/issue-26480.rs) -error: non-scalar cast: `{numeric}` as `()` +error: non-scalar cast: `{integer}` as `()` --> $DIR/issue-26480.rs:33:19 | 33 | ($x:expr) => ($x as ()) From 6dc98cf099d1fc3209e1354144f2190c052c8a0b Mon Sep 17 00:00:00 2001 From: mcarton Date: Thu, 28 Jul 2016 19:33:31 +0200 Subject: [PATCH 18/21] Revert "Remove unused methods from MultiSpan" This reverts commit f7019a4e2f80577d38ec35fcebd64d5970b15f78. This removed the only way to make a suggestion with more than one substitute. Bring it back until we come up with a better solution. --- src/libsyntax_pos/lib.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index c96be8fec2b02..7dfe19452a2a9 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -193,6 +193,20 @@ impl MultiSpan { } } + pub fn from_span(primary_span: Span) -> MultiSpan { + MultiSpan { + primary_spans: vec![primary_span], + span_labels: vec![] + } + } + + pub fn from_spans(vec: Vec) -> MultiSpan { + MultiSpan { + primary_spans: vec, + span_labels: vec![] + } + } + pub fn push_span_label(&mut self, span: Span, label: String) { self.span_labels.push((span, label)); } @@ -240,10 +254,7 @@ impl MultiSpan { impl From for MultiSpan { fn from(span: Span) -> MultiSpan { - MultiSpan { - primary_spans: vec![span], - span_labels: vec![] - } + MultiSpan::from_span(span) } } From f459e801fd6cfad61e81ed12e6c364f0776d6ed4 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 28 Jul 2016 22:09:31 -0400 Subject: [PATCH 19/21] Rewrite `collections::LinkedList::append` doc example. --- src/libcollections/linked_list.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 3d5c3125fae24..6842f02e0e19b 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -203,19 +203,22 @@ impl LinkedList { /// ``` /// use std::collections::LinkedList; /// - /// let mut a = LinkedList::new(); - /// let mut b = LinkedList::new(); - /// a.push_back(1); - /// a.push_back(2); - /// b.push_back(3); - /// b.push_back(4); + /// let mut list1 = LinkedList::new(); + /// list1.push_back('a'); /// - /// a.append(&mut b); + /// let mut list2 = LinkedList::new(); + /// list2.push_back('b'); + /// list2.push_back('c'); /// - /// for e in &a { - /// println!("{}", e); // prints 1, then 2, then 3, then 4 - /// } - /// println!("{}", b.len()); // prints 0 + /// list1.append(&mut list2); + /// + /// let mut iter = list1.iter(); + /// assert_eq!(iter.next(), Some(&'a')); + /// assert_eq!(iter.next(), Some(&'b')); + /// assert_eq!(iter.next(), Some(&'c')); + /// assert!(iter.next().is_none()); + /// + /// assert!(list2.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn append(&mut self, other: &mut Self) { From 2a41b31a88356d5a772cb644ab8d29af0bf44742 Mon Sep 17 00:00:00 2001 From: Wang Xuerui Date: Fri, 29 Jul 2016 16:40:10 +0800 Subject: [PATCH 20/21] syntax_ext: format: fix ICE with bad named arguments --- src/libsyntax_ext/format.rs | 4 +++- src/test/compile-fail/ifmt-bad-arg.rs | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 94bb78edaacdb..1f6f57c70f72f 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -406,7 +406,9 @@ impl<'a, 'b> Context<'a, 'b> { let arg_idx = match arg_index_consumed.get_mut(i) { None => 0, // error already emitted elsewhere Some(offset) => { - let arg_idx = self.arg_index_map[i][*offset]; + let ref idx_map = self.arg_index_map[i]; + // unwrap_or branch: error already emitted elsewhere + let arg_idx = *idx_map.get(*offset).unwrap_or(&0); *offset += 1; arg_idx } diff --git a/src/test/compile-fail/ifmt-bad-arg.rs b/src/test/compile-fail/ifmt-bad-arg.rs index 272ad980feb46..59c61a42e077f 100644 --- a/src/test/compile-fail/ifmt-bad-arg.rs +++ b/src/test/compile-fail/ifmt-bad-arg.rs @@ -41,6 +41,12 @@ fn main() { //~^ ERROR invalid reference to argument `0` (no arguments given) //~^^ ERROR invalid reference to argument `1` (no arguments given) + // bad named arguments, #35082 + + format!("{valuea} {valueb}", valuea=5, valuec=7); + //~^ ERROR there is no argument named `valueb` + //~^^ ERROR named argument never used + // bad syntax of the format string format!("{"); //~ ERROR: expected `'}'` but string was terminated From 415fde498a561f22eb7e431b31a31906764a196b Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 28 Jul 2016 05:58:45 -0400 Subject: [PATCH 21/21] intravisit: Fold functionality of IdVisitor into the regular Visitor. --- src/librustc/hir/intravisit.rs | 255 ++++++---------------- src/librustc/hir/map/collector.rs | 2 +- src/librustc/hir/mod.rs | 6 +- src/librustc/lint/context.rs | 36 ++- src/librustc/middle/cstore.rs | 7 +- src/librustc/middle/effect.rs | 4 +- src/librustc/middle/liveness.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_const_eval/check_match.rs | 10 +- src/librustc_incremental/calculate_svh.rs | 8 +- src/librustc_metadata/astencode.rs | 10 +- src/librustc_mir/mir_map.rs | 2 +- src/librustc_passes/consts.rs | 2 +- src/librustc_passes/rvalues.rs | 2 +- src/librustc_privacy/lib.rs | 2 +- src/librustc_typeck/check/upvar.rs | 2 +- 16 files changed, 119 insertions(+), 233 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 442c85af22a26..a06fc21764de4 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -94,11 +94,14 @@ pub trait Visitor<'v> : Sized { /////////////////////////////////////////////////////////////////////////// + fn visit_id(&mut self, _node_id: NodeId) { + // Nothing to do. + } fn visit_name(&mut self, _span: Span, _name: Name) { // Nothing to do. } - fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { - walk_mod(self, m) + fn visit_mod(&mut self, m: &'v Mod, _s: Span, n: NodeId) { + walk_mod(self, m, n) } fn visit_foreign_item(&mut self, i: &'v ForeignItem) { walk_foreign_item(self, i) @@ -135,8 +138,8 @@ pub trait Visitor<'v> : Sized { fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) { walk_where_predicate(self, predicate) } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) { - walk_fn(self, fk, fd, b, s) + fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, id: NodeId) { + walk_fn(self, fk, fd, b, s, id) } fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) @@ -157,7 +160,7 @@ pub trait Visitor<'v> : Sized { s: &'v VariantData, _: Name, _: &'v Generics, - _: NodeId, + _parent_id: NodeId, _: Span) { walk_struct_def(self, s) } @@ -225,24 +228,28 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) { } pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) { + visitor.visit_id(macro_def.id); visitor.visit_name(macro_def.span, macro_def.name); walk_opt_name(visitor, macro_def.span, macro_def.imported_from); walk_list!(visitor, visit_attribute, ¯o_def.attrs); } -pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) { +pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_node_id: NodeId) { + visitor.visit_id(mod_node_id); for &item_id in &module.item_ids { visitor.visit_nested_item(item_id); } } pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { + visitor.visit_id(local.id); visitor.visit_pat(&local.pat); walk_list!(visitor, visit_ty, &local.ty); walk_list!(visitor, visit_expr, &local.init); } pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { + visitor.visit_id(lifetime.id); visitor.visit_name(lifetime.span, lifetime.name); } @@ -263,6 +270,7 @@ pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef) where V: Visitor<'v> { + visitor.visit_id(trait_ref.ref_id); visitor.visit_path(&trait_ref.path, trait_ref.ref_id) } @@ -271,9 +279,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_name(item.span, item.name); match item.node { ItemExternCrate(opt_name) => { + visitor.visit_id(item.id); walk_opt_name(visitor, item.span, opt_name) } ItemUse(ref vp) => { + visitor.visit_id(item.id); match vp.node { ViewPathSimple(name, ref path) => { visitor.visit_name(vp.span, name); @@ -292,6 +302,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { } ItemStatic(ref typ, _, ref expr) | ItemConst(ref typ, ref expr) => { + visitor.visit_id(item.id); visitor.visit_ty(typ); visitor.visit_expr(expr); } @@ -309,23 +320,29 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { item.id) } ItemMod(ref module) => { + // visit_mod() takes care of visiting the Item's NodeId visitor.visit_mod(module, item.span, item.id) } ItemForeignMod(ref foreign_module) => { + visitor.visit_id(item.id); walk_list!(visitor, visit_foreign_item, &foreign_module.items); } ItemTy(ref typ, ref type_parameters) => { + visitor.visit_id(item.id); visitor.visit_ty(typ); visitor.visit_generics(type_parameters) } ItemEnum(ref enum_definition, ref type_parameters) => { visitor.visit_generics(type_parameters); + // visit_enum_def() takes care of visiting the Item's NodeId visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span) } ItemDefaultImpl(_, ref trait_ref) => { + visitor.visit_id(item.id); visitor.visit_trait_ref(trait_ref) } ItemImpl(_, _, ref type_parameters, ref opt_trait_reference, ref typ, ref impl_items) => { + visitor.visit_id(item.id); visitor.visit_generics(type_parameters); walk_list!(visitor, visit_trait_ref, opt_trait_reference); visitor.visit_ty(typ); @@ -333,9 +350,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { } ItemStruct(ref struct_definition, ref generics) => { visitor.visit_generics(generics); + visitor.visit_id(item.id); visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span); } ItemTrait(_, ref generics, ref bounds, ref methods) => { + visitor.visit_id(item.id); visitor.visit_generics(generics); walk_list!(visitor, visit_ty_param_bound, bounds); walk_list!(visitor, visit_trait_item, methods); @@ -348,6 +367,7 @@ pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, enum_definition: &'v EnumDef, generics: &'v Generics, item_id: NodeId) { + visitor.visit_id(item_id); walk_list!(visitor, visit_variant, &enum_definition.variants, @@ -358,18 +378,20 @@ pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant, generics: &'v Generics, - item_id: NodeId) { + parent_item_id: NodeId) { visitor.visit_name(variant.span, variant.node.name); visitor.visit_variant_data(&variant.node.data, variant.node.name, generics, - item_id, + parent_item_id, variant.span); walk_list!(visitor, visit_expr, &variant.node.disr_expr); walk_list!(visitor, visit_attribute, &variant.node.attrs); } pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { + visitor.visit_id(typ.id); + match typ.node { TyVec(ref ty) => { visitor.visit_ty(ty) @@ -421,6 +443,7 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V, _prefix: &'v Path, item: &'v PathListItem) { + visitor.visit_id(item.node.id()); walk_opt_name(visitor, item.span, item.node.name()); walk_opt_name(visitor, item.span, item.node.rename()); } @@ -450,11 +473,13 @@ pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, type_binding: &'v TypeBinding) { + visitor.visit_id(type_binding.id); visitor.visit_name(type_binding.span, type_binding.name); visitor.visit_ty(&type_binding.ty); } pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { + visitor.visit_id(pattern.id); match pattern.node { PatKind::TupleStruct(ref path, ref children, _) => { visitor.visit_path(path, pattern.id); @@ -499,6 +524,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { } pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) { + visitor.visit_id(foreign_item.id); visitor.visit_vis(&foreign_item.vis); visitor.visit_name(foreign_item.span, foreign_item.name); @@ -526,11 +552,13 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyPar pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) { for param in &generics.ty_params { + visitor.visit_id(param.id); visitor.visit_name(param.span, param.name); walk_list!(visitor, visit_ty_param_bound, ¶m.bounds); walk_list!(visitor, visit_ty, ¶m.default); } walk_list!(visitor, visit_lifetime_def, &generics.lifetimes); + visitor.visit_id(generics.where_clause.id); walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates); } @@ -557,6 +585,7 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>( ref path, ref ty, ..}) => { + visitor.visit_id(id); visitor.visit_path(path, id); visitor.visit_ty(ty); } @@ -571,6 +600,7 @@ pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionR pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { for argument in &function_declaration.inputs { + visitor.visit_id(argument.id); visitor.visit_pat(&argument.pat); visitor.visit_ty(&argument.ty) } @@ -579,6 +609,7 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: & pub fn walk_fn_decl_nopat<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { for argument in &function_declaration.inputs { + visitor.visit_id(argument.id); visitor.visit_ty(&argument.ty) } walk_fn_ret_ty(visitor, &function_declaration.output) @@ -600,7 +631,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>, function_declaration: &'v FnDecl, function_body: &'v Block, - _span: Span) { + _span: Span, + id: NodeId) { + visitor.visit_id(id); walk_fn_decl(visitor, function_declaration); walk_fn_kind(visitor, function_kind); visitor.visit_block(function_body) @@ -611,10 +644,12 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai walk_list!(visitor, visit_attribute, &trait_item.attrs); match trait_item.node { ConstTraitItem(ref ty, ref default) => { + visitor.visit_id(trait_item.id); visitor.visit_ty(ty); walk_list!(visitor, visit_expr, default); } MethodTraitItem(ref sig, None) => { + visitor.visit_id(trait_item.id); visitor.visit_generics(&sig.generics); walk_fn_decl(visitor, &sig.decl); } @@ -629,6 +664,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai trait_item.id); } TypeTraitItem(ref bounds, ref default) => { + visitor.visit_id(trait_item.id); walk_list!(visitor, visit_ty_param_bound, bounds); walk_list!(visitor, visit_ty, default); } @@ -641,6 +677,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt walk_list!(visitor, visit_attribute, &impl_item.attrs); match impl_item.node { ImplItemKind::Const(ref ty, ref expr) => { + visitor.visit_id(impl_item.id); visitor.visit_ty(ty); visitor.visit_expr(expr); } @@ -655,16 +692,19 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt impl_item.id); } ImplItemKind::Type(ref ty) => { + visitor.visit_id(impl_item.id); visitor.visit_ty(ty); } } } pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) { + visitor.visit_id(struct_definition.id()); walk_list!(visitor, visit_struct_field, struct_definition.fields()); } pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) { + visitor.visit_id(struct_field.id); visitor.visit_vis(&struct_field.vis); visitor.visit_name(struct_field.span, struct_field.name); visitor.visit_ty(&struct_field.ty); @@ -672,14 +712,20 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v } pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { + visitor.visit_id(block.id); walk_list!(visitor, visit_stmt, &block.stmts); walk_list!(visitor, visit_expr, &block.expr); } pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { match statement.node { - StmtDecl(ref declaration, _) => visitor.visit_decl(declaration), - StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => { + StmtDecl(ref declaration, id) => { + visitor.visit_id(id); + visitor.visit_decl(declaration) + } + StmtExpr(ref expression, id) | + StmtSemi(ref expression, id) => { + visitor.visit_id(id); visitor.visit_expr(expression) } } @@ -693,6 +739,7 @@ pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) { } pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { + visitor.visit_id(expression.id); match expression.node { ExprBox(ref subexpression) => { visitor.visit_expr(subexpression) @@ -815,6 +862,7 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) { if let Visibility::Restricted { ref path, id } = *vis { + visitor.visit_id(id); visitor.visit_path(path, id) } } @@ -837,15 +885,16 @@ impl IdRange { self.min >= self.max } + pub fn contains(&self, id: NodeId) -> bool { + id >= self.min && id < self.max + } + pub fn add(&mut self, id: NodeId) { self.min = cmp::min(self.min, id); self.max = cmp::max(self.max, id + 1); } } -pub trait IdVisitingOperation { - fn visit_id(&mut self, node_id: NodeId); -} pub struct IdRangeComputingVisitor { pub result: IdRange, @@ -861,181 +910,12 @@ impl IdRangeComputingVisitor { } } -impl IdVisitingOperation for IdRangeComputingVisitor { +impl<'v> Visitor<'v> for IdRangeComputingVisitor { fn visit_id(&mut self, id: NodeId) { self.result.add(id); } } -pub struct IdVisitor<'a, O: 'a> { - operation: &'a mut O, - - // In general, the id visitor visits the contents of an item, but - // not including nested trait/impl items, nor other nested items. - // The base visitor itself always skips nested items, but not - // trait/impl items. This means in particular that if you start by - // visiting a trait or an impl, you should not visit the - // trait/impl items respectively. This is handled by setting - // `skip_members` to true when `visit_item` is on the stack. This - // way, if the user begins by calling `visit_trait_item`, we will - // visit the trait item, but if they begin with `visit_item`, we - // won't visit the (nested) trait items. - skip_members: bool, -} - -impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> { - pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> { - IdVisitor { operation: operation, skip_members: false } - } - - fn visit_generics_helper(&mut self, generics: &Generics) { - for type_parameter in generics.ty_params.iter() { - self.operation.visit_id(type_parameter.id) - } - for lifetime in &generics.lifetimes { - self.operation.visit_id(lifetime.lifetime.id) - } - } -} - -impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { - fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) { - self.operation.visit_id(node_id); - walk_mod(self, module) - } - - fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { - self.operation.visit_id(foreign_item.id); - walk_foreign_item(self, foreign_item) - } - - fn visit_item(&mut self, item: &Item) { - assert!(!self.skip_members); - self.skip_members = true; - - self.operation.visit_id(item.id); - match item.node { - ItemUse(ref view_path) => { - match view_path.node { - ViewPathSimple(_, _) | - ViewPathGlob(_) => {} - ViewPathList(_, ref paths) => { - for path in paths { - self.operation.visit_id(path.node.id()) - } - } - } - } - _ => {} - } - walk_item(self, item); - - self.skip_members = false; - } - - fn visit_local(&mut self, local: &Local) { - self.operation.visit_id(local.id); - walk_local(self, local) - } - - fn visit_block(&mut self, block: &Block) { - self.operation.visit_id(block.id); - walk_block(self, block) - } - - fn visit_stmt(&mut self, statement: &Stmt) { - self.operation.visit_id(statement.node.id()); - walk_stmt(self, statement) - } - - fn visit_pat(&mut self, pattern: &Pat) { - self.operation.visit_id(pattern.id); - walk_pat(self, pattern) - } - - fn visit_expr(&mut self, expression: &Expr) { - self.operation.visit_id(expression.id); - walk_expr(self, expression) - } - - fn visit_ty(&mut self, typ: &Ty) { - self.operation.visit_id(typ.id); - walk_ty(self, typ) - } - - fn visit_generics(&mut self, generics: &Generics) { - self.visit_generics_helper(generics); - walk_generics(self, generics) - } - - fn visit_fn(&mut self, - function_kind: FnKind<'v>, - function_declaration: &'v FnDecl, - block: &'v Block, - span: Span, - node_id: NodeId) { - self.operation.visit_id(node_id); - - match function_kind { - FnKind::ItemFn(_, generics, _, _, _, _, _) => { - self.visit_generics_helper(generics) - } - FnKind::Method(_, sig, _, _) => { - self.visit_generics_helper(&sig.generics) - } - FnKind::Closure(_) => {} - } - - for argument in &function_declaration.inputs { - self.operation.visit_id(argument.id) - } - - walk_fn(self, function_kind, function_declaration, block, span); - } - - fn visit_struct_field(&mut self, struct_field: &StructField) { - self.operation.visit_id(struct_field.id); - walk_struct_field(self, struct_field) - } - - fn visit_variant_data(&mut self, - struct_def: &VariantData, - _: Name, - _: &Generics, - _: NodeId, - _: Span) { - self.operation.visit_id(struct_def.id()); - walk_struct_def(self, struct_def); - } - - fn visit_trait_item(&mut self, ti: &TraitItem) { - if !self.skip_members { - self.operation.visit_id(ti.id); - walk_trait_item(self, ti); - } - } - - fn visit_impl_item(&mut self, ii: &ImplItem) { - if !self.skip_members { - self.operation.visit_id(ii.id); - walk_impl_item(self, ii); - } - } - - fn visit_lifetime(&mut self, lifetime: &Lifetime) { - self.operation.visit_id(lifetime.id); - } - - fn visit_lifetime_def(&mut self, def: &LifetimeDef) { - self.visit_lifetime(&def.lifetime); - } - - fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { - self.operation.visit_id(trait_ref.ref_id); - walk_trait_ref(self, trait_ref); - } -} - /// Computes the id range for a single fn body, ignoring nested items. pub fn compute_id_range_for_fn_body(fk: FnKind, decl: &FnDecl, @@ -1043,8 +923,7 @@ pub fn compute_id_range_for_fn_body(fk: FnKind, sp: Span, id: NodeId) -> IdRange { - let mut visitor = IdRangeComputingVisitor { result: IdRange::max() }; - let mut id_visitor = IdVisitor::new(&mut visitor); - id_visitor.visit_fn(fk, decl, body, sp, id); - id_visitor.operation.result + let mut visitor = IdRangeComputingVisitor::new(); + visitor.visit_fn(fk, decl, body, sp, id); + visitor.result() } diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 693d7a2edfca5..b3f222b22e891 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -197,7 +197,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, b: &'ast Block, s: Span, id: NodeId) { assert_eq!(self.parent_node, id); - intravisit::walk_fn(self, fk, fd, b, s); + intravisit::walk_fn(self, fk, fd, b, s, id); } fn visit_block(&mut self, block: &'ast Block) { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 655f80ec07238..20bf4f7d3edbb 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1362,9 +1362,9 @@ pub enum ViewPath_ { /// TraitRef's appear in impls. /// /// resolve maps each TraitRef's ref_id to its defining trait; that's all -/// that the ref_id is for. The impl_id maps to the "self type" of this impl. -/// If this impl is an ItemImpl, the impl_id is redundant (it could be the -/// same as the impl's node id). +/// that the ref_id is for. Note that ref_id's value is not the NodeId of the +/// trait being referred to but just a unique NodeId that serves as a key +/// within the DefMap. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct TraitRef { pub path: Path, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index ce3d72de9ae99..a55957c4d193e 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -45,7 +45,6 @@ use syntax_pos::Span; use errors::DiagnosticBuilder; use hir; use hir::intravisit as hir_visit; -use hir::intravisit::{IdVisitor, IdVisitingOperation}; use syntax::visit as ast_visit; /// Information about the registered lints. @@ -663,9 +662,11 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { } fn visit_ids(&mut self, f: F) - where F: FnOnce(&mut IdVisitor) + where F: FnOnce(&mut IdVisitor) { - let mut v = IdVisitor::new(self); + let mut v = IdVisitor { + cx: self + }; f(&mut v); } } @@ -779,7 +780,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> { fn visit_fn(&mut self, fk: hir_visit::FnKind<'v>, decl: &'v hir::FnDecl, body: &'v hir::Block, span: Span, id: ast::NodeId) { run_lints!(self, check_fn, late_passes, fk, decl, body, span, id); - hir_visit::walk_fn(self, fk, decl, body, span); + hir_visit::walk_fn(self, fk, decl, body, span, id); run_lints!(self, check_fn_post, late_passes, fk, decl, body, span, id); } @@ -820,7 +821,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> { fn visit_mod(&mut self, m: &hir::Mod, s: Span, n: ast::NodeId) { run_lints!(self, check_mod, late_passes, m, s, n); - hir_visit::walk_mod(self, m); + hir_visit::walk_mod(self, m, n); run_lints!(self, check_mod_post, late_passes, m, s, n); } @@ -859,7 +860,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) { self.with_lint_attrs(&trait_item.attrs, |cx| { run_lints!(cx, check_trait_item, late_passes, trait_item); - cx.visit_ids(|v| v.visit_trait_item(trait_item)); + cx.visit_ids(|v| hir_visit::walk_trait_item(v, trait_item)); hir_visit::walk_trait_item(cx, trait_item); run_lints!(cx, check_trait_item_post, late_passes, trait_item); }); @@ -868,7 +869,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) { self.with_lint_attrs(&impl_item.attrs, |cx| { run_lints!(cx, check_impl_item, late_passes, impl_item); - cx.visit_ids(|v| v.visit_impl_item(impl_item)); + cx.visit_ids(|v| hir_visit::walk_impl_item(v, impl_item)); hir_visit::walk_impl_item(cx, impl_item); run_lints!(cx, check_impl_item_post, late_passes, impl_item); }); @@ -1046,16 +1047,30 @@ impl<'a> ast_visit::Visitor for EarlyContext<'a> { } } +struct IdVisitor<'a, 'b: 'a, 'tcx: 'a+'b> { + cx: &'a mut LateContext<'b, 'tcx> +} + // Output any lints that were previously added to the session. -impl<'a, 'tcx> IdVisitingOperation for LateContext<'a, 'tcx> { +impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> { + fn visit_id(&mut self, id: ast::NodeId) { - if let Some(lints) = self.sess().lints.borrow_mut().remove(&id) { + if let Some(lints) = self.cx.sess().lints.borrow_mut().remove(&id) { debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints); for (lint_id, span, msg) in lints { - self.span_lint(lint_id.lint, span, &msg[..]) + self.cx.span_lint(lint_id.lint, span, &msg[..]) } } } + + fn visit_trait_item(&mut self, _ti: &hir::TraitItem) { + // Do not recurse into trait or impl items automatically. These are + // processed separately by calling hir_visit::walk_trait_item() + } + + fn visit_impl_item(&mut self, _ii: &hir::ImplItem) { + // See visit_trait_item() + } } enum CheckLintNameResult { @@ -1172,7 +1187,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Visit the whole crate. cx.with_lint_attrs(&krate.attrs, |cx| { - cx.visit_id(ast::CRATE_NODE_ID); cx.visit_ids(|v| { hir_visit::walk_crate(v, krate); }); diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index fd9463b13c055..484aacfd9ecc0 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -44,7 +44,7 @@ use syntax::parse::token::InternedString; use syntax_pos::Span; use rustc_back::target::Target; use hir; -use hir::intravisit::{IdVisitor, IdVisitingOperation, Visitor}; +use hir::intravisit::Visitor; pub use self::DefLike::{DlDef, DlField, DlImpl}; pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown}; @@ -292,11 +292,6 @@ impl InlinedItem { InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii), } } - - pub fn visit_ids(&self, operation: &mut O) { - let mut id_visitor = IdVisitor::new(operation); - self.visit(&mut id_visitor); - } } // FIXME: find a better place for this? diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 6fe98119c7060..446767ecbcaba 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -79,7 +79,7 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> { impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl, - block: &'v hir::Block, span: Span, _: ast::NodeId) { + block: &'v hir::Block, span: Span, id: ast::NodeId) { let (is_item_fn, is_unsafe_fn) = match fn_kind { FnKind::ItemFn(_, _, unsafety, _, _, _, _) => @@ -96,7 +96,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { self.unsafe_context = UnsafeContext::new(SafeContext) } - intravisit::walk_fn(self, fn_kind, fn_decl, block, span); + intravisit::walk_fn(self, fn_kind, fn_decl, block, span, id); self.unsafe_context = old_unsafe_context } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index ea3765c76f89b..1222b5f42a19f 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -390,7 +390,7 @@ fn visit_fn(ir: &mut IrMaps, // gather up the various local variables, significant expressions, // and so forth: - intravisit::walk_fn(&mut fn_maps, fk, decl, body, sp); + intravisit::walk_fn(&mut fn_maps, fk, decl, body, sp, id); // Special nodes and variables: // - exit_ln represents the end of the fn, either by return or panic diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index e86120b73bf97..1fe47cd485387 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -197,7 +197,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt, decl, body); - intravisit::walk_fn(this, fk, decl, body, sp); + intravisit::walk_fn(this, fk, decl, body, sp, id); } fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 915a0cf0bdc73..d3952de2fbe30 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -34,7 +34,7 @@ use std::iter::{FromIterator, IntoIterator, repeat}; use rustc::hir; use rustc::hir::{Pat, PatKind}; -use rustc::hir::intravisit::{self, IdVisitor, IdVisitingOperation, Visitor, FnKind}; +use rustc::hir::intravisit::{self, Visitor, FnKind}; use rustc_back::slice; use syntax::ast::{self, DUMMY_NODE_ID, NodeId}; @@ -474,7 +474,7 @@ struct RenamingRecorder<'map> { renaming_map: &'map mut FnvHashMap<(NodeId, Span), NodeId> } -impl<'map> IdVisitingOperation for RenamingRecorder<'map> { +impl<'v, 'map> Visitor<'v> for RenamingRecorder<'map> { fn visit_id(&mut self, node_id: NodeId) { let key = (node_id, self.origin_span); self.renaming_map.insert(key, self.substituted_node_id); @@ -529,9 +529,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { renaming_map: renaming_map, }; - let mut id_visitor = IdVisitor::new(&mut renaming_recorder); - - id_visitor.visit_expr(const_expr); + renaming_recorder.visit_expr(const_expr); } } } @@ -1049,7 +1047,7 @@ fn check_fn(cx: &mut MatchCheckCtxt, _ => cx.param_env = ParameterEnvironment::for_item(cx.tcx, fn_id), } - intravisit::walk_fn(cx, kind, decl, body, sp); + intravisit::walk_fn(cx, kind, decl, body, sp, fn_id); for input in &decl.inputs { check_irrefutable(cx, &input.pat, true); diff --git a/src/librustc_incremental/calculate_svh.rs b/src/librustc_incremental/calculate_svh.rs index 7b1e0d2d0c8b6..f9fa5154e20f3 100644 --- a/src/librustc_incremental/calculate_svh.rs +++ b/src/librustc_incremental/calculate_svh.rs @@ -384,9 +384,9 @@ mod svh_visitor { SawItem.hash(self.st); visit::walk_item(self, i) } - fn visit_mod(&mut self, m: &'a Mod, _s: Span, _n: NodeId) { + fn visit_mod(&mut self, m: &'a Mod, _s: Span, n: NodeId) { debug!("visit_mod: st={:?}", self.st); - SawMod.hash(self.st); visit::walk_mod(self, m) + SawMod.hash(self.st); visit::walk_mod(self, m, n) } fn visit_decl(&mut self, d: &'a Decl) { @@ -405,9 +405,9 @@ mod svh_visitor { } fn visit_fn(&mut self, fk: FnKind<'a>, fd: &'a FnDecl, - b: &'a Block, s: Span, _: NodeId) { + b: &'a Block, s: Span, n: NodeId) { debug!("visit_fn: st={:?}", self.st); - SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s) + SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, n) } fn visit_trait_item(&mut self, ti: &'a TraitItem) { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 2e8c5a7c23418..454c805ab577e 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -18,7 +18,7 @@ use rustc::session::Session; use rustc::hir; use rustc::hir::fold; use rustc::hir::fold::Folder; -use rustc::hir::intravisit::{IdRange, IdRangeComputingVisitor, IdVisitingOperation}; +use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange}; use common as c; use cstore; @@ -693,7 +693,7 @@ struct SideTableEncodingIdVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { rbml_w: &'a mut Encoder<'b>, } -impl<'a, 'b, 'c, 'tcx> IdVisitingOperation for +impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'c, 'tcx> { fn visit_id(&mut self, id: ast::NodeId) { encode_side_tables_for_id(self.ecx, self.rbml_w, id) @@ -704,7 +704,7 @@ fn encode_side_tables_for_ii(ecx: &e::EncodeContext, rbml_w: &mut Encoder, ii: &InlinedItem) { rbml_w.start_tag(c::tag_table as usize); - ii.visit_ids(&mut SideTableEncodingIdVisitor { + ii.visit(&mut SideTableEncodingIdVisitor { ecx: ecx, rbml_w: rbml_w }); @@ -1242,9 +1242,9 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) { } } -fn inlined_item_id_range(v: &InlinedItem) -> IdRange { +fn inlined_item_id_range(ii: &InlinedItem) -> IdRange { let mut visitor = IdRangeComputingVisitor::new(); - v.visit_ids(&mut visitor); + ii.visit(&mut visitor); visitor.result() } diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index b7c5f35892b0b..11d6b0779275e 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { build::construct_fn(cx, id, arguments, fn_sig.output, body) }); - intravisit::walk_fn(self, fk, decl, body, span); + intravisit::walk_fn(self, fk, decl, body, span, id); } } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index b0ba38f1db673..1030a4b0116de 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -158,7 +158,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { let qualif = self.with_mode(mode, |this| { this.with_euv(Some(fn_id), |euv| euv.walk_fn(fd, b)); - intravisit::walk_fn(this, fk, fd, b, s); + intravisit::walk_fn(this, fk, fd, b, s, fn_id); this.qualif }); diff --git a/src/librustc_passes/rvalues.rs b/src/librustc_passes/rvalues.rs index 4684683f02501..2a5dc50cae92f 100644 --- a/src/librustc_passes/rvalues.rs +++ b/src/librustc_passes/rvalues.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for RvalueContext<'a, 'tcx> { let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); }); - intravisit::walk_fn(self, fk, fd, b, s) + intravisit::walk_fn(self, fk, fd, b, s, fn_id) } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index acaf9b9b2faee..793e52d379203 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -291,7 +291,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { } } - intravisit::walk_mod(self, m); + intravisit::walk_mod(self, m, id); } fn visit_macro_def(&mut self, md: &'v hir::MacroDef) { diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 702dd5f8de58a..6fdbc3282bccd 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -503,7 +503,7 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for AdjustBorrowKind<'a, 'gcx, 'tcx> { span: Span, id: ast::NodeId) { - intravisit::walk_fn(self, fn_kind, decl, body, span); + intravisit::walk_fn(self, fn_kind, decl, body, span, id); self.analyze_closure(id, span, decl, body); } }