diff --git a/src/Cargo.lock b/src/Cargo.lock index abe736a4fe6..52314b0ac89 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -204,7 +204,7 @@ dependencies = [ "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -737,7 +737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "flate2" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -959,7 +959,7 @@ version = "0.0.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1649,7 +1649,7 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.6" +version = "2.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1797,7 +1797,7 @@ dependencies = [ "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1814,6 +1814,7 @@ dependencies = [ "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1889,7 +1890,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2133,7 +2134,7 @@ dependencies = [ name = "rustc_codegen_utils" version = "0.0.0" dependencies = [ - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_data_structures 0.0.0", @@ -2276,7 +2277,7 @@ dependencies = [ name = "rustc_metadata" version = "0.0.0" dependencies = [ - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", "rustc 0.0.0", @@ -3222,7 +3223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" -"checksum flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37847f133aae7acf82bb9577ccd8bda241df836787642654286e79679826a54b" +"checksum flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4af030962d89d62aa52cd9492083b1cd9b2d1a77764878102a6c0f86b4d5444d" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" @@ -3319,7 +3320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" -"checksum racer 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "99e820b7f7701c834c3f6f8226f388c19c0ea948a3ef79ddc96aa7398b5ba87a" +"checksum racer 2.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0beefbfaed799c3554021a48856113ad53862311395f6d75376192884ba5fbe6" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c25f94357f2..cf79d4f777a 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1263,14 +1263,16 @@ impl Step for Clippy { builder.install(&cargoclippy, &image.join("bin"), 0o755); let doc = image.join("share/doc/clippy"); builder.install(&src.join("README.md"), &doc, 0o644); - builder.install(&src.join("LICENSE"), &doc, 0o644); + builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); + builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); // Prepare the overlay let overlay = tmp.join("clippy-overlay"); drop(fs::remove_dir_all(&overlay)); t!(fs::create_dir_all(&overlay)); builder.install(&src.join("README.md"), &overlay, 0o644); - builder.install(&src.join("LICENSE"), &doc, 0o644); + builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); + builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); builder.create(&overlay.join("version"), &version); // Generate the installer tarball diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 247727762d1..c09de02ab51 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1288,6 +1288,9 @@ impl Build { t!(fs::create_dir_all(dstdir)); drop(fs::remove_file(&dst)); { + if !src.exists() { + panic!("Error: File \"{}\" not found!", src.display()); + } let mut s = t!(fs::File::open(&src)); let mut d = t!(fs::File::create(&dst)); io::copy(&mut s, &mut d).expect("failed to copy"); diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index b49ec0ae252..a2e68a223f1 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -152,7 +152,7 @@ //! Additionally, the return value of this function is [`fmt::Result`] which is a //! type alias of [`Result`]`<(), `[`std::fmt::Error`]`>`. Formatting implementations //! should ensure that they propagate errors from the [`Formatter`][`Formatter`] (e.g., when -//! calling [`write!`]) however, they should never return errors spuriously. That +//! calling [`write!`]). However, they should never return errors spuriously. That //! is, a formatting implementation must and may only return an error if the //! passed-in [`Formatter`] returns an error. This is because, contrary to what //! the function signature might suggest, string formatting is an infallible diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 915b8e7787e..40bb2faa362 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -867,7 +867,7 @@ impl Clone for Rc { /// /// let five = Rc::new(5); /// - /// Rc::clone(&five); + /// let _ = Rc::clone(&five); /// ``` #[inline] fn clone(&self) -> Rc { @@ -1304,7 +1304,7 @@ impl Clone for Weak { /// /// let weak_five = Rc::downgrade(&Rc::new(5)); /// - /// Weak::clone(&weak_five); + /// let _ = Weak::clone(&weak_five); /// ``` #[inline] fn clone(&self) -> Weak { diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 9e245fbd7bb..35935861fb1 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -713,7 +713,7 @@ impl Clone for Arc { /// /// let five = Arc::new(5); /// - /// Arc::clone(&five); + /// let _ = Arc::clone(&five); /// ``` #[inline] fn clone(&self) -> Arc { @@ -1135,7 +1135,7 @@ impl Clone for Weak { /// /// let weak_five = Arc::downgrade(&Arc::new(5)); /// - /// Weak::clone(&weak_five); + /// let _ = Weak::clone(&weak_five); /// ``` #[inline] fn clone(&self) -> Weak { diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 7add8ef05ee..817e9ffcbb5 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -418,9 +418,7 @@ fn fundamental_ty(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool { match ty.sty { ty::Ref(..) => true, ty::Adt(def, _) => def.is_fundamental(), - ty::Dynamic(ref data, ..) => { - data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental")) - } + ty::Dynamic(ref data, ..) => tcx.has_attr(data.principal().def_id(), "fundamental"), _ => false } } @@ -467,11 +465,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool { ty::Adt(def, _) => def_id_is_local(def.did, in_crate), ty::Foreign(did) => def_id_is_local(did, in_crate), - ty::Dynamic(ref tt, ..) => { - tt.principal().map_or(false, |p| - def_id_is_local(p.def_id(), in_crate) - ) - } + ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate), ty::Error => true, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 82d881e10b1..8e8024e51da 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2088,10 +2088,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return; } - match data.principal() { - Some(p) => p.with_self_ty(this.tcx(), self_ty), - None => return, - } + data.principal().with_self_ty(this.tcx(), self_ty) } ty::Infer(ty::TyVar(_)) => { debug!("assemble_candidates_from_object_ty: ambiguous"); @@ -2183,15 +2180,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // // We always upcast when we can because of reason // #2 (region bounds). - match (data_a.principal(), data_b.principal()) { - (Some(a), Some(b)) => { - a.def_id() == b.def_id() - && data_b.auto_traits() - // All of a's auto traits need to be in b's auto traits. - .all(|b| data_a.auto_traits().any(|a| a == b)) - } - _ => false, - } + data_a.principal().def_id() == data_b.principal().def_id() + && data_b.auto_traits() + // All of a's auto traits need to be in b's auto traits. + .all(|b| data_a.auto_traits().any(|a| a == b)) } // T -> Trait. @@ -2981,7 +2973,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .shallow_resolve(*obligation.self_ty().skip_binder()); let poly_trait_ref = match self_ty.sty { ty::Dynamic(ref data, ..) => { - data.principal().unwrap().with_self_ty(self.tcx(), self_ty) + data.principal().with_self_ty(self.tcx(), self_ty) } _ => span_bug!(obligation.cause.span, "object candidate with non-object"), }; @@ -3244,10 +3236,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { // See assemble_candidates_for_unsizing for more info. let existential_predicates = data_a.map_bound(|data_a| { - let principal = data_a.principal(); - let iter = principal - .into_iter() - .map(ty::ExistentialPredicate::Trait) + let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal())) .chain( data_a .projection_bounds() @@ -3285,7 +3274,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // T -> Trait. (_, &ty::Dynamic(ref data, r)) => { let mut object_dids = data.auto_traits() - .chain(data.principal().map(|p| p.def_id())); + .chain(iter::once(data.principal().def_id())); if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) { return Err(TraitNotObjectSafe(did)); } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 3123f0fbe31..d886d5ed204 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -208,8 +208,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::FnDef(..) => "fn item".into(), ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) => { - inner.principal().map_or_else(|| "trait".into(), - |p| format!("trait {}", tcx.item_path_str(p.def_id())).into()) + format!("trait {}", tcx.item_path_str(inner.principal().def_id())).into() } ty::Closure(..) => "closure".into(), ty::Generator(..) => "generator".into(), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 0f68e7aba4d..e6aaf8b1bb2 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -78,7 +78,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType), ty::RawPtr(_) => Some(PtrSimplifiedType), ty::Dynamic(ref trait_info, ..) => { - trait_info.principal().map(|p| TraitSimplifiedType(p.def_id())) + Some(TraitSimplifiedType(trait_info.principal().def_id())) } ty::Ref(_, ty, _) => { // since we introduce auto-refs during method lookup, we diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index ab081324036..c4a25971da3 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -436,7 +436,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { match ty.sty { ty::Adt(adt_def, _) => Some(adt_def.did), - ty::Dynamic(data, ..) => data.principal().map(|p| p.def_id()), + ty::Dynamic(data, ..) => Some(data.principal().def_id()), ty::Array(subty, _) | ty::Slice(subty) => characteristic_def_id_of_type(subty), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 145c122e75d..cc6e6b2861e 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -559,10 +559,10 @@ impl<'a, 'gcx, 'tcx> Binder> { impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List> {} impl<'tcx> List> { - pub fn principal(&self) -> Option> { - match self.get(0) { - Some(&ExistentialPredicate::Trait(tr)) => Some(tr), - _ => None, + pub fn principal(&self) -> ExistentialTraitRef<'tcx> { + match self[0] { + ExistentialPredicate::Trait(tr) => tr, + other => bug!("first predicate is {:?}", other), } } @@ -589,8 +589,8 @@ impl<'tcx> List> { } impl<'tcx> Binder<&'tcx List>> { - pub fn principal(&self) -> Option> { - self.skip_binder().principal().map(Binder::bind) + pub fn principal(&self) -> PolyExistentialTraitRef<'tcx> { + Binder::bind(self.skip_binder().principal()) } #[inline] @@ -1825,9 +1825,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } Dynamic(ref obj, region) => { let mut v = vec![region]; - if let Some(p) = obj.principal() { - v.extend(p.skip_binder().substs.regions()); - } + v.extend(obj.principal().skip_binder().substs.regions()); v } Adt(_, substs) | Opaque(_, substs) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 7af838845cd..27747970f76 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { let cause = self.cause(traits::MiscObligation); let component_traits = - data.auto_traits().chain(data.principal().map(|p| p.def_id())); + data.auto_traits().chain(once(data.principal().def_id())); self.out.extend( component_traits.map(|did| traits::Obligation::new( cause.clone(), diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 33534ab27f1..f3b5503b8d0 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -621,16 +621,16 @@ define_print! { // Use a type that can't appear in defaults of type parameters. let dummy_self = tcx.mk_infer(ty::FreshTy(0)); - if let Some(p) = self.principal() { - let principal = tcx.lift(&p).expect("could not lift TraitRef for printing") - .with_self_ty(tcx, dummy_self); - let projections = self.projection_bounds().map(|p| { - tcx.lift(&p) - .expect("could not lift projection for printing") - .with_self_ty(tcx, dummy_self) - }).collect::>(); - cx.parameterized(f, principal.substs, principal.def_id, &projections)?; - } + let principal = tcx + .lift(&self.principal()) + .expect("could not lift TraitRef for printing") + .with_self_ty(tcx, dummy_self); + let projections = self.projection_bounds().map(|p| { + tcx.lift(&p) + .expect("could not lift projection for printing") + .with_self_ty(tcx, dummy_self) + }).collect::>(); + cx.parameterized(f, principal.substs, principal.def_id, &projections)?; // Builtin bounds. for did in self.auto_traits() { diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index c8e8d0dc84e..7b93d3e795e 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -536,7 +536,10 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { // Note that the platform intrinsic ABI is exempt here as // that's how we connect up to LLVM and it's unstable // anyway, we control all calls to it in libstd. - layout::Abi::Vector { .. } if abi != Abi::PlatformIntrinsic => { + layout::Abi::Vector { .. } + if abi != Abi::PlatformIntrinsic && + cx.sess().target.target.options.simd_types_indirect => + { arg.make_indirect(); return } diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 578018c7adc..e6197423738 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -59,7 +59,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> { /// Cache instances of monomorphic and polymorphic items pub instances: RefCell, &'a Value>>, /// Cache generated vtables - pub vtables: RefCell, Option>), + pub vtables: RefCell, ty::PolyExistentialTraitRef<'tcx>), &'a Value>>, /// Cache of constant strings, pub const_cstr_cache: RefCell>, diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 706568b5446..6eff086a2ba 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -435,12 +435,7 @@ fn trait_pointer_metadata( // But it does not describe the trait's methods. let containing_scope = match trait_type.sty { - ty::Dynamic(ref data, ..) => if let Some(principal) = data.principal() { - let def_id = principal.def_id(); - Some(get_namespace_for_item(cx, def_id)) - } else { - NO_SCOPE_METADATA - }, + ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())), _ => { bug!("debuginfo: Unexpected trait-object type in \ trait_pointer_metadata(): {:?}", diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs index 2f110fd552a..06b9318a5e8 100644 --- a/src/librustc_codegen_llvm/debuginfo/type_names.rs +++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs @@ -116,14 +116,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } }, ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - let principal = cx.tcx.normalize_erasing_late_bound_regions( - ty::ParamEnv::reveal_all(), - &principal, - ); - push_item_name(cx, principal.def_id, false, output); - push_type_params(cx, principal.substs, output); - } + let principal = cx.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &trait_data.principal(), + ); + push_item_name(cx, principal.def_id, false, output); + push_type_params(cx, principal.substs, output); }, ty::FnDef(..) | ty::FnPtr(_) => { let sig = t.fn_sig(cx.tcx); diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs index 8a1159bc477..db06b87f44e 100644 --- a/src/librustc_codegen_llvm/meth.rs +++ b/src/librustc_codegen_llvm/meth.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> VirtualIndex { pub fn get_vtable( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, - trait_ref: Option>, + trait_ref: ty::PolyExistentialTraitRef<'tcx>, ) -> &'ll Value { let tcx = cx.tcx; @@ -86,23 +86,19 @@ pub fn get_vtable( // Not in the cache. Build it. let nullptr = C_null(Type::i8p(cx)); + let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty)); + let methods = methods.iter().cloned().map(|opt_mth| { + opt_mth.map_or(nullptr, |(def_id, substs)| { + callee::resolve_and_get_fn(cx, def_id, substs) + }) + }); + let (size, align) = cx.size_and_align_of(ty); - let mut components: Vec<_> = [ + let components: Vec<_> = [ callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)), C_usize(cx, size.bytes()), C_usize(cx, align.abi()) - ].iter().cloned().collect(); - - if let Some(trait_ref) = trait_ref { - let trait_ref = trait_ref.with_self_ty(tcx, ty); - let methods = tcx.vtable_methods(trait_ref); - let methods = methods.iter().cloned().map(|opt_mth| { - opt_mth.map_or(nullptr, |(def_id, substs)| { - callee::resolve_and_get_fn(cx, def_id, substs) - }) - }); - components.extend(methods); - } + ].iter().cloned().chain(methods).collect(); let vtable_const = C_struct(cx, &components, false); let align = cx.data_layout().pointer_align; diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 7fb66ea97f2..b4f95b915eb 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -44,7 +44,7 @@ use serialize::json; use std::any::Any; use std::env; -use std::ffi::{OsStr, OsString}; +use std::ffi::OsString; use std::fs; use std::io::{self, Write}; use std::iter; @@ -1021,6 +1021,7 @@ where .cloned() .collect(); missing_fragment_specifiers.sort(); + for span in missing_fragment_specifiers { let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER; let msg = "missing fragment specifier"; @@ -1472,7 +1473,7 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa .collect(); let mut file = fs::File::create(&deps_filename)?; for path in out_filenames { - write!(file, "{}: {}\n\n", path.display(), files.join(" "))?; + writeln!(file, "{}: {}\n", path.display(), files.join(" "))?; } // Emit a fake target for each input file to the compilation. This @@ -1484,15 +1485,12 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa Ok(()) })(); - match result { - Ok(()) => {} - Err(e) => { - sess.fatal(&format!( - "error writing dependencies to `{}`: {}", - deps_filename.display(), - e - )); - } + if let Err(e) = result { + sess.fatal(&format!( + "error writing dependencies to `{}`: {}", + deps_filename.display(), + e + )); } } @@ -1520,6 +1518,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Vec { + None => { session .struct_span_err(a.span, "`crate_type` requires a value") .note("for example: `#![crate_type=\"lib\"]`") @@ -1581,25 +1580,26 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec CrateDisambiguator { @@ -1650,17 +1650,14 @@ pub fn build_output_filenames( // "-" as input file will cause the parser to read from stdin so we // have to make up a name // We want to toss everything after the final '.' - let dirpath = match *odir { - Some(ref d) => d.clone(), - None => PathBuf::new(), - }; + let dirpath = (*odir).as_ref().cloned().unwrap_or_default(); // If a crate name is present, we use it as the link name let stem = sess.opts .crate_name .clone() .or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string())) - .unwrap_or(input.filestem()); + .unwrap_or_else(|| input.filestem()); OutputFilenames { out_directory: dirpath, @@ -1693,13 +1690,11 @@ pub fn build_output_filenames( sess.warn("ignoring -C extra-filename flag due to -o flag"); } - let cur_dir = Path::new(""); - OutputFilenames { - out_directory: out_file.parent().unwrap_or(cur_dir).to_path_buf(), + out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), out_filestem: out_file .file_stem() - .unwrap_or(OsStr::new("")) + .unwrap_or_default() .to_str() .unwrap() .to_string(), diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 0514bd20c98..276b7290c2e 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -89,6 +89,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use serialize::json::ToJson; use std::any::Any; +use std::borrow::Cow; use std::cmp::max; use std::default::Default; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; @@ -136,9 +137,7 @@ pub mod target_features { codegen_backend: &dyn CodegenBackend) { let tf = Symbol::intern("target_feature"); - for feat in codegen_backend.target_features(sess) { - cfg.insert((tf, Some(feat))); - } + cfg.extend(codegen_backend.target_features(sess).into_iter().map(|feat| (tf, Some(feat)))); if sess.crt_static_feature() { cfg.insert((tf, Some(Symbol::intern("crt-static")))); @@ -152,21 +151,14 @@ pub const EXIT_SUCCESS: isize = 0; /// Exit status code used for compilation failures and invalid flags. pub const EXIT_FAILURE: isize = 1; -const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ - md#bug-reports"; +const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ + md#bug-reports"; -const ICE_REPORT_COMPILER_FLAGS: &'static [&'static str] = &[ - "Z", - "C", - "crate-type", -]; -const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &'static [&'static str] = &[ - "metadata", - "extra-filename", -]; -const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &'static [&'static str] = &[ - "incremental", -]; +const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["Z", "C", "crate-type"]; + +const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"]; + +const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"]; pub fn abort_on_err(result: Result, sess: &Session) -> T { match result { @@ -195,14 +187,16 @@ pub fn run(run_compiler: F) -> isize } None => { let emitter = - errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, - None, - true, - false); + errors::emitter::EmitterWriter::stderr( + errors::ColorConfig::Auto, + None, + true, + false + ); let handler = errors::Handler::with_emitter(true, false, Box::new(emitter)); handler.emit(&MultiSpan::new(), - "aborting due to previous error(s)", - errors::Level::Fatal); + "aborting due to previous error(s)", + errors::Level::Fatal); panic::resume_unwind(Box::new(errors::FatalErrorMarker)); } } @@ -224,15 +218,10 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box { // available for future dynamic libraries opened. This is currently used by // loading LLVM and then making its symbols available for other dynamic // libraries. - let lib = match DynamicLibrary::open_global_now(path) { - Ok(lib) => lib, - Err(err) => { - let err = format!("couldn't load codegen backend {:?}: {:?}", - path, - err); - early_error(ErrorOutputType::default(), &err); - } - }; + let lib = DynamicLibrary::open_global_now(path).unwrap_or_else(|err| { + let err = format!("couldn't load codegen backend {:?}: {:?}", path, err); + early_error(ErrorOutputType::default(), &err); + }); unsafe { match lib.symbol("__rustc_codegen_backend") { Ok(f) => { @@ -328,37 +317,30 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { let sysroot = sysroot_candidates.iter() .map(|sysroot| { let libdir = filesearch::relative_target_lib_path(&sysroot, &target); - sysroot.join(libdir) - .with_file_name(option_env!("CFG_CODEGEN_BACKENDS_DIR") - .unwrap_or("codegen-backends")) + sysroot.join(libdir).with_file_name( + option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends")) }) .filter(|f| { info!("codegen backend candidate: {}", f.display()); f.exists() }) .next(); - let sysroot = match sysroot { - Some(path) => path, - None => { - let candidates = sysroot_candidates.iter() - .map(|p| p.display().to_string()) - .collect::>() - .join("\n* "); - let err = format!("failed to find a `codegen-backends` folder \ - in the sysroot candidates:\n* {}", candidates); - early_error(ErrorOutputType::default(), &err); - } - }; + let sysroot = sysroot.unwrap_or_else(|| { + let candidates = sysroot_candidates.iter() + .map(|p| p.display().to_string()) + .collect::>() + .join("\n* "); + let err = format!("failed to find a `codegen-backends` folder \ + in the sysroot candidates:\n* {}", candidates); + early_error(ErrorOutputType::default(), &err); + }); info!("probing {} for a codegen backend", sysroot.display()); - let d = match sysroot.read_dir() { - Ok(d) => d, - Err(e) => { - let err = format!("failed to load default codegen backend, couldn't \ - read `{}`: {}", sysroot.display(), e); - early_error(ErrorOutputType::default(), &err); - } - }; + let d = sysroot.read_dir().unwrap_or_else(|e| { + let err = format!("failed to load default codegen backend, couldn't \ + read `{}`: {}", sysroot.display(), e); + early_error(ErrorOutputType::default(), &err); + }); let mut file: Option = None; @@ -378,8 +360,8 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { } if let Some(ref prev) = file { let err = format!("duplicate codegen backends found\n\ - first: {}\n\ - second: {}\n\ + first: {}\n\ + second: {}\n\ ", prev.display(), path.display()); early_error(ErrorOutputType::default(), &err); } @@ -391,7 +373,7 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { None => { let err = format!("failed to load default codegen backend for `{}`, \ no appropriate codegen dylib found in `{}`", - backend_name, sysroot.display()); + backend_name, sysroot.display()); early_error(ErrorOutputType::default(), &err); } } @@ -578,7 +560,7 @@ pub fn set_sigpipe_handler() { unsafe { // Set the SIGPIPE signal handler, so that an EPIPE // will cause rustc to terminate, as expected. - assert!(libc::signal(libc::SIGPIPE, libc::SIG_DFL) != libc::SIG_ERR); + assert_ne!(libc::signal(libc::SIGPIPE, libc::SIG_DFL), libc::SIG_ERR); } } @@ -996,7 +978,7 @@ impl RustcDefaultCalls { input: &Input) -> Compilation { let r = matches.opt_strs("Z"); - if r.contains(&("ls".to_string())) { + if r.iter().any(|s| *s == "ls") { match input { &Input::File(ref ifile) => { let path = &(*ifile); @@ -1015,7 +997,7 @@ impl RustcDefaultCalls { return Compilation::Stop; } - return Compilation::Continue; + Compilation::Continue } @@ -1028,7 +1010,7 @@ impl RustcDefaultCalls { use rustc::session::config::PrintRequest::*; // PrintRequest::NativeStaticLibs is special - printed during linking // (empty iterator returns true) - if sess.opts.prints.iter().all(|&p| p==PrintRequest::NativeStaticLibs) { + if sess.opts.prints.iter().all(|&p| p == PrintRequest::NativeStaticLibs) { return Compilation::Continue; } @@ -1055,10 +1037,8 @@ impl RustcDefaultCalls { Sysroot => println!("{}", sess.sysroot().display()), TargetSpec => println!("{}", sess.target.target.to_json().pretty()), FileNames | CrateName => { - let input = match input { - Some(input) => input, - None => early_error(ErrorOutputType::default(), "no input file provided"), - }; + let input = input.unwrap_or_else(|| + early_error(ErrorOutputType::default(), "no input file provided")); let attrs = attrs.as_ref().unwrap(); let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess); let id = rustc_codegen_utils::link::find_crate_name(Some(sess), attrs, input); @@ -1074,18 +1054,14 @@ impl RustcDefaultCalls { &id, &t_outputs ); - println!("{}", - fname.file_name() - .unwrap() - .to_string_lossy()); + println!("{}", fname.file_name().unwrap().to_string_lossy()); } } Cfg => { let allow_unstable_cfg = UnstableFeatures::from_environment() .is_nightly_build(); - let mut cfgs = Vec::new(); - for &(name, ref value) in sess.parse_sess.config.iter() { + let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| { let gated_cfg = GatedCfg::gate(&ast::MetaItem { ident: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)), node: ast::MetaItemKind::Word, @@ -1104,16 +1080,16 @@ impl RustcDefaultCalls { let value = value.as_ref().map(|s| s.as_ref()); if name != "target_feature" || value != Some("crt-static") { if !allow_unstable_cfg && gated_cfg.is_some() { - continue; + return None } } - cfgs.push(if let Some(value) = value { - format!("{}=\"{}\"", name, value) + if let Some(value) = value { + Some(format!("{}=\"{}\"", name, value)) } else { - name.to_string() - }); - } + Some(name.to_string()) + } + }).collect::>(); cfgs.sort(); for cfg in cfgs { @@ -1150,9 +1126,8 @@ fn commit_date_str() -> Option<&'static str> { pub fn version(binary: &str, matches: &getopts::Matches) { let verbose = matches.opt_present("verbose"); - println!("{} {}", - binary, - option_env!("CFG_VERSION").unwrap_or("unknown version")); + println!("{} {}", binary, option_env!("CFG_VERSION").unwrap_or("unknown version")); + if verbose { fn unw(x: Option<&str>) -> &str { x.unwrap_or("unknown") @@ -1176,7 +1151,7 @@ fn usage(verbose: bool, include_unstable_options: bool) { for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) { (option.apply)(&mut options); } - let message = "Usage: rustc [OPTIONS] INPUT".to_string(); + let message = "Usage: rustc [OPTIONS] INPUT"; let nightly_help = if nightly_options::is_nightly_build() { "\n -Z help Print internal options for debugging rustc" } else { @@ -1191,7 +1166,7 @@ fn usage(verbose: bool, include_unstable_options: bool) { -C help Print codegen options -W help \ Print 'lint' options and default settings{}{}\n", - options.usage(&message), + options.usage(message), nightly_help, verbose_help); } @@ -1273,8 +1248,6 @@ Available lint options: print_lints(builtin); - - let max_name_len = max("warnings".len(), plugin_groups.iter() .chain(&builtin_groups) @@ -1407,10 +1380,8 @@ pub fn handle_options(args: &[String]) -> Option { for option in config::rustc_optgroups() { (option.apply)(&mut options); } - let matches = match options.parse(args) { - Ok(m) => m, - Err(f) => early_error(ErrorOutputType::default(), &f.to_string()), - }; + let matches = options.parse(args).unwrap_or_else(|f| + early_error(ErrorOutputType::default(), &f.to_string())); // For all options we just parsed, we check a few aspects: // @@ -1452,6 +1423,7 @@ pub fn handle_options(args: &[String]) -> Option { } let cg_flags = matches.opt_strs("C"); + if cg_flags.iter().any(|x| *x == "help") { describe_codegen_flags(); return None; @@ -1462,7 +1434,7 @@ pub fn handle_options(args: &[String]) -> Option { "the --no-stack-check flag is deprecated and does nothing"); } - if cg_flags.contains(&"passes=list".to_string()) { + if cg_flags.iter().any(|x| *x == "passes=list") { get_codegen_sysroot("llvm")().print_passes(); return None; } @@ -1500,7 +1472,7 @@ pub fn in_named_rustc_thread(name: String, f: F) -> Result(name: String, f: F) -> Result Option<(Vec, bool)> { } } - if result.len() > 0 { + if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None @@ -1680,25 +1652,25 @@ pub fn monitor(f: F) -> Result<(), CompilationFail errors::Level::Bug); } - let mut xs = vec![ - "the compiler unexpectedly panicked. this is a bug.".to_string(), - format!("we would appreciate a bug report: {}", BUG_REPORT_URL), + let mut xs: Vec> = vec![ + "the compiler unexpectedly panicked. this is a bug.".into(), + format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(), format!("rustc {} running on {}", option_env!("CFG_VERSION").unwrap_or("unknown_version"), - config::host_triple()), + config::host_triple()).into(), ]; if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() { - xs.push(format!("compiler flags: {}", flags.join(" "))); + xs.push(format!("compiler flags: {}", flags.join(" ")).into()); if excluded_cargo_defaults { - xs.push("some of the compiler flags provided by cargo are hidden".to_string()); + xs.push("some of the compiler flags provided by cargo are hidden".into()); } } for note in &xs { handler.emit(&MultiSpan::new(), - ¬e, + note, errors::Level::Note); } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 7e395f1e9a9..b4f6d10b1f8 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -167,10 +167,10 @@ pub fn parse_pretty(sess: &Session, impl PpSourceMode { /// Constructs a `PrinterSupport` object and passes it to `f`. fn call_with_pp_support<'tcx, A, F>(&self, - sess: &'tcx Session, - hir_map: Option<&hir_map::Map<'tcx>>, - f: F) - -> A + sess: &'tcx Session, + hir_map: Option<&hir_map::Map<'tcx>>, + f: F) + -> A where F: FnOnce(&dyn PrinterSupport) -> A { match *self { @@ -198,17 +198,18 @@ impl PpSourceMode { _ => panic!("Should use call_with_pp_support_hir"), } } - fn call_with_pp_support_hir<'tcx, A, F>(&self, - sess: &'tcx Session, - cstore: &'tcx CStore, - hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis, - resolutions: &Resolutions, - arenas: &'tcx AllArenas<'tcx>, - output_filenames: &OutputFilenames, - id: &str, - f: F) - -> A + fn call_with_pp_support_hir<'tcx, A, F>( + &self, + sess: &'tcx Session, + cstore: &'tcx CStore, + hir_map: &hir_map::Map<'tcx>, + analysis: &ty::CrateAnalysis, + resolutions: &Resolutions, + arenas: &'tcx AllArenas<'tcx>, + output_filenames: &OutputFilenames, + id: &str, + f: F + ) -> A where F: FnOnce(&dyn HirPrinterSupport, &hir::Crate) -> A { match *self { @@ -855,7 +856,7 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, break n.body(); } let parent = tcx.hir.get_parent_node(node_id); - assert!(node_id != parent); + assert_ne!(node_id, parent); node_id = parent; } } @@ -952,18 +953,17 @@ pub fn print_after_parsing(sess: &Session, // Silently ignores an identified node. let out: &mut dyn Write = &mut out; s.call_with_pp_support(sess, None, move |annotation| { - debug!("pretty printing source code {:?}", s); - let sess = annotation.sess(); - pprust::print_crate(sess.source_map(), - &sess.parse_sess, - krate, - src_name, - &mut rdr, - box out, - annotation.pp_ann(), - false) - }) - .unwrap() + debug!("pretty printing source code {:?}", s); + let sess = annotation.sess(); + pprust::print_crate(sess.source_map(), + &sess.parse_sess, + krate, + src_name, + &mut rdr, + box out, + annotation.pp_ann(), + false) + }).unwrap() } else { unreachable!(); }; diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs index 2ec85e1c27f..d334a9476ce 100644 --- a/src/librustc_driver/profile/mod.rs +++ b/src/librustc_driver/profile/mod.rs @@ -23,7 +23,7 @@ pub fn begin(sess: &Session) { use std::sync::mpsc::{channel}; let (tx, rx) = channel(); if profq_set_chan(sess, tx) { - thread::spawn(move||profile_queries_thread(rx)); + thread::spawn(move || profile_queries_thread(rx)); } } @@ -34,11 +34,12 @@ pub fn begin(sess: &Session) { pub fn dump(sess: &Session, path: String) { use std::sync::mpsc::{channel}; let (tx, rx) = channel(); - let params = ProfQDumpParams{ - path, ack:tx, + let params = ProfQDumpParams { + path, + ack: tx, // FIXME: Add another compiler flag to toggle whether this log // is written; false for now - dump_profq_msg_log:true, + dump_profq_msg_log: true, }; profq_msg(sess, ProfileQueriesMsg::Dump(params)); let _ = rx.recv().unwrap(); @@ -63,20 +64,20 @@ struct StackFrame { } fn total_duration(traces: &[trace::Rec]) -> Duration { - let mut sum : Duration = Duration::new(0,0); + let mut sum : Duration = Duration::new(0, 0); for t in traces.iter() { sum += t.dur_total; } return sum } // profiling thread; retains state (in local variables) and dump traces, upon request. -fn profile_queries_thread(r:Receiver) { +fn profile_queries_thread(r: Receiver) { use self::trace::*; use std::fs::File; use std::time::{Instant}; - let mut profq_msgs : Vec = vec![]; - let mut frame : StackFrame = StackFrame{ parse_st:ParseState::Clear, traces:vec![] }; - let mut stack : Vec = vec![]; + let mut profq_msgs: Vec = vec![]; + let mut frame: StackFrame = StackFrame { parse_st: ParseState::Clear, traces: vec![] }; + let mut stack: Vec = vec![]; loop { let msg = r.recv(); if let Err(_recv_err) = msg { @@ -90,7 +91,7 @@ fn profile_queries_thread(r:Receiver) { match msg { ProfileQueriesMsg::Halt => return, ProfileQueriesMsg::Dump(params) => { - assert!(stack.len() == 0); + assert!(stack.is_empty()); assert!(frame.parse_st == ParseState::Clear); { // write log of all messages @@ -109,17 +110,14 @@ fn profile_queries_thread(r:Receiver) { let counts_path = format!("{}.counts.txt", params.path); let mut counts_file = File::create(&counts_path).unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, - "\n\n", - "profile_queries.css").unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, "\n").unwrap(); + writeln!(html_file, "\n\n").unwrap(); trace::write_traces(&mut html_file, &mut counts_file, &frame.traces); - write!(html_file, "\n\n").unwrap(); + writeln!(html_file, "\n").unwrap(); let ack_path = format!("{}.ack", params.path); let ack_file = File::create(&ack_path).unwrap(); @@ -141,10 +139,10 @@ fn profile_queries_thread(r:Receiver) { // Parse State: Clear (ParseState::Clear, - ProfileQueriesMsg::QueryBegin(span,querymsg)) => { + ProfileQueriesMsg::QueryBegin(span, querymsg)) => { let start = Instant::now(); frame.parse_st = ParseState::HaveQuery - (Query{span:span, msg:querymsg}, start) + (Query { span, msg: querymsg }, start) }, (ParseState::Clear, ProfileQueriesMsg::CacheHit) => { @@ -287,8 +285,6 @@ fn profile_queries_thread(r:Receiver) { frame = StackFrame{parse_st:ParseState::Clear, traces:vec![]}; }, - // - // // Parse errors: (ParseState::HaveQuery(q,_), @@ -310,7 +306,6 @@ fn profile_queries_thread(r:Receiver) { unreachable!() }, } - } } } diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index e329b037d22..9589ae2a8db 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -43,18 +43,18 @@ pub struct QueryMetric { pub dur_total: Duration, } +fn cons(s: &str) -> String { + let first = s.split(|d| d == '(' || d == '{').next(); + assert!(first.is_some() && first != Some("")); + first.unwrap().to_owned() +} + pub fn cons_of_query_msg(q: &trace::Query) -> String { - let s = format!("{:?}", q.msg); - let cons: Vec<&str> = s.split(|d| d == '(' || d == '{').collect(); - assert!(cons.len() > 0 && cons[0] != ""); - cons[0].to_string() + cons(&format!("{:?}", q.msg)) } pub fn cons_of_key(k: &DepNode) -> String { - let s = format!("{:?}", k); - let cons: Vec<&str> = s.split(|d| d == '(' || d == '{').collect(); - assert!(cons.len() > 0 && cons[0] != ""); - cons[0].to_string() + cons(&format!("{:?}", k)) } // First return value is text; second return value is a CSS class @@ -84,35 +84,33 @@ pub fn html_of_effect(eff: &Effect) -> (String, String) { // First return value is text; second return value is a CSS class fn html_of_duration(_start: &Instant, dur: &Duration) -> (String, String) { use rustc::util::common::duration_to_secs_str; - (duration_to_secs_str(dur.clone()), - String::new() - ) + (duration_to_secs_str(dur.clone()), String::new()) } -fn html_of_fraction(frac: f64) -> (String, String) { +fn html_of_fraction(frac: f64) -> (String, &'static str) { let css = { - if frac > 0.50 { "frac-50".to_string() } - else if frac > 0.40 { "frac-40".to_string() } - else if frac > 0.30 { "frac-30".to_string() } - else if frac > 0.20 { "frac-20".to_string() } - else if frac > 0.10 { "frac-10".to_string() } - else if frac > 0.05 { "frac-05".to_string() } - else if frac > 0.02 { "frac-02".to_string() } - else if frac > 0.01 { "frac-01".to_string() } - else if frac > 0.001 { "frac-001".to_string() } - else { "frac-0".to_string() } + if frac > 0.50 { "frac-50" } + else if frac > 0.40 { "frac-40" } + else if frac > 0.30 { "frac-30" } + else if frac > 0.20 { "frac-20" } + else if frac > 0.10 { "frac-10" } + else if frac > 0.05 { "frac-05" } + else if frac > 0.02 { "frac-02" } + else if frac > 0.01 { "frac-01" } + else if frac > 0.001 { "frac-001" } + else { "frac-0" } }; let percent = frac * 100.0; - if percent > 0.1 { (format!("{:.1}%", percent), css) } - else { ("< 0.1%".to_string(), css) } + + if percent > 0.1 { + (format!("{:.1}%", percent), css) + } else { + ("< 0.1%".to_string(), css) + } } fn total_duration(traces: &[Rec]) -> Duration { - let mut sum : Duration = Duration::new(0,0); - for t in traces.iter() { - sum += t.dur_total; - } - return sum + Duration::new(0, 0) + traces.iter().map(|t| t.dur_total).sum() } fn duration_div(nom: Duration, den: Duration) -> f64 { @@ -130,64 +128,65 @@ fn write_traces_rec(file: &mut File, traces: &[Rec], total: Duration, depth: usi let fraction = duration_div(t.dur_total, total); let percent = fraction * 100.0; let (frc_text, frc_css_classes) = html_of_fraction(fraction); - write!(file, "
\n", - depth, - t.extent.len(), - /* Heuristic for 'important' CSS class: */ - if t.extent.len() > 5 || percent >= 1.0 { - " important" } - else { "" }, - eff_css_classes, - dur_css_classes, - frc_css_classes, + writeln!(file, "
", + depth, + t.extent.len(), + /* Heuristic for 'important' CSS class: */ + if t.extent.len() > 5 || percent >= 1.0 { " important" } else { "" }, + eff_css_classes, + dur_css_classes, + frc_css_classes, ).unwrap(); - write!(file, "
{}
\n", eff_text).unwrap(); - write!(file, "
{}
\n", dur_text).unwrap(); - write!(file, "
{}
\n", frc_text).unwrap(); + writeln!(file, "
{}
", eff_text).unwrap(); + writeln!(file, "
{}
", dur_text).unwrap(); + writeln!(file, "
{}
", frc_text).unwrap(); write_traces_rec(file, &t.extent, total, depth + 1); - write!(file, "
\n").unwrap(); + writeln!(file, "
").unwrap(); } } fn compute_counts_rec(counts: &mut FxHashMap, traces: &[Rec]) { + counts.reserve(traces.len()); for t in traces.iter() { match t.effect { Effect::TimeBegin(ref msg) => { let qm = match counts.get(msg) { - Some(_qm) => { panic!("TimeBegin with non-unique, repeat message") } - None => QueryMetric{ + Some(_qm) => panic!("TimeBegin with non-unique, repeat message"), + None => QueryMetric { count: 1, dur_self: t.dur_self, dur_total: t.dur_total, - }}; + } + }; counts.insert(msg.clone(), qm); }, Effect::TaskBegin(ref key) => { let cons = cons_of_key(key); let qm = match counts.get(&cons) { Some(qm) => - QueryMetric{ + QueryMetric { count: qm.count + 1, dur_self: qm.dur_self + t.dur_self, dur_total: qm.dur_total + t.dur_total, }, - None => QueryMetric{ + None => QueryMetric { count: 1, dur_self: t.dur_self, dur_total: t.dur_total, - }}; + } + }; counts.insert(cons, qm); }, Effect::QueryBegin(ref qmsg, ref _cc) => { let qcons = cons_of_query_msg(qmsg); let qm = match counts.get(&qcons) { Some(qm) => - QueryMetric{ + QueryMetric { count: qm.count + 1, dur_total: qm.dur_total + t.dur_total, dur_self: qm.dur_self + t.dur_self }, - None => QueryMetric{ + None => QueryMetric { count: 1, dur_total: t.dur_total, dur_self: t.dur_self, @@ -200,19 +199,20 @@ fn compute_counts_rec(counts: &mut FxHashMap, traces: &[Rec] } } -pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap) { +pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap) { use rustc::util::common::duration_to_secs_str; use std::cmp::Reverse; let mut data = counts.iter().map(|(ref cons, ref qm)| (cons.clone(), qm.count.clone(), qm.dur_total.clone(), qm.dur_self.clone()) ).collect::>(); + data.sort_by_key(|k| Reverse(k.3)); for (cons, count, dur_total, dur_self) in data { - write!(count_file, "{}, {}, {}, {}\n", - cons, count, - duration_to_secs_str(dur_total), - duration_to_secs_str(dur_self) + writeln!(count_file, "{}, {}, {}, {}", + cons, count, + duration_to_secs_str(dur_total), + duration_to_secs_str(dur_self) ).unwrap(); } } @@ -223,12 +223,12 @@ pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &[Rec] compute_counts_rec(&mut counts, traces); write_counts(counts_file, &mut counts); - let total : Duration = total_duration(traces); + let total: Duration = total_duration(traces); write_traces_rec(html_file, traces, total, 0) } pub fn write_style(html_file: &mut File) { - write!(html_file,"{}", " + write!(html_file, "{}", " body { font-family: sans-serif; background: black; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index ec3c310c63c..7d178d20967 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -80,10 +80,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { match callee.node { hir::ExprKind::Path(ref qpath) => { let def = cx.tables.qpath_def(qpath, callee.hir_id); - if let Def::Fn(_) = def { - Some(def) - } else { // `Def::Local` if it was a closure, for which we - None // do not currently support must-use linting + match def { + Def::Fn(_) | Def::Method(_) => Some(def), + // `Def::Local` if it was a closure, for which we + // do not currently support must-use linting + _ => None } }, _ => None diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index b5137e914dc..f4ddfa5293e 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -327,7 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } (_, &ty::Dynamic(ref data, _)) => { // Initial cast from sized to dyn trait - let trait_ref = data.principal().unwrap().with_self_ty( + let trait_ref = data.principal().with_self_ty( *self.tcx, src_pointee_ty, ); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 29f16762944..dd83d3157ba 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -907,22 +907,20 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, !impl_ty.needs_subst() && !impl_ty.has_escaping_regions()); if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty { - if let Some(principal) = trait_ty.principal() { - let poly_trait_ref = principal.with_self_ty(tcx, impl_ty); - assert!(!poly_trait_ref.has_escaping_regions()); + let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty); + assert!(!poly_trait_ref.has_escaping_regions()); - // Walk all methods of the trait, including those of its supertraits - let methods = tcx.vtable_methods(poly_trait_ref); - let methods = methods.iter().cloned().filter_map(|method| method) - .map(|(def_id, substs)| ty::Instance::resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - substs).unwrap()) - .filter(|&instance| should_monomorphize_locally(tcx, &instance)) - .map(|instance| create_fn_mono_item(instance)); - output.extend(methods); - } + // Walk all methods of the trait, including those of its supertraits + let methods = tcx.vtable_methods(poly_trait_ref); + let methods = methods.iter().cloned().filter_map(|method| method) + .map(|(def_id, substs)| ty::Instance::resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + substs).unwrap()) + .filter(|&instance| should_monomorphize_locally(tcx, &instance)) + .map(|instance| create_fn_mono_item(instance)); + output.extend(methods); // Also add the destructor visit_drop_use(tcx, impl_ty, false, output); } diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index f0ea93bfffd..4c4d56c8938 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -320,12 +320,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.push(']'); }, ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - self.push_def_path(principal.def_id(), output); - self.push_type_params(principal.skip_binder().substs, - trait_data.projection_bounds(), - output); - } + let principal = trait_data.principal(); + self.push_def_path(principal.def_id(), output); + self.push_type_params( + principal.skip_binder().substs, + trait_data.projection_bounds(), + output, + ); }, ty::Foreign(did) => self.push_def_path(did, output), ty::FnDef(..) | diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 040ee35632c..5963f1a481c 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::mir::*; use rustc::mir::visit::*; -use rustc::ty::{self, Instance, Ty, TyCtxt}; +use rustc::ty::{self, Instance, InstanceDef, Ty, TyCtxt}; use rustc::ty::subst::{Subst,Substs}; use std::collections::VecDeque; @@ -100,12 +100,21 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { param_env, callee_def_id, substs) { - callsites.push_back(CallSite { - callee: instance.def_id(), - substs: instance.substs, - bb, - location: terminator.source_info - }); + let is_virtual = + if let InstanceDef::Virtual(..) = instance.def { + true + } else { + false + }; + + if !is_virtual { + callsites.push_back(CallSite { + callee: instance.def_id(), + substs: instance.substs, + bb, + location: terminator.source_info + }); + } } } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 60679d6d430..989851bb1b9 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -93,8 +93,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { let ty_def_id = match self.tcx.type_of(item_def_id).sty { ty::Adt(adt, _) => adt.did, ty::Foreign(did) => did, - ty::Dynamic(ref obj, ..) if obj.principal().is_some() => - obj.principal().unwrap().def_id(), + ty::Dynamic(ref obj, ..) => obj.principal().def_id(), ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id, _ => return Some(AccessLevel::Public) }; @@ -484,7 +483,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b let ty_def_id = match ty.sty { ty::Adt(adt, _) => Some(adt.did), ty::Foreign(did) => Some(did), - ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), + ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), ty::Projection(ref proj) => Some(proj.item_def_id), ty::FnDef(def_id, ..) | ty::Closure(def_id, ..) | @@ -1456,7 +1455,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<' let ty_def_id = match ty.sty { ty::Adt(adt, _) => Some(adt.did), ty::Foreign(did) => Some(did), - ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), + ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), ty::Projection(ref proj) => { if self.required_visibility == ty::Visibility::Invisible { // Conservatively approximate the whole type alias as public without diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 9c0f945326d..9ee4582fabf 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -680,6 +680,12 @@ pub struct TargetOptions { /// typically because the platform needs to unwind for things like stack /// unwinders. pub requires_uwtable: bool, + + /// Whether or not SIMD types are passed by reference in the Rust ABI, + /// typically required if a target can be compiled with a mixed set of + /// target features. This is `true` by default, and `false` for targets like + /// wasm32 where the whole program either has simd or not. + pub simd_types_indirect: bool, } impl Default for TargetOptions { @@ -760,6 +766,7 @@ impl Default for TargetOptions { embed_bitcode: false, emit_debug_gdb_scripts: true, requires_uwtable: false, + simd_types_indirect: true, } } } @@ -1041,6 +1048,7 @@ impl Target { key!(embed_bitcode, bool); key!(emit_debug_gdb_scripts, bool); key!(requires_uwtable, bool); + key!(simd_types_indirect, bool); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -1250,6 +1258,7 @@ impl ToJson for Target { target_option_val!(embed_bitcode); target_option_val!(emit_debug_gdb_scripts); target_option_val!(requires_uwtable); + target_option_val!(simd_types_indirect); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() diff --git a/src/librustc_target/spec/wasm32_unknown_unknown.rs b/src/librustc_target/spec/wasm32_unknown_unknown.rs index c0455ceb839..46353068bd0 100644 --- a/src/librustc_target/spec/wasm32_unknown_unknown.rs +++ b/src/librustc_target/spec/wasm32_unknown_unknown.rs @@ -54,6 +54,12 @@ pub fn target() -> Result { linker: Some("rust-lld".to_owned()), lld_flavor: LldFlavor::Wasm, + // No need for indirection here, simd types can always be passed by + // value as the whole module either has simd or not, which is different + // from x86 (for example) where programs can have functions that don't + // enable simd features. + simd_types_indirect: false, + .. Default::default() }; Ok(Target { diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 285fed9544d..e0ee26cba08 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -73,7 +73,7 @@ enum PointerKind<'tcx> { /// No metadata attached, ie pointer to sized type or foreign type Thin, /// A trait object - Vtable(Option), + Vtable(DefId), /// Slice Length, /// The unsize info of this projection @@ -105,7 +105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Ok(match t.sty { ty::Slice(_) | ty::Str => Some(PointerKind::Length), ty::Dynamic(ref tty, ..) => - Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))), + Some(PointerKind::Vtable(tty.principal().def_id())), ty::Adt(def, substs) if def.is_struct() => { match def.non_enum_variant().fields.last() { None => Some(PointerKind::Thin), diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 202789d1d8a..940fa4d3916 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -198,9 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.deduce_sig_from_projection(None, &pb) }) .next(); - let kind = object_type - .principal() - .and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id())); + let kind = self.tcx.lang_items().fn_trait_kind(object_type.principal().def_id()); (sig, kind) } ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 4e5488b432d..75f5bf74c6a 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { .include_raw_pointers() .filter_map(|(ty, _)| match ty.sty { - ty::Dynamic(ref data, ..) => data.principal().map(|p| closure(self, ty, p)), + ty::Dynamic(ref data, ..) => Some(closure(self, ty, data.principal())), _ => None, } ) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index ec4483204f0..ae02cd64c38 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -452,10 +452,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { match self_ty.sty { ty::Dynamic(ref data, ..) => { - if let Some(p) = data.principal() { - self.assemble_inherent_candidates_from_object(self_ty, p); - self.assemble_inherent_impl_candidates_for_type(p.def_id()); - } + let p = data.principal(); + self.assemble_inherent_candidates_from_object(self_ty, p); + self.assemble_inherent_impl_candidates_for_type(p.def_id()); } ty::Adt(def, _) => { self.assemble_inherent_impl_candidates_for_type(def.did); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 28b9dcb9bfd..2006796a100 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -663,8 +663,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Adt(def, _) => def.did.is_local(), ty::Foreign(did) => did.is_local(), - ty::Dynamic(ref tr, ..) => tr.principal() - .map_or(false, |p| p.def_id().is_local()), + ty::Dynamic(ref tr, ..) => tr.principal().def_id().is_local(), ty::Param(_) => true, diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 1955a709dbf..ec979dea4fd 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -108,8 +108,8 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> { ty::Foreign(did) => { self.check_def_id(item, did); } - ty::Dynamic(ref data, ..) if data.principal().is_some() => { - self.check_def_id(item, data.principal().unwrap().def_id()); + ty::Dynamic(ref data, ..) => { + self.check_def_id(item, data.principal().def_id()); } ty::Char => { self.check_primitive_impl(def_id, diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 616ca97a7a7..9b17654d469 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -181,13 +181,12 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI // This is something like impl Trait1 for Trait2. Illegal // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe. - if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) { + if !tcx.is_object_safe(data.principal().def_id()) { // This is an error, but it will be reported by wfcheck. Ignore it here. // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. } else { let mut supertrait_def_ids = - traits::supertrait_def_ids(tcx, - data.principal().unwrap().def_id()); + traits::supertrait_def_ids(tcx, data.principal().def_id()); if supertrait_def_ids.any(|d| d == trait_def_id) { let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap()); struct_span_err!(tcx.sess, diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index 254146c0ef3..132da8f5cea 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -203,28 +203,27 @@ fn insert_required_predicates_to_be_wf<'tcx>( debug!("Dynamic"); debug!("field_ty = {}", &field_ty); debug!("ty in field = {}", &ty); - if let Some(ex_trait_ref) = obj.principal() { - // Here, we are passing the type `usize` as a - // placeholder value with the function - // `with_self_ty`, since there is no concrete type - // `Self` for a `dyn Trait` at this - // stage. Therefore when checking explicit - // predicates in `check_explicit_predicates` we - // need to ignore checking the explicit_map for - // Self type. - let substs = ex_trait_ref - .with_self_ty(tcx, tcx.types.usize) - .skip_binder() - .substs; - check_explicit_predicates( - tcx, - &ex_trait_ref.skip_binder().def_id, - substs, - required_predicates, - explicit_map, - IgnoreSelfTy(true), - ); - } + let ex_trait_ref = obj.principal(); + // Here, we are passing the type `usize` as a + // placeholder value with the function + // `with_self_ty`, since there is no concrete type + // `Self` for a `dyn Trait` at this + // stage. Therefore when checking explicit + // predicates in `check_explicit_predicates` we + // need to ignore checking the explicit_map for + // Self type. + let substs = ex_trait_ref + .with_self_ty(tcx, tcx.types.usize) + .skip_binder() + .substs; + check_explicit_predicates( + tcx, + &ex_trait_ref.skip_binder().def_id, + substs, + required_predicates, + explicit_map, + IgnoreSelfTy(true), + ); } ty::Projection(obj) => { diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 32a591777db..3e523c0c7f5 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -311,11 +311,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let contra = self.contravariant(variance); self.add_constraints_from_region(current, r, contra); - if let Some(p) = data.principal() { - let poly_trait_ref = p.with_self_ty(self.tcx(), self.tcx().types.err); - self.add_constraints_from_trait_ref( - current, *poly_trait_ref.skip_binder(), variance); - } + let poly_trait_ref = data + .principal() + .with_self_ty(self.tcx(), self.tcx().types.err); + self.add_constraints_from_trait_ref( + current, *poly_trait_ref.skip_binder(), variance); for projection in data.projection_bounds() { self.add_constraints_from_ty( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ddabef96c7c..2ba1f103971 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2632,47 +2632,44 @@ impl<'tcx> Clean for Ty<'tcx> { } } ty::Dynamic(ref obj, ref reg) => { - if let Some(principal) = obj.principal() { - let did = principal.def_id(); + let principal = obj.principal(); + let did = principal.def_id(); + inline::record_extern_fqn(cx, did, TypeKind::Trait); + + let mut typarams = vec![]; + reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b))); + for did in obj.auto_traits() { + let empty = cx.tcx.intern_substs(&[]); + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), + Some(did), false, vec![], empty); inline::record_extern_fqn(cx, did, TypeKind::Trait); + let bound = GenericBound::TraitBound(PolyTrait { + trait_: ResolvedPath { + path, + typarams: None, + did, + is_generic: false, + }, + generic_params: Vec::new(), + }, hir::TraitBoundModifier::None); + typarams.push(bound); + } - let mut typarams = vec![]; - reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b))); - for did in obj.auto_traits() { - let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, &cx.tcx.item_name(did).as_str(), - Some(did), false, vec![], empty); - inline::record_extern_fqn(cx, did, TypeKind::Trait); - let bound = GenericBound::TraitBound(PolyTrait { - trait_: ResolvedPath { - path, - typarams: None, - did, - is_generic: false, - }, - generic_params: Vec::new(), - }, hir::TraitBoundModifier::None); - typarams.push(bound); - } + let mut bindings = vec![]; + for pb in obj.projection_bounds() { + bindings.push(TypeBinding { + name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), + ty: pb.skip_binder().ty.clean(cx) + }); + } - let mut bindings = vec![]; - for pb in obj.projection_bounds() { - bindings.push(TypeBinding { - name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), - ty: pb.skip_binder().ty.clean(cx) - }); - } - - let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), - false, bindings, principal.skip_binder().substs); - ResolvedPath { - path, - typarams: Some(typarams), - did, - is_generic: false, - } - } else { - Never + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), + false, bindings, principal.skip_binder().substs); + ResolvedPath { + path, + typarams: Some(typarams), + did, + is_generic: false, } } ty::Tuple(ref t) => Tuple(t.clean(cx)), diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index bcdd1b4b088..cd1e3438fc3 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -48,4 +48,13 @@ jemalloc = ["alloc_jemalloc"] force_alloc_system = [] panic-unwind = ["panic_unwind"] profiler = ["profiler_builtins"] + +# An off-by-default feature which enables a linux-syscall-like ABI for libstd to +# interoperate with the host environment. Currently not well documented and +# requires rebuilding the standard library to use it. wasm_syscall = [] + +# An off-by-default features to enable libstd to assume that wasm-bindgen is in +# the environment for hooking up some thread-related information like the +# current thread id and accessing/getting the current thread's TCB +wasm-bindgen-threads = [] diff --git a/src/libstd/sys/wasm/mutex_atomics.rs b/src/libstd/sys/wasm/mutex_atomics.rs index ced6c17ef96..762e807096f 100644 --- a/src/libstd/sys/wasm/mutex_atomics.rs +++ b/src/libstd/sys/wasm/mutex_atomics.rs @@ -11,7 +11,8 @@ use arch::wasm32::atomic; use cell::UnsafeCell; use mem; -use sync::atomic::{AtomicUsize, AtomicU64, Ordering::SeqCst}; +use sync::atomic::{AtomicUsize, AtomicU32, Ordering::SeqCst}; +use sys::thread; pub struct Mutex { locked: AtomicUsize, @@ -70,7 +71,7 @@ impl Mutex { } pub struct ReentrantMutex { - owner: AtomicU64, + owner: AtomicU32, recursions: UnsafeCell, } @@ -91,7 +92,7 @@ unsafe impl Sync for ReentrantMutex {} impl ReentrantMutex { pub unsafe fn uninitialized() -> ReentrantMutex { ReentrantMutex { - owner: AtomicU64::new(0), + owner: AtomicU32::new(0), recursions: UnsafeCell::new(0), } } @@ -101,20 +102,20 @@ impl ReentrantMutex { } pub unsafe fn lock(&self) { - let me = thread_id(); + let me = thread::my_id(); while let Err(owner) = self._try_lock(me) { - let val = atomic::wait_i64(self.ptr(), owner as i64, -1); + let val = atomic::wait_i32(self.ptr(), owner as i32, -1); debug_assert!(val == 0 || val == 1); } } #[inline] pub unsafe fn try_lock(&self) -> bool { - self._try_lock(thread_id()).is_ok() + self._try_lock(thread::my_id()).is_ok() } #[inline] - unsafe fn _try_lock(&self, id: u64) -> Result<(), u64> { + unsafe fn _try_lock(&self, id: u32) -> Result<(), u32> { let id = id.checked_add(1).unwrap(); // make sure `id` isn't 0 match self.owner.compare_exchange(0, id, SeqCst, SeqCst) { // we transitioned from unlocked to locked @@ -153,11 +154,7 @@ impl ReentrantMutex { } #[inline] - fn ptr(&self) -> *mut i64 { - &self.owner as *const AtomicU64 as *mut i64 + fn ptr(&self) -> *mut i32 { + &self.owner as *const AtomicU32 as *mut i32 } } - -fn thread_id() -> u64 { - panic!("thread ids not implemented on wasm with atomics yet") -} diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index bef6c1f3490..4ad89c42b92 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -69,3 +69,49 @@ pub mod guard { pub unsafe fn init() -> Option { None } pub unsafe fn deinit() {} } + +cfg_if! { + if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] { + #[link(wasm_import_module = "__wbindgen_thread_xform__")] + extern { + fn __wbindgen_current_id() -> u32; + fn __wbindgen_tcb_get() -> u32; + fn __wbindgen_tcb_set(ptr: u32); + } + pub fn my_id() -> u32 { + unsafe { __wbindgen_current_id() } + } + + // These are currently only ever used in `thread_local_atomics.rs`, if + // you'd like to use them be sure to update that and make sure everyone + // agrees what's what. + pub fn tcb_get() -> *mut u8 { + use mem; + assert_eq!(mem::size_of::<*mut u8>(), mem::size_of::()); + unsafe { __wbindgen_tcb_get() as *mut u8 } + } + + pub fn tcb_set(ptr: *mut u8) { + unsafe { __wbindgen_tcb_set(ptr as u32); } + } + + // FIXME: still need something for hooking exiting a thread to free + // data... + + } else if #[cfg(target_feature = "atomics")] { + pub fn my_id() -> u32 { + panic!("thread ids not implemented on wasm with atomics yet") + } + + pub fn tcb_get() -> *mut u8 { + panic!("thread local data not implemented on wasm with atomics yet") + } + + pub fn tcb_set(ptr: *mut u8) { + panic!("thread local data not implemented on wasm with atomics yet") + } + } else { + // stubbed out because no functions actually access these intrinsics + // unless atomics are enabled + } +} diff --git a/src/libstd/sys/wasm/thread_local_atomics.rs b/src/libstd/sys/wasm/thread_local_atomics.rs index 1394013b4a3..acfe60719f2 100644 --- a/src/libstd/sys/wasm/thread_local_atomics.rs +++ b/src/libstd/sys/wasm/thread_local_atomics.rs @@ -8,22 +8,61 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use sys::thread; +use sync::atomic::{AtomicUsize, Ordering::SeqCst}; + +const MAX_KEYS: usize = 128; +static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); + +struct ThreadControlBlock { + keys: [*mut u8; MAX_KEYS], +} + +impl ThreadControlBlock { + fn new() -> ThreadControlBlock { + ThreadControlBlock { + keys: [0 as *mut u8; MAX_KEYS], + } + } + + fn get() -> *mut ThreadControlBlock { + let ptr = thread::tcb_get(); + if !ptr.is_null() { + return ptr as *mut ThreadControlBlock + } + let tcb = Box::into_raw(Box::new(ThreadControlBlock::new())); + thread::tcb_set(tcb as *mut u8); + tcb + } +} + pub type Key = usize; -pub unsafe fn create(_dtor: Option) -> Key { - panic!("TLS on wasm with atomics not implemented yet"); +pub unsafe fn create(dtor: Option) -> Key { + drop(dtor); // FIXME: need to figure out how to hook thread exit to run this + let key = NEXT_KEY.fetch_add(1, SeqCst); + if key >= MAX_KEYS { + NEXT_KEY.store(MAX_KEYS, SeqCst); + panic!("cannot allocate space for more TLS keys"); + } + // offset by 1 so we never hand out 0. This is currently required by + // `sys_common/thread_local.rs` where it can't cope with keys of value 0 + // because it messes up the atomic management. + return key + 1 } -pub unsafe fn set(_key: Key, _value: *mut u8) { - panic!("TLS on wasm with atomics not implemented yet"); +pub unsafe fn set(key: Key, value: *mut u8) { + (*ThreadControlBlock::get()).keys[key - 1] = value; } -pub unsafe fn get(_key: Key) -> *mut u8 { - panic!("TLS on wasm with atomics not implemented yet"); +pub unsafe fn get(key: Key) -> *mut u8 { + (*ThreadControlBlock::get()).keys[key - 1] } pub unsafe fn destroy(_key: Key) { - panic!("TLS on wasm with atomics not implemented yet"); + // FIXME: should implement this somehow, this isn't typically called but it + // can be called if two threads race to initialize a TLS slot and one ends + // up not being needed. } #[inline] diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index a170abb2628..59f100fad1b 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -172,16 +172,22 @@ macro_rules! __thread_local_inner { &'static $crate::cell::UnsafeCell< $crate::option::Option<$t>>> { - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))] static __KEY: $crate::thread::__StaticLocalKeyInner<$t> = $crate::thread::__StaticLocalKeyInner::new(); #[thread_local] - #[cfg(all(target_thread_local, not(target_arch = "wasm32")))] + #[cfg(all( + target_thread_local, + not(all(target_arch = "wasm32", not(target_feature = "atomics"))), + ))] static __KEY: $crate::thread::__FastLocalKeyInner<$t> = $crate::thread::__FastLocalKeyInner::new(); - #[cfg(all(not(target_thread_local), not(target_arch = "wasm32")))] + #[cfg(all( + not(target_thread_local), + not(all(target_arch = "wasm32", not(target_feature = "atomics"))), + ))] static __KEY: $crate::thread::__OsLocalKeyInner<$t> = $crate::thread::__OsLocalKeyInner::new(); @@ -302,7 +308,7 @@ impl LocalKey { /// On some platforms like wasm32 there's no threads, so no need to generate /// thread locals and we can instead just use plain statics! #[doc(hidden)] -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))] pub mod statik { use cell::UnsafeCell; use fmt; diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index c8d54a63946..796b2bd3eed 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -203,7 +203,7 @@ pub use self::local::{LocalKey, AccessError}; // where available, but both are needed. #[unstable(feature = "libstd_thread_internals", issue = "0")] -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))] #[doc(hidden)] pub use self::local::statik::Key as __StaticLocalKeyInner; #[unstable(feature = "libstd_thread_internals", issue = "0")] #[cfg(target_thread_local)] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b86b92fb29e..84122688c83 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -499,6 +499,9 @@ declare_features! ( // #[cfg_attr(predicate, multiple, attributes, here)] (active, cfg_attr_multi, "1.31.0", Some(54881), None), + + // Allows `const _: TYPE = VALUE` + (active, underscore_const_names, "1.31.0", Some(54912), None), ); declare_features! ( @@ -1583,6 +1586,13 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } + ast::ItemKind::Const(_,_) => { + if i.ident.name == "_" { + gate_feature_post!(&self, underscore_const_names, i.span, + "naming constants with `_` is unstable"); + } + } + ast::ItemKind::ForeignMod(ref foreign_module) => { self.check_abi(foreign_module.abi, i.span); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b5896f37c00..c7089a295fc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6346,7 +6346,13 @@ impl<'a> Parser<'a> { } fn parse_item_const(&mut self, m: Option) -> PResult<'a, ItemInfo> { - let id = self.parse_ident()?; + let id = match self.token { + token::Ident(ident, false) if ident.name == keywords::Underscore.name() => { + self.bump(); // `_` + ident.gensym() + }, + _ => self.parse_ident()?, + }; self.expect(&token::Colon)?; let ty = self.parse_ty()?; self.expect(&token::Eq)?; diff --git a/src/stage0.txt b/src/stage0.txt index f0967d1ba8a..6e931a84bac 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2018-09-23 +date: 2018-10-13 rustc: beta cargo: beta diff --git a/src/test/mir-opt/inline-trait-method.rs b/src/test/mir-opt/inline-trait-method.rs new file mode 100644 index 00000000000..0f79f43ee2d --- /dev/null +++ b/src/test/mir-opt/inline-trait-method.rs @@ -0,0 +1,31 @@ +// compile-flags: -Z span_free_formats + +fn main() { + println!("{}", test(&())); +} + +fn test(x: &dyn X) -> u32 { + x.y() +} + +trait X { + fn y(&self) -> u32 { + 1 + } +} + +impl X for () { + fn y(&self) -> u32 { + 2 + } +} + +// END RUST SOURCE +// START rustc.test.Inline.after.mir +// ... +// bb0: { +// ... +// _0 = const X::y(move _2) -> bb1; +// } +// ... +// END rustc.test.Inline.after.mir diff --git a/src/test/run-pass/resolve-pseudo-shadowing.rs b/src/test/run-pass/resolve-pseudo-shadowing.rs index 071279ae7d8..bf6e686bb7b 100644 --- a/src/test/run-pass/resolve-pseudo-shadowing.rs +++ b/src/test/run-pass/resolve-pseudo-shadowing.rs @@ -12,7 +12,7 @@ fn check(_c: Clone) { fn check2() { - <() as std::clone::Clone>::clone(&()); + let _ = <() as std::clone::Clone>::clone(&()); } check2(); } diff --git a/src/test/ui/closure-expected-type/README.md b/src/test/ui/closure-expected-type/README.md deleted file mode 100644 index 9995b00a9a7..00000000000 --- a/src/test/ui/closure-expected-type/README.md +++ /dev/null @@ -1 +0,0 @@ -See `src/test/run-pass/closure-expected-type`. diff --git a/src/test/ui/closure-expected-type/issue-24421.rs b/src/test/ui/closure-expected-type/issue-24421.rs new file mode 100644 index 00000000000..b3c50a74a32 --- /dev/null +++ b/src/test/ui/closure-expected-type/issue-24421.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass + +fn test(f: F) {} + +fn main() { + test(|x, y | {}); + test(|x:&u64, y:&u64| {}); + test(|x:&u64, y | {}); + test(|x, y:&u64| {}); +} diff --git a/src/test/ui/feature-gate-underscore_const_names.rs b/src/test/ui/feature-gate-underscore_const_names.rs new file mode 100644 index 00000000000..b283e286514 --- /dev/null +++ b/src/test/ui/feature-gate-underscore_const_names.rs @@ -0,0 +1,24 @@ +// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(const_let)] + +trait Trt {} +struct Str {} + +impl Trt for Str {} + +const _ : () = { + use std::marker::PhantomData; + struct ImplementsTrait(PhantomData); + let _ = ImplementsTrait::(PhantomData); + () +}; + +fn main() {} diff --git a/src/test/ui/feature-gate-underscore_const_names.stderr b/src/test/ui/feature-gate-underscore_const_names.stderr new file mode 100644 index 00000000000..ab90ef8f11f --- /dev/null +++ b/src/test/ui/feature-gate-underscore_const_names.stderr @@ -0,0 +1,16 @@ +error[E0658]: naming constants with `_` is unstable (see issue #54912) + --> $DIR/feature-gate-underscore_const_names.rs:17:1 + | +LL | / const _ : () = { +LL | | use std::marker::PhantomData; +LL | | struct ImplementsTrait(PhantomData); +LL | | let _ = ImplementsTrait::(PhantomData); +LL | | () +LL | | }; + | |__^ + | + = help: add #![feature(underscore_const_names)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs index def23046db2..e3e20bc89b4 100644 --- a/src/test/ui/fn_must_use.rs +++ b/src/test/ui/fn_must_use.rs @@ -22,6 +22,11 @@ impl MyStruct { fn need_to_use_this_method_value(&self) -> usize { self.n } + + #[must_use] + fn need_to_use_this_associated_function_value() -> isize { + -1 + } } trait EvenNature { @@ -66,6 +71,9 @@ fn main() { m.is_even(); // trait method! //~^ WARN unused return value + MyStruct::need_to_use_this_associated_function_value(); + //~^ WARN unused return value + m.replace(3); // won't warn (annotation needs to be in trait definition) // comparison methods are `must_use` diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/fn_must_use.stderr index b5bad22f3dc..1bce8abbbf0 100644 --- a/src/test/ui/fn_must_use.stderr +++ b/src/test/ui/fn_must_use.stderr @@ -1,5 +1,5 @@ warning: unused return value of `need_to_use_this_value` which must be used - --> $DIR/fn_must_use.rs:60:5 + --> $DIR/fn_must_use.rs:65:5 | LL | need_to_use_this_value(); //~ WARN unused return value | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,39 +12,45 @@ LL | #![warn(unused_must_use)] = note: it's important warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used - --> $DIR/fn_must_use.rs:65:5 + --> $DIR/fn_must_use.rs:70:5 | LL | m.need_to_use_this_method_value(); //~ WARN unused return value | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused return value of `EvenNature::is_even` which must be used - --> $DIR/fn_must_use.rs:66:5 + --> $DIR/fn_must_use.rs:71:5 | LL | m.is_even(); // trait method! | ^^^^^^^^^^^^ | = note: no side effects +warning: unused return value of `MyStruct::need_to_use_this_associated_function_value` which must be used + --> $DIR/fn_must_use.rs:74:5 + | +LL | MyStruct::need_to_use_this_associated_function_value(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + warning: unused return value of `std::cmp::PartialEq::eq` which must be used - --> $DIR/fn_must_use.rs:72:5 + --> $DIR/fn_must_use.rs:80:5 | LL | 2.eq(&3); //~ WARN unused return value | ^^^^^^^^^ warning: unused return value of `std::cmp::PartialEq::eq` which must be used - --> $DIR/fn_must_use.rs:73:5 + --> $DIR/fn_must_use.rs:81:5 | LL | m.eq(&n); //~ WARN unused return value | ^^^^^^^^^ warning: unused comparison which must be used - --> $DIR/fn_must_use.rs:76:5 + --> $DIR/fn_must_use.rs:84:5 | LL | 2 == 3; //~ WARN unused comparison | ^^^^^^ warning: unused comparison which must be used - --> $DIR/fn_must_use.rs:77:5 + --> $DIR/fn_must_use.rs:85:5 | LL | m == n; //~ WARN unused comparison | ^^^^^^ diff --git a/src/test/ui/issues/issue-52240.nll.stderr b/src/test/ui/issues/issue-52240.nll.stderr new file mode 100644 index 00000000000..69b663b17d3 --- /dev/null +++ b/src/test/ui/issues/issue-52240.nll.stderr @@ -0,0 +1,9 @@ +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/issue-52240.rs:9:27 + | +LL | if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) { + | ^^^^^^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/issues/issue-52240.rs b/src/test/ui/issues/issue-52240.rs new file mode 100644 index 00000000000..9ac7e9905da --- /dev/null +++ b/src/test/ui/issues/issue-52240.rs @@ -0,0 +1,16 @@ +// issue-52240: Can turn immutable into mut with `ref mut` + +enum Foo { + Bar(i32), +} + +fn main() { + let arr = vec!(Foo::Bar(0)); + if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) { + //~^ ERROR cannot borrow field of immutable binding as mutable + *val = 9001; + } + match arr[0] { + Foo::Bar(ref s) => println!("{}", s) + } +} diff --git a/src/test/ui/issues/issue-52240.stderr b/src/test/ui/issues/issue-52240.stderr new file mode 100644 index 00000000000..c2c2524816d --- /dev/null +++ b/src/test/ui/issues/issue-52240.stderr @@ -0,0 +1,9 @@ +error[E0596]: cannot borrow field of immutable binding as mutable + --> $DIR/issue-52240.rs:9:27 + | +LL | if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) { + | ^^^^^^^^^^^ cannot mutably borrow field of immutable binding + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/issues/issue-54966.rs b/src/test/ui/issues/issue-54966.rs new file mode 100644 index 00000000000..0ed3c4b3ca9 --- /dev/null +++ b/src/test/ui/issues/issue-54966.rs @@ -0,0 +1,6 @@ +// issue-54966: ICE returning an unknown type with impl FnMut + +fn generate_duration() -> Oper {} +//~^ ERROR cannot find type `Oper` in this scope + +fn main() {} diff --git a/src/test/ui/issues/issue-54966.stderr b/src/test/ui/issues/issue-54966.stderr new file mode 100644 index 00000000000..aa9a61cb592 --- /dev/null +++ b/src/test/ui/issues/issue-54966.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Oper` in this scope + --> $DIR/issue-54966.rs:3:27 + | +LL | fn generate_duration() -> Oper {} + | ^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/underscore_const_names.rs b/src/test/ui/underscore_const_names.rs new file mode 100644 index 00000000000..8d31fd0b1e9 --- /dev/null +++ b/src/test/ui/underscore_const_names.rs @@ -0,0 +1,43 @@ +// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass + +#![feature(const_let)] +#![feature(underscore_const_names)] + +trait Trt {} +struct Str {} +impl Trt for Str {} + +macro_rules! check_impl { + ($struct:ident,$trait:ident) => { + const _ : () = { + use std::marker::PhantomData; + struct ImplementsTrait(PhantomData); + let _ = ImplementsTrait::<$struct>(PhantomData); + () + }; + } +} + +#[deny(unused)] +const _ : () = (); + +const _ : i32 = 42; +const _ : Str = Str{}; + +check_impl!(Str, Trt); +check_impl!(Str, Trt); + +fn main() { + check_impl!(Str, Trt); + check_impl!(Str, Trt); +} diff --git a/src/tools/cargo b/src/tools/cargo index ad6e5c0037d..5dbac988851 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit ad6e5c0037d88602a1c95051e42b392ed5ffcbe8 +Subproject commit 5dbac98885199bbd7c0f189d7405b5523434d1e3 diff --git a/src/tools/clippy b/src/tools/clippy index 32b1d1fc157..9d3373137b7 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 32b1d1fc157f71ed2f10b60fe28abe087a743618 +Subproject commit 9d3373137b74a403281b293b19ab9346773af073 diff --git a/src/tools/miri b/src/tools/miri index 26f9d617c34..8b14b033684 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 26f9d617c347185433b77c481a5c50c55d9b72ce +Subproject commit 8b14b03368429e6ee2a8ac0e0c876505606ab1f1 diff --git a/src/tools/rls b/src/tools/rls index 15d4d4a5b0c..440a9855b73 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 15d4d4a5b0cf3c0155195f3322cc7a61148e5567 +Subproject commit 440a9855b73b6bf9b5345cf3a79565566f6ef345