diff --git a/Cargo.lock b/Cargo.lock index 73cb611d79f18..85a94b4f59912 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,9 +412,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.50" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" +checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" dependencies = [ "jobserver", ] @@ -2298,9 +2298,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-src" -version = "111.8.1+1.1.1f" +version = "111.9.0+1.1.1g" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04f0299a91de598dde58d2e99101895498dcf3d58896a3297798f28b27c8b72" +checksum = "a2dbe10ddd1eb335aba3780eb2eaa13e1b7b441d2562fd962398740927f39ec4" dependencies = [ "cc", ] diff --git a/RELEASES.md b/RELEASES.md index 36597b1864f25..8ea481f7e18cd 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,15 @@ +Version 1.43.1 (2020-05-07) +=========================== + +* [Updated openssl-src to 1.1.1g for CVE-2020-1967.][71430] +* [Fixed the stabilization of AVX-512 features.][71473] +* [Fixed `cargo package --list` not working with unpublished dependencies.][cargo/8151] + +[71430]: https://github.com/rust-lang/rust/pull/71430 +[71473]: https://github.com/rust-lang/rust/issues/71473 +[cargo/8151]: https://github.com/rust-lang/cargo/issues/8151 + + Version 1.43.0 (2020-04-23) ========================== @@ -14,7 +26,7 @@ Language - [Merge `fn` syntax + cleanup item parsing.][68728] - [`item` macro fragments can be interpolated into `trait`s, `impl`s, and `extern` blocks.][69366] For example, you may now write: - ```rust + ```rust macro_rules! mac_trait { ($i:item) => { trait T { $i } @@ -82,7 +94,7 @@ Misc - [Certain checks in the `const_err` lint were deemed unrelated to const evaluation][69185], and have been moved to the `unconditional_panic` and `arithmetic_overflow` lints. - + Compatibility Notes ------------------- @@ -173,7 +185,7 @@ Language (e.g. `type Foo: Ord;`). - `...` (the C-variadic type) may occur syntactically directly as the type of any function parameter. - + These are still rejected *semantically*, so you will likely receive an error but these changes can be seen and parsed by procedural macros and conditional compilation. @@ -465,7 +477,7 @@ Compatibility Notes - [Using `#[inline]` on function prototypes and consts now emits a warning under `unused_attribute` lint.][65294] Using `#[inline]` anywhere else inside traits or `extern` blocks now correctly emits a hard error. - + [65294]: https://github.com/rust-lang/rust/pull/65294/ [66103]: https://github.com/rust-lang/rust/pull/66103/ [65843]: https://github.com/rust-lang/rust/pull/65843/ diff --git a/src/ci/scripts/install-msys2-packages.sh b/src/ci/scripts/install-msys2-packages.sh index 3874a86e120b1..ff7479c05d04e 100755 --- a/src/ci/scripts/install-msys2-packages.sh +++ b/src/ci/scripts/install-msys2-packages.sh @@ -9,11 +9,19 @@ if isWindows; then pacman -S --noconfirm --needed base-devel ca-certificates make diffutils tar \ binutils + # Detect the native Python version installed on the agent. On GitHub + # Actions, the C:\hostedtoolcache\windows\Python directory contains a + # subdirectory for each installed Python version. + # + # The -V flag of the sort command sorts the input by version number. + native_python_version="$(ls /c/hostedtoolcache/windows/Python | sort -Vr | head -n 1)" + # Make sure we use the native python interpreter instead of some msys equivalent # one way or another. The msys interpreters seem to have weird path conversions # baked in which break LLVM's build system one way or another, so let's use the # native version which keeps everything as native as possible. - python_home="C:/hostedtoolcache/windows/Python/3.7.6/x64" + python_home="/c/hostedtoolcache/windows/Python/${native_python_version}/x64" cp "${python_home}/python.exe" "${python_home}/python3.exe" - ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\3.7.6\\x64" + ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64" + ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64\\Scripts" fi diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs index 2dd405ced20e1..6700ef017bde4 100644 --- a/src/libcore/iter/adapters/chain.rs +++ b/src/libcore/iter/adapters/chain.rs @@ -18,6 +18,9 @@ pub struct Chain { // adapter because its specialization for `FusedIterator` unconditionally descends into the // iterator, and that could be expensive to keep revisiting stuff like nested chains. It also // hurts compiler performance to add more iterator layers to `Chain`. + // + // Only the "first" iterator is actually set `None` when exhausted, depending on whether you + // iterate forward or backward. If you mix directions, then both sides may be `None`. a: Option, b: Option, } @@ -43,6 +46,17 @@ macro_rules! fuse { }; } +/// Try an iterator method without fusing, +/// like an inline `.as_mut().and_then(...)` +macro_rules! maybe { + ($self:ident . $iter:ident . $($call:tt)+) => { + match $self.$iter { + Some(ref mut iter) => iter.$($call)+, + None => None, + } + }; +} + #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Chain where @@ -54,7 +68,7 @@ where #[inline] fn next(&mut self) -> Option { match fuse!(self.a.next()) { - None => fuse!(self.b.next()), + None => maybe!(self.b.next()), item => item, } } @@ -85,7 +99,7 @@ where } if let Some(ref mut b) = self.b { acc = b.try_fold(acc, f)?; - self.b = None; + // we don't fuse the second iterator } Try::from_ok(acc) } @@ -114,7 +128,7 @@ where } self.a = None; } - fuse!(self.b.nth(n)) + maybe!(self.b.nth(n)) } #[inline] @@ -123,7 +137,7 @@ where P: FnMut(&Self::Item) -> bool, { match fuse!(self.a.find(&mut predicate)) { - None => fuse!(self.b.find(predicate)), + None => maybe!(self.b.find(predicate)), item => item, } } @@ -174,7 +188,7 @@ where #[inline] fn next_back(&mut self) -> Option { match fuse!(self.b.next_back()) { - None => fuse!(self.a.next_back()), + None => maybe!(self.a.next_back()), item => item, } } @@ -190,7 +204,7 @@ where } self.b = None; } - fuse!(self.a.nth_back(n)) + maybe!(self.a.nth_back(n)) } #[inline] @@ -199,7 +213,7 @@ where P: FnMut(&Self::Item) -> bool, { match fuse!(self.b.rfind(&mut predicate)) { - None => fuse!(self.a.rfind(predicate)), + None => maybe!(self.a.rfind(predicate)), item => item, } } @@ -216,7 +230,7 @@ where } if let Some(ref mut a) = self.a { acc = a.try_rfold(acc, f)?; - self.a = None; + // we don't fuse the second iterator } Try::from_ok(acc) } @@ -236,8 +250,6 @@ where } // Note: *both* must be fused to handle double-ended iterators. -// Now that we "fuse" both sides, we *could* implement this unconditionally, -// but we should be cautious about committing to that in the public API. #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Chain where diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 1a1dbcd7b871a..7da02b11676ab 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -207,50 +207,64 @@ fn test_iterator_chain_find() { assert_eq!(iter.next(), None); } -#[test] -fn test_iterator_chain_size_hint() { - struct Iter { - is_empty: bool, - } +struct Toggle { + is_empty: bool, +} - impl Iterator for Iter { - type Item = (); +impl Iterator for Toggle { + type Item = (); - // alternates between `None` and `Some(())` - fn next(&mut self) -> Option { - if self.is_empty { - self.is_empty = false; - None - } else { - self.is_empty = true; - Some(()) - } + // alternates between `None` and `Some(())` + fn next(&mut self) -> Option { + if self.is_empty { + self.is_empty = false; + None + } else { + self.is_empty = true; + Some(()) } + } - fn size_hint(&self) -> (usize, Option) { - if self.is_empty { (0, Some(0)) } else { (1, Some(1)) } - } + fn size_hint(&self) -> (usize, Option) { + if self.is_empty { (0, Some(0)) } else { (1, Some(1)) } } +} - impl DoubleEndedIterator for Iter { - fn next_back(&mut self) -> Option { - self.next() - } +impl DoubleEndedIterator for Toggle { + fn next_back(&mut self) -> Option { + self.next() } +} +#[test] +fn test_iterator_chain_size_hint() { // this chains an iterator of length 0 with an iterator of length 1, // so after calling `.next()` once, the iterator is empty and the // state is `ChainState::Back`. `.size_hint()` should now disregard // the size hint of the left iterator - let mut iter = Iter { is_empty: true }.chain(once(())); + let mut iter = Toggle { is_empty: true }.chain(once(())); assert_eq!(iter.next(), Some(())); assert_eq!(iter.size_hint(), (0, Some(0))); - let mut iter = once(()).chain(Iter { is_empty: true }); + let mut iter = once(()).chain(Toggle { is_empty: true }); assert_eq!(iter.next_back(), Some(())); assert_eq!(iter.size_hint(), (0, Some(0))); } +#[test] +fn test_iterator_chain_unfused() { + // Chain shouldn't be fused in its second iterator, depending on direction + let mut iter = NonFused::new(empty()).chain(Toggle { is_empty: true }); + iter.next().unwrap_none(); + iter.next().unwrap(); + iter.next().unwrap_none(); + + let mut iter = Toggle { is_empty: true }.chain(NonFused::new(empty())); + iter.next_back().unwrap_none(); + iter.next_back().unwrap(); + iter.next_back().unwrap_none(); +} + #[test] fn test_zip_nth() { let xs = [0, 1, 2, 4, 5]; diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 05f958cbe81fe..e7d36d327cd89 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -42,6 +42,7 @@ #![feature(unwrap_infallible)] #![feature(leading_trailing_ones)] #![feature(const_forget)] +#![feature(option_unwrap_none)] extern crate test; diff --git a/src/librustc_error_codes/error_codes/E0751.md b/src/librustc_error_codes/error_codes/E0751.md index a440f82e4b6b3..809b888d92ac3 100644 --- a/src/librustc_error_codes/error_codes/E0751.md +++ b/src/librustc_error_codes/error_codes/E0751.md @@ -2,7 +2,7 @@ There are both a positive and negative trait implementation for the same type. Erroneous code example: -```compile_fail,E0748 +```compile_fail,E0751 trait MyTrait {} impl MyTrait for i32 { } impl !MyTrait for i32 { } diff --git a/src/librustc_infer/infer/outlives/verify.rs b/src/librustc_infer/infer/outlives/verify.rs index 1a601d723cb7b..adf5af6f9dde6 100644 --- a/src/librustc_infer/infer/outlives/verify.rs +++ b/src/librustc_infer/infer/outlives/verify.rs @@ -223,7 +223,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // like `T` and `T::Item`. It may not work as well for things // like `>::Item`. let c_b = self.param_env.caller_bounds; - let param_bounds = self.collect_outlives_from_predicate_list(&compare_ty, c_b); + let param_bounds = self.collect_outlives_from_predicate_list(&compare_ty, c_b.into_iter()); // Next, collect regions we scraped from the well-formedness // constraints in the fn signature. To do that, we walk the list @@ -315,15 +315,12 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { let tcx = self.tcx; let assoc_item = tcx.associated_item(assoc_item_def_id); let trait_def_id = assoc_item.container.assert_trait(); - let trait_predicates = - tcx.predicates_of(trait_def_id).predicates.iter().map(|(p, _)| *p).collect(); + let trait_predicates = tcx.predicates_of(trait_def_id).predicates.iter().map(|(p, _)| *p); let identity_substs = InternalSubsts::identity_for_item(tcx, assoc_item_def_id); let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs); self.collect_outlives_from_predicate_list( move |ty| ty == identity_proj, - traits::elaborate_predicates(tcx, trait_predicates) - .map(|o| o.predicate) - .collect::>(), + traits::elaborate_predicates(tcx, trait_predicates).map(|o| o.predicate), ) .map(|b| b.1) } diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs index 3f63d25fb4723..a1b1975439c3a 100644 --- a/src/librustc_infer/traits/util.rs +++ b/src/librustc_infer/traits/util.rs @@ -97,24 +97,22 @@ pub fn elaborate_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, ) -> Elaborator<'tcx> { - elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()]) + elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate())) } pub fn elaborate_trait_refs<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, ) -> Elaborator<'tcx> { - let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect(); + let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()); elaborate_predicates(tcx, predicates) } pub fn elaborate_predicates<'tcx>( tcx: TyCtxt<'tcx>, - mut predicates: Vec>, + predicates: impl IntoIterator>, ) -> Elaborator<'tcx> { - let mut visited = PredicateSet::new(tcx); - predicates.retain(|pred| visited.insert(pred)); - let obligations: Vec<_> = + let obligations = predicates.into_iter().map(|predicate| predicate_obligation(predicate, None)).collect(); elaborate_obligations(tcx, obligations) } @@ -151,21 +149,20 @@ impl Elaborator<'tcx> { // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); - let obligations = predicates.predicates.iter().map(|(pred, span)| { + let obligations = predicates.predicates.into_iter().map(|(pred, span)| { predicate_obligation( pred.subst_supertrait(tcx, &data.to_poly_trait_ref()), Some(*span), ) }); - debug!("super_predicates: data={:?} predicates={:?}", data, &obligations); + debug!("super_predicates: data={:?}", data); // Only keep those bounds that we haven't already seen. // This is necessary to prevent infinite recursion in some // cases. One common case is when people define // `trait Sized: Sized { }` rather than `trait Sized { }`. let visited = &mut self.visited; - let obligations = - obligations.filter(|obligation| visited.insert(&obligation.predicate)); + let obligations = obligations.filter(|o| visited.insert(&o.predicate)); self.stack.extend(obligations); } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index a3748a3a9fede..ddd252cb290e4 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::{self, Ty}; use rustc_session::lint::builtin::UNUSED_ATTRIBUTES; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; -use rustc_span::{BytePos, Span}; +use rustc_span::{BytePos, Span, DUMMY_SP}; use log::debug; @@ -415,6 +415,12 @@ trait UnusedDelimLint { msg: &str, keep_space: (bool, bool), ) { + // FIXME(flip1995): Quick and dirty fix for #70814. This should be fixed in rustdoc + // properly. + if span == DUMMY_SP { + return; + } + cx.struct_span_lint(self.lint(), span, |lint| { let span_msg = format!("unnecessary {} around {}", Self::DELIM_STR, msg); let mut err = lint.build(&span_msg); diff --git a/src/librustc_middle/ty/trait_def.rs b/src/librustc_middle/ty/trait_def.rs index 912f8be1d3342..3546e5f429ef5 100644 --- a/src/librustc_middle/ty/trait_def.rs +++ b/src/librustc_middle/ty/trait_def.rs @@ -168,15 +168,13 @@ impl<'tcx> TyCtxt<'tcx> { } /// Returns a vector containing all impls - pub fn all_impls(self, def_id: DefId) -> Vec { - let impls = self.trait_impls_of(def_id); + pub fn all_impls(self, def_id: DefId) -> impl Iterator + 'tcx { + let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id); - impls - .blanket_impls - .iter() - .chain(impls.non_blanket_impls.values().flatten()) + blanket_impls + .into_iter() + .chain(non_blanket_impls.into_iter().map(|(_, v)| v).flatten()) .cloned() - .collect() } } diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index bd85b48bf4b98..c5ff89d728b37 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -690,6 +690,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let fty = self.sanitize_type(place, fty); match self.field_ty(place, base, field, location) { Ok(ty) => { + let ty = self.cx.normalize(ty, location); if let Err(terr) = self.cx.eq_types( ty, fty, diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 77a9be0ed35d8..74281d152f499 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -122,8 +122,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { .predicates_of(source.def_id()) .predicates .iter() - .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }) - .collect(); + .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); if !traits::normalize_and_test_predicates( tcx, traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(), diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 67713b5636965..6f6e5fc8659c2 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1522,11 +1522,20 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ident: Ident, has_sub: bool, ) -> Option { + // An immutable (no `mut`) by-value (no `ref`) binding pattern without + // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could + // also be interpreted as a path to e.g. a constant, variant, etc. + let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not); + let ls_binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?; let (res, binding) = match ls_binding { - LexicalScopeBinding::Item(binding) if binding.is_ambiguity() => { + LexicalScopeBinding::Item(binding) + if is_syntactic_ambiguity && binding.is_ambiguity() => + { // For ambiguous bindings we don't know all their definitions and cannot check // whether they can be shadowed by fresh bindings or not, so force an error. + // issues/33118#issuecomment-233962221 (see below) still applies here, + // but we have to ignore it for backward compatibility. self.r.record_use(ident, ValueNS, binding, false); return None; } @@ -1534,11 +1543,6 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { LexicalScopeBinding::Res(res) => (res, None), }; - // An immutable (no `mut`) by-value (no `ref`) binding pattern without - // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could - // also be interpreted as a path to e.g. a constant, variant, etc. - let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not); - match res { Res::SelfCtor(_) // See #70549. | Res::Def( diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index f67b8b87ced5f..7647775eff42a 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -418,7 +418,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs); let required_region_bounds = - required_region_bounds(tcx, opaque_type, bounds.predicates); + required_region_bounds(tcx, opaque_type, bounds.predicates.into_iter()); debug_assert!(!required_region_bounds.is_empty()); for required_region in required_region_bounds { @@ -1127,7 +1127,8 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { debug!("instantiate_opaque_types: bounds={:?}", bounds); - let required_region_bounds = required_region_bounds(tcx, ty, bounds.predicates.clone()); + let required_region_bounds = + required_region_bounds(tcx, ty, bounds.predicates.iter().cloned()); debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds); // Make sure that we are in fact defining the *entire* type @@ -1245,17 +1246,15 @@ pub fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: DefId, opaque_hir_id: hir crate fn required_region_bounds( tcx: TyCtxt<'tcx>, erased_self_ty: Ty<'tcx>, - predicates: Vec>, + predicates: impl Iterator>, ) -> Vec> { - debug!( - "required_region_bounds(erased_self_ty={:?}, predicates={:?})", - erased_self_ty, predicates - ); + debug!("required_region_bounds(erased_self_ty={:?})", erased_self_ty); assert!(!erased_self_ty.has_escaping_bound_vars()); traits::elaborate_predicates(tcx, predicates) .filter_map(|obligation| { + debug!("required_region_bounds(obligation={:?})", obligation); match obligation.predicate { ty::Predicate::Projection(..) | ty::Predicate::Trait(..) diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/src/librustc_trait_selection/traits/auto_trait.rs index 052de4a4e5b55..6326a87c5edc3 100644 --- a/src/librustc_trait_selection/traits/auto_trait.rs +++ b/src/librustc_trait_selection/traits/auto_trait.rs @@ -281,7 +281,7 @@ impl AutoTraitFinder<'tcx> { }, })); - let mut computed_preds: FxHashSet<_> = param_env.caller_bounds.iter().cloned().collect(); + let computed_preds = param_env.caller_bounds.iter().cloned(); let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds.iter().cloned().collect(); @@ -358,10 +358,11 @@ impl AutoTraitFinder<'tcx> { _ => panic!("Unexpected error for '{:?}': {:?}", ty, result), }; - computed_preds.extend(user_computed_preds.iter().cloned()); - let normalized_preds = - elaborate_predicates(tcx, computed_preds.iter().cloned().collect()) - .map(|o| o.predicate); + let normalized_preds = elaborate_predicates( + tcx, + computed_preds.clone().chain(user_computed_preds.iter().cloned()), + ) + .map(|o| o.predicate); new_env = ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal, None); } @@ -739,7 +740,7 @@ impl AutoTraitFinder<'tcx> { if p.ty().skip_binder().has_infer_types() { if !self.evaluate_nested_obligations( ty, - v.clone().iter().cloned(), + v.into_iter(), computed_preds, fresh_preds, predicates, diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index 8a9017960fb23..74cf06d54687d 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -1007,7 +1007,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { } }; - for obligation in super::elaborate_predicates(self.tcx, vec![*cond]) { + for obligation in super::elaborate_predicates(self.tcx, std::iter::once(*cond)) { if let ty::Predicate::Trait(implication, _) = obligation.predicate { let error = error.to_poly_trait_ref(); let implication = implication.to_poly_trait_ref(); @@ -1208,8 +1208,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { match simp { Some(simp) => all_impls - .iter() - .filter_map(|&def_id| { + .filter_map(|def_id| { let imp = self.tcx.impl_trait_ref(def_id).unwrap(); let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true); if let Some(imp_simp) = imp_simp { @@ -1217,13 +1216,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { return None; } } - Some(imp) }) .collect(), - None => { - all_impls.iter().map(|&def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect() - } + None => all_impls.map(|def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect(), } } diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs index f8fc155f582b8..c5dbe81629550 100644 --- a/src/librustc_trait_selection/traits/mod.rs +++ b/src/librustc_trait_selection/traits/mod.rs @@ -110,8 +110,8 @@ pub enum TraitQueryMode { pub fn predicates_for_generics<'tcx>( cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - generic_bounds: &ty::InstantiatedPredicates<'tcx>, -) -> PredicateObligations<'tcx> { + generic_bounds: ty::InstantiatedPredicates<'tcx>, +) -> impl Iterator> { util::predicates_for_generics(cause, 0, param_env, generic_bounds) } @@ -297,7 +297,7 @@ pub fn normalize_param_env_or_error<'tcx>( ); let mut predicates: Vec<_> = - util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec()) + util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.into_iter().cloned()) .map(|obligation| obligation.predicate) .collect(); diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs index d9fba1fd78392..96b2b904e6543 100644 --- a/src/librustc_trait_selection/traits/object_safety.rs +++ b/src/librustc_trait_selection/traits/object_safety.rs @@ -302,7 +302,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // Search for a predicate like `Self : Sized` amongst the trait bounds. let predicates = tcx.predicates_of(def_id); let predicates = predicates.instantiate_identity(tcx).predicates; - elaborate_predicates(tcx, predicates).any(|obligation| match obligation.predicate { + elaborate_predicates(tcx, predicates.into_iter()).any(|obligation| match obligation.predicate { ty::Predicate::Trait(ref trait_pred, _) => { trait_pred.def_id() == sized_def_id && trait_pred.skip_binder().self_ty().is_param(0) } diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 4d02c5eb2301d..2b4a0409fd1e2 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -900,7 +900,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( // If so, extract what we know from the trait and try to come up with a good answer. let trait_predicates = tcx.predicates_of(def_id); let bounds = trait_predicates.instantiate(tcx, substs); - let bounds = elaborate_predicates(tcx, bounds.predicates).map(|o| o.predicate); + let bounds = elaborate_predicates(tcx, bounds.predicates.into_iter()).map(|o| o.predicate); assemble_candidates_from_predicates( selcx, obligation, @@ -911,16 +911,14 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( ) } -fn assemble_candidates_from_predicates<'cx, 'tcx, I>( +fn assemble_candidates_from_predicates<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, obligation_trait_ref: &ty::TraitRef<'tcx>, candidate_set: &mut ProjectionTyCandidateSet<'tcx>, ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionTyCandidate<'tcx>, - env_predicates: I, -) where - I: IntoIterator>, -{ + env_predicates: impl Iterator>, +) { debug!("assemble_candidates_from_predicates(obligation={:?})", obligation); let infcx = selcx.infcx(); for predicate in env_predicates { @@ -1153,10 +1151,8 @@ fn confirm_object_candidate<'cx, 'tcx>( object_ty ), }; - let env_predicates = data - .projection_bounds() - .map(|p| p.with_self_ty(selcx.tcx(), object_ty).to_predicate()) - .collect(); + let env_predicates = + data.projection_bounds().map(|p| p.with_self_ty(selcx.tcx(), object_ty).to_predicate()); let env_predicate = { let env_predicates = elaborate_predicates(selcx.tcx(), env_predicates); diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs index 45fda3004b09b..dfbb07424487d 100644 --- a/src/librustc_trait_selection/traits/select.rs +++ b/src/librustc_trait_selection/traits/select.rs @@ -1443,7 +1443,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { bounds ); - let elaborated_predicates = util::elaborate_predicates(self.tcx(), bounds.predicates); + let elaborated_predicates = + util::elaborate_predicates(self.tcx(), bounds.predicates.into_iter()); let matching_bound = elaborated_predicates.filter_to_traits().find(|bound| { self.infcx.probe(|_| { self.match_projection( diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs index fabd8c89b72af..5ecd956e59c6f 100644 --- a/src/librustc_trait_selection/traits/specialize/mod.rs +++ b/src/librustc_trait_selection/traits/specialize/mod.rs @@ -189,26 +189,22 @@ fn fulfill_implication<'a, 'tcx>( let selcx = &mut SelectionContext::new(&infcx); let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl); - let (target_trait_ref, mut obligations) = + let (target_trait_ref, obligations) = impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs); - debug!( - "fulfill_implication: target_trait_ref={:?}, obligations={:?}", - target_trait_ref, obligations - ); // do the impls unify? If not, no specialization. - match infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref) { - Ok(InferOk { obligations: o, .. }) => { - obligations.extend(o); - } - Err(_) => { - debug!( - "fulfill_implication: {:?} does not unify with {:?}", - source_trait_ref, target_trait_ref - ); - return Err(()); - } - } + let more_obligations = + match infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref) + { + Ok(InferOk { obligations, .. }) => obligations, + Err(_) => { + debug!( + "fulfill_implication: {:?} does not unify with {:?}", + source_trait_ref, target_trait_ref + ); + return Err(()); + } + }; // attempt to prove all of the predicates for impl2 given those for impl1 // (which are packed up in penv) @@ -226,7 +222,7 @@ fn fulfill_implication<'a, 'tcx>( // we already make a mockery out of the region system, so // why not ignore them a bit earlier? let mut fulfill_cx = FulfillmentContext::new_ignoring_regions(); - for oblig in obligations.into_iter() { + for oblig in obligations.chain(more_obligations) { fulfill_cx.register_predicate_obligation(&infcx, oblig); } match fulfill_cx.select_all_or_error(infcx) { @@ -261,7 +257,7 @@ pub(super) fn specialization_graph_provider( ) -> &specialization_graph::Graph { let mut sg = specialization_graph::Graph::new(); - let mut trait_impls = tcx.all_impls(trait_id); + let mut trait_impls: Vec<_> = tcx.all_impls(trait_id).collect(); // The coherence checking implementation seems to rely on impls being // iterated over (roughly) in definition order, so we are sorting by @@ -345,7 +341,7 @@ fn report_negative_positive_conflict( let mut err = struct_span_err!( tcx.sess, impl_span, - E0748, + E0751, "found both positive and negative implementation of trait `{}`{}:", overlap.trait_desc, overlap.self_desc.clone().map_or(String::new(), |ty| format!(" for type `{}`", ty)) diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs index ffece42ec306c..4aceccf64ce65 100644 --- a/src/librustc_trait_selection/traits/util.rs +++ b/src/librustc_trait_selection/traits/util.rs @@ -81,12 +81,10 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> { pub fn expand_trait_aliases<'tcx>( tcx: TyCtxt<'tcx>, - trait_refs: impl IntoIterator, Span)>, + trait_refs: impl Iterator, Span)>, ) -> TraitAliasExpander<'tcx> { - let items: Vec<_> = trait_refs - .into_iter() - .map(|(trait_ref, span)| TraitAliasExpansionInfo::new(trait_ref, span)) - .collect(); + let items: Vec<_> = + trait_refs.map(|(trait_ref, span)| TraitAliasExpansionInfo::new(trait_ref, span)).collect(); TraitAliasExpander { tcx, stack: items } } @@ -199,7 +197,7 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>( param_env: ty::ParamEnv<'tcx>, impl_def_id: DefId, impl_substs: SubstsRef<'tcx>, -) -> (ty::TraitRef<'tcx>, Vec>) { +) -> (ty::TraitRef<'tcx>, impl Iterator>) { let impl_trait_ref = selcx.tcx().impl_trait_ref(impl_def_id).unwrap(); let impl_trait_ref = impl_trait_ref.subst(selcx.tcx(), impl_substs); let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } = @@ -210,13 +208,11 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>( let Normalized { value: predicates, obligations: normalization_obligations2 } = super::normalize(selcx, param_env, ObligationCause::dummy(), &predicates); let impl_obligations = - predicates_for_generics(ObligationCause::dummy(), 0, param_env, &predicates); + predicates_for_generics(ObligationCause::dummy(), 0, param_env, predicates); - let impl_obligations: Vec<_> = impl_obligations - .into_iter() - .chain(normalization_obligations1) - .chain(normalization_obligations2) - .collect(); + let impl_obligations = impl_obligations + .chain(normalization_obligations1.into_iter()) + .chain(normalization_obligations2.into_iter()); (impl_trait_ref, impl_obligations) } @@ -226,20 +222,16 @@ pub fn predicates_for_generics<'tcx>( cause: ObligationCause<'tcx>, recursion_depth: usize, param_env: ty::ParamEnv<'tcx>, - generic_bounds: &ty::InstantiatedPredicates<'tcx>, -) -> Vec> { + generic_bounds: ty::InstantiatedPredicates<'tcx>, +) -> impl Iterator> { debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); - generic_bounds - .predicates - .iter() - .map(|&predicate| Obligation { - cause: cause.clone(), - recursion_depth, - param_env, - predicate, - }) - .collect() + generic_bounds.predicates.into_iter().map(move |predicate| Obligation { + cause: cause.clone(), + recursion_depth, + param_env, + predicate, + }) } pub fn predicate_for_trait_ref<'tcx>( diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs index f6953971ef5bc..7eabdf706ef9f 100644 --- a/src/librustc_trait_selection/traits/wf.rs +++ b/src/librustc_trait_selection/traits/wf.rs @@ -140,7 +140,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( item: Option<&hir::Item<'tcx>>, cause: &mut traits::ObligationCause<'tcx>, pred: &ty::Predicate<'_>, - mut trait_assoc_items: impl Iterator, + mut trait_assoc_items: impl Iterator, ) { debug!( "extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}", @@ -232,35 +232,34 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let item = self.item; + let extend = |obligation: traits::PredicateObligation<'tcx>| { + let mut cause = cause.clone(); + if let Some(parent_trait_ref) = obligation.predicate.to_opt_poly_trait_ref() { + let derived_cause = traits::DerivedObligationCause { + parent_trait_ref, + parent_code: Rc::new(obligation.cause.code.clone()), + }; + cause.code = traits::ObligationCauseCode::DerivedObligation(derived_cause); + } + extend_cause_with_original_assoc_item_obligation( + tcx, + trait_ref, + item, + &mut cause, + &obligation.predicate, + tcx.associated_items(trait_ref.def_id).in_definition_order(), + ); + traits::Obligation::new(cause, param_env, obligation.predicate) + }; + if let Elaborate::All = elaborate { - let implied_obligations = traits::util::elaborate_obligations(tcx, obligations.clone()); - let implied_obligations = implied_obligations.map(|obligation| { - debug!("compute_trait_ref implied_obligation {:?}", obligation); - debug!("compute_trait_ref implied_obligation cause {:?}", obligation.cause); - let mut cause = cause.clone(); - if let Some(parent_trait_ref) = obligation.predicate.to_opt_poly_trait_ref() { - let derived_cause = traits::DerivedObligationCause { - parent_trait_ref, - parent_code: Rc::new(obligation.cause.code.clone()), - }; - cause.code = traits::ObligationCauseCode::DerivedObligation(derived_cause); - } - extend_cause_with_original_assoc_item_obligation( - tcx, - trait_ref, - item, - &mut cause, - &obligation.predicate, - tcx.associated_items(trait_ref.def_id).in_definition_order().copied(), - ); - debug!("compute_trait_ref new cause {:?}", cause); - traits::Obligation::new(cause, param_env, obligation.predicate) - }); + let implied_obligations = traits::util::elaborate_obligations(tcx, obligations); + let implied_obligations = implied_obligations.map(extend); self.out.extend(implied_obligations); + } else { + self.out.extend(obligations); } - self.out.extend(obligations); - self.out.extend(trait_ref.substs.types().filter(|ty| !ty.has_escaping_bound_vars()).map( |ty| traits::Obligation::new(cause.clone(), param_env, ty::Predicate::WellFormed(ty)), )); @@ -627,16 +626,13 @@ pub fn object_region_bounds<'tcx>( // a placeholder type. let open_ty = tcx.mk_ty_infer(ty::FreshTy(0)); - let predicates = existential_predicates - .iter() - .filter_map(|predicate| { - if let ty::ExistentialPredicate::Projection(_) = *predicate.skip_binder() { - None - } else { - Some(predicate.with_self_ty(tcx, open_ty)) - } - }) - .collect(); + let predicates = existential_predicates.iter().filter_map(|predicate| { + if let ty::ExistentialPredicate::Projection(_) = *predicate.skip_binder() { + None + } else { + Some(predicate.with_self_ty(tcx, open_ty)) + } + }); required_region_bounds(tcx, open_ty, predicates) } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 3f81689cdc90f..22c81ece39181 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -114,7 +114,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // a custom error in that case. if illegal_sized_bound.is_none() { let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig)); - self.add_obligations(method_ty, all_substs, &method_predicates); + self.add_obligations(method_ty, all_substs, method_predicates); } // Create the final `MethodCallee`. @@ -395,7 +395,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { &mut self, fty: Ty<'tcx>, all_substs: SubstsRef<'tcx>, - method_predicates: &ty::InstantiatedPredicates<'tcx>, + method_predicates: ty::InstantiatedPredicates<'tcx>, ) { debug!( "add_obligations: fty={:?} all_substs={:?} method_predicates={:?}", @@ -572,7 +572,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { None => return None, }; - traits::elaborate_predicates(self.tcx, predicates.predicates.clone()) + traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied()) .filter_map(|obligation| match obligation.predicate { ty::Predicate::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => { let span = predicates diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index c4f53332cb673..65e9abcd14644 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -390,7 +390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { assert!(!bounds.has_escaping_bound_vars()); let cause = traits::ObligationCause::misc(span, self.body_id); - obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, &bounds)); + obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds)); // Also add an obligation for the method type being well-formed. let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig)); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 3f159fe5e3029..03e32c21a54ac 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1342,7 +1342,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // clauses) that must be considered. Make sure that those // match as well (or at least may match, sometimes we // don't have enough information to fully evaluate). - let candidate_obligations: Vec<_> = match probe.kind { + match probe.kind { InherentImplCandidate(ref substs, ref ref_obligations) => { // Check whether the impl imposes obligations we have to worry about. let impl_def_id = probe.item.container.id(); @@ -1353,19 +1353,23 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Convert the bounds into obligations. let impl_obligations = - traits::predicates_for_generics(cause, self.param_env, &impl_bounds); + traits::predicates_for_generics(cause, self.param_env, impl_bounds); - debug!("impl_obligations={:?}", impl_obligations); - impl_obligations - .into_iter() + let candidate_obligations = impl_obligations .chain(norm_obligations.into_iter()) - .chain(ref_obligations.iter().cloned()) - .collect() + .chain(ref_obligations.iter().cloned()); + // Evaluate those obligations to see if they might possibly hold. + for o in candidate_obligations { + let o = self.resolve_vars_if_possible(&o); + if !self.predicate_may_hold(&o) { + result = ProbeResult::NoMatch; + possibly_unsatisfied_predicates.push((o.predicate, None)); + } + } } ObjectCandidate | WhereClauseCandidate(..) => { // These have no additional conditions to check. - vec![] } TraitCandidate(trait_ref) => { @@ -1412,17 +1416,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return ProbeResult::NoMatch; } } - vec![] } - }; - - debug!( - "consider_probe - candidate_obligations={:?} sub_obligations={:?}", - candidate_obligations, sub_obligations - ); + } // Evaluate those obligations to see if they might possibly hold. - for o in candidate_obligations.into_iter().chain(sub_obligations) { + for o in sub_obligations { let o = self.resolve_vars_if_possible(&o); if !self.predicate_may_hold(&o) { result = ProbeResult::NoMatch; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1be8d258dcb18..ec5d3331956e5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3434,7 +3434,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn add_obligations_for_parameters( &self, cause: traits::ObligationCause<'tcx>, - predicates: &ty::InstantiatedPredicates<'tcx>, + predicates: ty::InstantiatedPredicates<'tcx>, ) { assert!(!predicates.has_escaping_bound_vars()); @@ -4385,7 +4385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (bounds, _) = self.instantiate_bounds(path_span, did, substs); let cause = traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did)); - self.add_obligations_for_parameters(cause, &bounds); + self.add_obligations_for_parameters(cause, bounds); Some((variant, ty)) } else { @@ -5654,9 +5654,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (i, mut obligation) in traits::predicates_for_generics( traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)), self.param_env, - &bounds, + bounds, ) - .into_iter() .enumerate() { // This makes the error point at the bound, but we want to point at the argument diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index cac9113fd5d30..23004cf364725 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -251,7 +251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Err(()) => { // error types are considered "builtin" - if !lhs_ty.references_error() { + if !lhs_ty.references_error() && !rhs_ty.references_error() { let source_map = self.tcx.sess.source_map(); match is_assign { IsAssign::Yes => { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 32004744ff950..d537891c0d739 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -1225,7 +1225,7 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) { let empty_env = ty::ParamEnv::empty(); let def_id = fcx.tcx.hir().local_def_id(id); - let predicates = fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, _)| *p).collect(); + let predicates = fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, _)| *p); // Check elaborated bounds. let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates); diff --git a/src/librustc_typeck/impl_wf_check/min_specialization.rs b/src/librustc_typeck/impl_wf_check/min_specialization.rs index ebfb3684eb0d6..076c13d106576 100644 --- a/src/librustc_typeck/impl_wf_check/min_specialization.rs +++ b/src/librustc_typeck/impl_wf_check/min_specialization.rs @@ -322,7 +322,7 @@ fn check_predicates<'tcx>( // which is sound because we forbid impls like the following // // impl AlwaysApplicable for D { } - let always_applicable_traits: Vec<_> = impl1_predicates + let always_applicable_traits = impl1_predicates .predicates .iter() .filter(|predicate| { @@ -331,8 +331,7 @@ fn check_predicates<'tcx>( Some(TraitSpecializationKind::AlwaysApplicable) ) }) - .copied() - .collect(); + .copied(); // Include the well-formed predicates of the type parameters of the impl. for ty in tcx.impl_trait_ref(impl1_def_id).unwrap().substs.types() { diff --git a/src/stage0.txt b/src/stage0.txt index 920b0e3bef1c6..de57423fd1a56 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,8 +12,8 @@ # 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: 2020-04-21 -rustc: 1.43.0 +date: 2020-05-07 +rustc: 1.43.1 cargo: 0.44.0 # We use a nightly rustfmt to format the source because it solves some @@ -40,4 +40,4 @@ cargo: 0.44.0 # looking at a beta source tarball and it's uncommented we'll shortly comment it # out. -dev: 1 +#dev: 1 diff --git a/src/stdarch b/src/stdarch index b00ecbeb268ee..d10eefc62284c 160000 --- a/src/stdarch +++ b/src/stdarch @@ -1 +1 @@ -Subproject commit b00ecbeb268ee97cef9fa9b2375e6f6cf0864db2 +Subproject commit d10eefc62284c40c5a95a2eed19fc1f414a5364d diff --git a/src/test/rustdoc-ui/unused-braces-lint.rs b/src/test/rustdoc-ui/unused-braces-lint.rs new file mode 100644 index 0000000000000..be0e31e4be2ff --- /dev/null +++ b/src/test/rustdoc-ui/unused-braces-lint.rs @@ -0,0 +1,14 @@ +// check-pass + +// This tests the bug in #70814, where the unused_braces lint triggered on the following code +// without providing a span. + +#![deny(unused_braces)] + +fn main() { + { + { + use std; + } + } +} diff --git a/src/test/ui/binding/ambiguity-item.rs b/src/test/ui/binding/ambiguity-item.rs index 10613cc616413..0f48340c2cd33 100644 --- a/src/test/ui/binding/ambiguity-item.rs +++ b/src/test/ui/binding/ambiguity-item.rs @@ -14,5 +14,6 @@ fn main() { let v = f; //~ ERROR `f` is ambiguous match v { f => {} //~ ERROR `f` is ambiguous + mut f => {} // OK, unambiguously a fresh binding due to `mut` } } diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr index 5081536b70245..4d9f815c79581 100644 --- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr +++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr @@ -1,4 +1,4 @@ -error[E0748]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: +error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: --> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1 | LL | unsafe impl Send for TestType {} @@ -18,5 +18,5 @@ LL | unsafe impl Send for TestType {} error: aborting due to 2 previous errors -Some errors have detailed explanations: E0119, E0748. +Some errors have detailed explanations: E0119, E0751. For more information about an error, try `rustc --explain E0119`. diff --git a/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs b/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs index 07af83104241c..9d44aa1361cfc 100644 --- a/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs +++ b/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs @@ -7,6 +7,7 @@ fn init_hash(_: &mut [u8; HASH_LEN]) {} fn foo<'a>() -> &'a () { Hash([0; HASH_LEN]); init_hash(&mut [0; HASH_LEN]); + let (_array,) = ([0; HASH_LEN],); &() } diff --git a/src/test/ui/issues-71798.rs b/src/test/ui/issues-71798.rs new file mode 100644 index 0000000000000..08b10463d3927 --- /dev/null +++ b/src/test/ui/issues-71798.rs @@ -0,0 +1,7 @@ +fn test_ref(x: &u32) -> impl std::future::Future + '_ { + *x //~^ ERROR the trait bound `u32: std::future::Future` is not satisfied +} + +fn main() { + let _ = test_ref & u; //~ ERROR cannot find value `u` in this scope +} diff --git a/src/test/ui/issues-71798.stderr b/src/test/ui/issues-71798.stderr new file mode 100644 index 0000000000000..85da87914e768 --- /dev/null +++ b/src/test/ui/issues-71798.stderr @@ -0,0 +1,20 @@ +error[E0425]: cannot find value `u` in this scope + --> $DIR/issues-71798.rs:6:24 + | +LL | let _ = test_ref & u; + | ^ not found in this scope + +error[E0277]: the trait bound `u32: std::future::Future` is not satisfied + --> $DIR/issues-71798.rs:1:25 + | +LL | fn test_ref(x: &u32) -> impl std::future::Future + '_ { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `u32` +LL | *x + | -- this returned value is of type `u32` + | + = note: the return type of a function must have a statically known size + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0425. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-33140-hack-boundaries.rs b/src/test/ui/issues/issue-33140-hack-boundaries.rs index 5984a256a3086..d091162fced6b 100644 --- a/src/test/ui/issues/issue-33140-hack-boundaries.rs +++ b/src/test/ui/issues/issue-33140-hack-boundaries.rs @@ -23,7 +23,7 @@ trait Trait2 {} impl Trait2 for dyn Send {} impl !Trait2 for dyn Send {} -//~^ ERROR E0748 +//~^ ERROR E0751 // Problem 3: type parameter trait Trait3 {} diff --git a/src/test/ui/issues/issue-33140-hack-boundaries.stderr b/src/test/ui/issues/issue-33140-hack-boundaries.stderr index b3bf34a2a9031..ae65701ecb52a 100644 --- a/src/test/ui/issues/issue-33140-hack-boundaries.stderr +++ b/src/test/ui/issues/issue-33140-hack-boundaries.stderr @@ -6,7 +6,7 @@ LL | impl Trait1 for dyn Send {} LL | impl Trait1 for dyn Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` -error[E0748]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`: +error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`: --> $DIR/issue-33140-hack-boundaries.rs:25:1 | LL | impl Trait2 for dyn Send {} @@ -64,5 +64,5 @@ LL | impl Trait5 for dyn Send where u32: Copy {} error: aborting due to 8 previous errors -Some errors have detailed explanations: E0119, E0748. +Some errors have detailed explanations: E0119, E0751. For more information about an error, try `rustc --explain E0119`. diff --git a/src/test/ui/specialization/specialization-overlap-negative.rs b/src/test/ui/specialization/specialization-overlap-negative.rs index dff2b28bf003c..90dbef3075b7f 100644 --- a/src/test/ui/specialization/specialization-overlap-negative.rs +++ b/src/test/ui/specialization/specialization-overlap-negative.rs @@ -6,6 +6,6 @@ trait MyTrait {} struct TestType(::std::marker::PhantomData); unsafe impl Send for TestType {} -impl !Send for TestType {} //~ ERROR E0748 +impl !Send for TestType {} //~ ERROR E0751 fn main() {} diff --git a/src/test/ui/specialization/specialization-overlap-negative.stderr b/src/test/ui/specialization/specialization-overlap-negative.stderr index cbc7271b199a6..e2616534d2041 100644 --- a/src/test/ui/specialization/specialization-overlap-negative.stderr +++ b/src/test/ui/specialization/specialization-overlap-negative.stderr @@ -1,4 +1,4 @@ -error[E0748]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: +error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: --> $DIR/specialization-overlap-negative.rs:9:1 | LL | unsafe impl Send for TestType {} @@ -8,4 +8,4 @@ LL | impl !Send for TestType {} error: aborting due to previous error -For more information about this error, try `rustc --explain E0748`. +For more information about this error, try `rustc --explain E0751`. diff --git a/src/test/ui/specialization/specialization-polarity.rs b/src/test/ui/specialization/specialization-polarity.rs index 4a733fb3c497e..e78035f171075 100644 --- a/src/test/ui/specialization/specialization-polarity.rs +++ b/src/test/ui/specialization/specialization-polarity.rs @@ -7,11 +7,11 @@ auto trait Foo {} impl Foo for T {} -impl !Foo for u8 {} //~ ERROR E0748 +impl !Foo for u8 {} //~ ERROR E0751 auto trait Bar {} impl !Bar for T {} -impl Bar for u8 {} //~ ERROR E0748 +impl Bar for u8 {} //~ ERROR E0751 fn main() {} diff --git a/src/test/ui/specialization/specialization-polarity.stderr b/src/test/ui/specialization/specialization-polarity.stderr index 30655d87d5500..44e60cad67aa4 100644 --- a/src/test/ui/specialization/specialization-polarity.stderr +++ b/src/test/ui/specialization/specialization-polarity.stderr @@ -1,4 +1,4 @@ -error[E0748]: found both positive and negative implementation of trait `Foo` for type `u8`: +error[E0751]: found both positive and negative implementation of trait `Foo` for type `u8`: --> $DIR/specialization-polarity.rs:10:1 | LL | impl Foo for T {} @@ -6,7 +6,7 @@ LL | impl Foo for T {} LL | impl !Foo for u8 {} | ^^^^^^^^^^^^^^^^ negative implementation here -error[E0748]: found both positive and negative implementation of trait `Bar` for type `u8`: +error[E0751]: found both positive and negative implementation of trait `Bar` for type `u8`: --> $DIR/specialization-polarity.rs:15:1 | LL | impl !Bar for T {} @@ -16,4 +16,4 @@ LL | impl Bar for u8 {} error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0748`. +For more information about this error, try `rustc --explain E0751`. diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.rs b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.rs index 043273e624189..da22e43377f52 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.rs +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.rs @@ -8,6 +8,6 @@ trait MyTrait { impl MyTrait for T { default fn foo() {} } -impl !MyTrait for u32 {} //~ ERROR E0748 +impl !MyTrait for u32 {} //~ ERROR E0751 fn main() {} diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr index 21fd08251d474..079546a7df40b 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr @@ -1,4 +1,4 @@ -error[E0748]: found both positive and negative implementation of trait `MyTrait` for type `u32`: +error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/negative-specializes-positive-item.rs:11:1 | LL | impl MyTrait for T { @@ -9,4 +9,4 @@ LL | impl !MyTrait for u32 {} error: aborting due to previous error -For more information about this error, try `rustc --explain E0748`. +For more information about this error, try `rustc --explain E0751`. diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive.rs b/src/test/ui/traits/negative-impls/negative-specializes-positive.rs index ac0fac10eef50..1939a098b50ee 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive.rs +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive.rs @@ -4,7 +4,7 @@ // Negative impl for u32 cannot "specialize" the base impl. trait MyTrait {} impl MyTrait for T {} -impl !MyTrait for u32 {} //~ ERROR E0748 +impl !MyTrait for u32 {} //~ ERROR E0751 // The second impl specializes the first, no error. trait MyTrait2 {} diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr b/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr index 0e7426c826028..ea005c1cbe0c6 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr @@ -1,4 +1,4 @@ -error[E0748]: found both positive and negative implementation of trait `MyTrait` for type `u32`: +error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/negative-specializes-positive.rs:7:1 | LL | impl MyTrait for T {} @@ -8,4 +8,4 @@ LL | impl !MyTrait for u32 {} error: aborting due to previous error -For more information about this error, try `rustc --explain E0748`. +For more information about this error, try `rustc --explain E0751`. diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs index d9c498fca6645..499ac461e59a5 100644 --- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs +++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs @@ -5,7 +5,7 @@ use std::pin::Pin; struct MyType<'a>(Cell>>, PhantomPinned); impl<'a> Clone for &'a mut MyType<'a> { - //~^ ERROR E0748 + //~^ ERROR E0751 fn clone(&self) -> &'a mut MyType<'a> { self.0.replace(None).unwrap() } diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr index f3305722cf2d3..d7039e3db6bde 100644 --- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr +++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr @@ -1,4 +1,4 @@ -error[E0748]: found both positive and negative implementation of trait `std::clone::Clone` for type `&mut MyType<'_>`: +error[E0751]: found both positive and negative implementation of trait `std::clone::Clone` for type `&mut MyType<'_>`: --> $DIR/pin-unsound-issue-66544-clone.rs:7:1 | LL | impl<'a> Clone for &'a mut MyType<'a> { @@ -8,4 +8,4 @@ LL | impl<'a> Clone for &'a mut MyType<'a> { error: aborting due to previous error -For more information about this error, try `rustc --explain E0748`. +For more information about this error, try `rustc --explain E0751`. diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs index cc27c301ffa9d..245be80078056 100644 --- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs +++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs @@ -10,7 +10,7 @@ use std::pin::Pin; struct MyType<'a>(Cell>>, PhantomPinned); impl<'a> DerefMut for &'a MyType<'a> { - //~^ ERROR E0748 + //~^ ERROR E0751 fn deref_mut(&mut self) -> &mut MyType<'a> { self.0.replace(None).unwrap() } diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr index 4e71c2468246b..a0b62a8bab68f 100644 --- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr +++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr @@ -1,4 +1,4 @@ -error[E0748]: found both positive and negative implementation of trait `std::ops::DerefMut` for type `&MyType<'_>`: +error[E0751]: found both positive and negative implementation of trait `std::ops::DerefMut` for type `&MyType<'_>`: --> $DIR/pin-unsound-issue-66544-derefmut.rs:12:1 | LL | impl<'a> DerefMut for &'a MyType<'a> { @@ -8,4 +8,4 @@ LL | impl<'a> DerefMut for &'a MyType<'a> { error: aborting due to previous error -For more information about this error, try `rustc --explain E0748`. +For more information about this error, try `rustc --explain E0751`. diff --git a/src/test/ui/traits/negative-impls/positive-specializes-negative.rs b/src/test/ui/traits/negative-impls/positive-specializes-negative.rs index eac4c24d5d3d0..f2c5f507a4ebb 100644 --- a/src/test/ui/traits/negative-impls/positive-specializes-negative.rs +++ b/src/test/ui/traits/negative-impls/positive-specializes-negative.rs @@ -4,6 +4,6 @@ trait MyTrait {} impl !MyTrait for T {} -impl MyTrait for u32 {} //~ ERROR E0748 +impl MyTrait for u32 {} //~ ERROR E0751 fn main() {} diff --git a/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr b/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr index ab371945a7eab..a24d7aa442f4a 100644 --- a/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr +++ b/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr @@ -1,4 +1,4 @@ -error[E0748]: found both positive and negative implementation of trait `MyTrait` for type `u32`: +error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/positive-specializes-negative.rs:7:1 | LL | impl !MyTrait for T {} @@ -8,4 +8,4 @@ LL | impl MyTrait for u32 {} error: aborting due to previous error -For more information about this error, try `rustc --explain E0748`. +For more information about this error, try `rustc --explain E0751`. diff --git a/src/tools/cargo b/src/tools/cargo index ebda5065ee8a1..05d080faa4f2b 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit ebda5065ee8a1e46801380abcbac21a25bc7e755 +Subproject commit 05d080faa4f2bc1e389ea7c4fd8f30ed2b733a7f diff --git a/src/tools/clippy b/src/tools/clippy index 891e1a859b524..d4092ace00d60 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 891e1a859b52486936e021235fdc36fbdd9b4100 +Subproject commit d4092ace00d60634bcdc22135d82e05a53971263