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