diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index 6b7d0e1f204b5..00d75be439964 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -72,13 +72,9 @@ impl Path {
) -> ast::Path {
let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect();
let lt = mk_lifetimes(cx, span, &self.lifetime);
- let tys: Vec
> =
- self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
- let params = lt
- .into_iter()
- .map(GenericArg::Lifetime)
- .chain(tys.into_iter().map(GenericArg::Type))
- .collect();
+ let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics));
+ let params =
+ lt.into_iter().map(GenericArg::Lifetime).chain(tys.map(GenericArg::Type)).collect();
match self.kind {
PathKind::Global => cx.path_all(span, true, idents, params),
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 16151e9dca5e0..4467980054f54 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -24,6 +24,7 @@
#![feature(new_uninit)]
#![feature(once_cell)]
#![feature(maybe_uninit_uninit_array)]
+#![feature(min_type_alias_impl_trait)]
#![allow(rustc::default_hash_types)]
#![deny(unaligned_references)]
diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs
index 1786fa340cc8b..e3fa587985df0 100644
--- a/compiler/rustc_data_structures/src/vec_map.rs
+++ b/compiler/rustc_data_structures/src/vec_map.rs
@@ -1,6 +1,6 @@
use std::borrow::Borrow;
use std::iter::FromIterator;
-use std::slice::{Iter, IterMut};
+use std::slice::Iter;
use std::vec::IntoIter;
use crate::stable_hasher::{HashStable, StableHasher};
@@ -67,9 +67,13 @@ where
self.into_iter()
}
- pub fn iter_mut(&mut self) -> IterMut<'_, (K, V)> {
+ pub fn iter_mut(&mut self) -> impl Iterator- {
self.into_iter()
}
+
+ pub fn retain(&mut self, f: impl Fn(&(K, V)) -> bool) {
+ self.0.retain(f)
+ }
}
impl Default for VecMap {
@@ -108,12 +112,12 @@ impl<'a, K, V> IntoIterator for &'a VecMap {
}
impl<'a, K, V> IntoIterator for &'a mut VecMap {
- type Item = &'a mut (K, V);
- type IntoIter = IterMut<'a, (K, V)>;
+ type Item = (&'a K, &'a mut V);
+ type IntoIter = impl Iterator
- ;
#[inline]
fn into_iter(self) -> Self::IntoIter {
- self.0.iter_mut()
+ self.0.iter_mut().map(|(k, v)| (&*k, v))
}
}
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index df162f8dce026..902c7c4787323 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -418,6 +418,7 @@ E0716: include_str!("./error_codes/E0716.md"),
E0718: include_str!("./error_codes/E0718.md"),
E0719: include_str!("./error_codes/E0719.md"),
E0720: include_str!("./error_codes/E0720.md"),
+E0722: include_str!("./error_codes/E0722.md"),
E0724: include_str!("./error_codes/E0724.md"),
E0725: include_str!("./error_codes/E0725.md"),
E0727: include_str!("./error_codes/E0727.md"),
@@ -634,7 +635,6 @@ E0783: include_str!("./error_codes/E0783.md"),
E0711, // a feature has been declared with conflicting stability attributes
E0717, // rustc_promotable without stability attribute
// E0721, // `await` keyword
- E0722, // Malformed `#[optimize]` attribute
// E0723, unstable feature in `const` context
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0722.md b/compiler/rustc_error_codes/src/error_codes/E0722.md
new file mode 100644
index 0000000000000..570717a92bd79
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0722.md
@@ -0,0 +1,31 @@
+The `optimize` attribute was malformed.
+
+Erroneous code example:
+
+```compile_fail,E0722
+#![feature(optimize_attribute)]
+
+#[optimize(something)] // error: invalid argument
+pub fn something() {}
+```
+
+The `#[optimize]` attribute should be used as follows:
+
+- `#[optimize(size)]` -- instructs the optimization pipeline to generate code
+ that's smaller rather than faster
+
+- `#[optimize(speed)]` -- instructs the optimization pipeline to generate code
+ that's faster rather than smaller
+
+For example:
+
+```
+#![feature(optimize_attribute)]
+
+#[optimize(size)]
+pub fn something() {}
+```
+
+See [RFC 2412] for more details.
+
+[RFC 2412]: https://rust-lang.github.io/rfcs/2412-optimize-attr.html
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 5c7d10560ca91..6aff2fdbd1f22 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3060,6 +3060,27 @@ impl<'hir> Node<'hir> {
Node::Crate(_) | Node::Visibility(_) => None,
}
}
+
+ /// Returns `Constness::Const` when this node is a const fn/impl.
+ pub fn constness(&self) -> Constness {
+ match self {
+ Node::Item(Item {
+ kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+ ..
+ })
+ | Node::TraitItem(TraitItem {
+ kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+ ..
+ })
+ | Node::ImplItem(ImplItem {
+ kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+ ..
+ })
+ | Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness,
+
+ _ => Constness::NotConst,
+ }
+ }
}
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 670129937be2b..426db95aca16e 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2130,7 +2130,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let new_lt = generics
.as_ref()
.and_then(|(parent_g, g)| {
- let possible: Vec<_> = (b'a'..=b'z').map(|c| format!("'{}", c as char)).collect();
+ let mut possible = (b'a'..=b'z').map(|c| format!("'{}", c as char));
let mut lts_names = g
.params
.iter()
@@ -2146,7 +2146,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
);
}
let lts = lts_names.iter().map(|s| -> &str { &*s }).collect::>();
- possible.into_iter().find(|candidate| !lts.contains(&candidate.as_str()))
+ possible.find(|candidate| !lts.contains(&candidate.as_str()))
})
.unwrap_or("'lt".to_string());
let add_lt_sugg = generics
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index ae53f1ac3bb49..392372fad531e 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -29,7 +29,10 @@ fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
| Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl),
- Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. }) => Some(fn_decl),
+ Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. })
+ | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => {
+ Some(fn_decl)
+ }
_ => None,
}
}
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index cb99ae19ee72e..0908b6a1763d5 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1722,7 +1722,7 @@ rustc_queries! {
/// span) for an *existing* error. Therefore, it is best-effort, and may never handle
/// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
/// because the `ty::Ty`-based wfcheck is always run.
- query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, hir::HirId)) -> Option> {
+ query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, traits::WellFormedLoc)) -> Option> {
eval_always
no_hash
desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index f951e43fbfa35..a4a2e82463757 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -16,7 +16,7 @@ use crate::ty::{self, AdtKind, Ty, TyCtxt};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::Constness;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
@@ -327,17 +327,39 @@ pub enum ObligationCauseCode<'tcx> {
/// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
OpaqueType,
- /// Well-formed checking. If a `HirId` is provided,
- /// it is used to perform HIR-based wf checking if an error
- /// occurs, in order to generate a more precise error message.
+ /// Well-formed checking. If a `WellFormedLoc` is provided,
+ /// then it will be used to eprform HIR-based wf checking
+ /// after an error occurs, in order to generate a more precise error span.
/// This is purely for diagnostic purposes - it is always
- /// correct to use `MiscObligation` instead
- WellFormed(Option),
+ /// correct to use `MiscObligation` instead, or to specify
+ /// `WellFormed(None)`
+ WellFormed(Option),
/// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching against.
MatchImpl(Lrc>, DefId),
}
+/// The 'location' at which we try to perform HIR-based wf checking.
+/// This information is used to obtain an `hir::Ty`, which
+/// we can walk in order to obtain precise spans for any
+/// 'nested' types (e.g. `Foo` in `Option`).
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+pub enum WellFormedLoc {
+ /// Use the type of the provided definition.
+ Ty(LocalDefId),
+ /// Use the type of the parameter of the provided function.
+ /// We cannot use `hir::Param`, since the function may
+ /// not have a body (e.g. a trait method definition)
+ Param {
+ /// The function to lookup the parameter in
+ function: LocalDefId,
+ /// The index of the parameter to use.
+ /// Parameters are indexed from 0, with the return type
+ /// being the last 'parameter'
+ param_idx: u16,
+ },
+}
+
impl ObligationCauseCode<'_> {
// Return the base obligation, ignoring derived obligations.
pub fn peel_derives(&self) -> &Self {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index b84058011066f..4ce49032398bc 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1682,7 +1682,7 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable
// This is the impl for `&'a InternalSubsts<'a>`.
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
-CloneLiftImpls! { for<'tcx> { Constness, } }
+CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
pub mod tls {
use super::{ptr_eq, GlobalCtxt, TyCtxt};
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
index feb7672f650ec..1460c2378d1c9 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
@@ -9,7 +9,7 @@ use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_span::symbol::{kw, sym};
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
use crate::util::borrowck_errors;
@@ -641,12 +641,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} else {
"'_".to_string()
};
- let suggestion = if snippet.ends_with(';') {
+ let span = if snippet.ends_with(';') {
// `type X = impl Trait;`
- format!("{} + {};", &snippet[..snippet.len() - 1], suggestable_fr_name)
+ span.with_hi(span.hi() - BytePos(1))
} else {
- format!("{} + {}", snippet, suggestable_fr_name)
+ span
};
+ let suggestion = format!(" + {}", suggestable_fr_name);
+ let span = span.shrink_to_hi();
diag.span_suggestion(
span,
&format!(
diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
index aa3ff98f7ff9f..3fb06cd2f5f44 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
@@ -26,7 +26,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
use rustc_middle::ty::{
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
@@ -60,7 +60,6 @@ use crate::borrow_check::{
LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
},
region_infer::{ClosureRegionRequirementsExt, TypeTest},
- renumber,
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
universal_regions::{DefiningTy, UniversalRegions},
Upvar,
@@ -180,7 +179,54 @@ pub(crate) fn type_check<'mir, 'tcx>(
liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
translate_outlives_facts(&mut cx);
- cx.opaque_type_values
+ let mut opaque_type_values = cx.opaque_type_values;
+
+ for (_, revealed_ty) in &mut opaque_type_values {
+ *revealed_ty = infcx.resolve_vars_if_possible(*revealed_ty);
+ if revealed_ty.has_infer_types_or_consts() {
+ infcx.tcx.sess.delay_span_bug(
+ body.span,
+ &format!("could not resolve {:#?}", revealed_ty.kind()),
+ );
+ *revealed_ty = infcx.tcx.ty_error();
+ }
+ }
+
+ opaque_type_values.retain(|(opaque_type_key, resolved_ty)| {
+ let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
+ *def_id == opaque_type_key.def_id
+ } else {
+ false
+ };
+
+ if concrete_is_opaque {
+ // We're using an opaque `impl Trait` type without
+ // 'revealing' it. For example, code like this:
+ //
+ // type Foo = impl Debug;
+ // fn foo1() -> Foo { ... }
+ // fn foo2() -> Foo { foo1() }
+ //
+ // In `foo2`, we're not revealing the type of `Foo` - we're
+ // just treating it as the opaque type.
+ //
+ // When this occurs, we do *not* want to try to equate
+ // the concrete type with the underlying defining type
+ // of the opaque type - this will always fail, since
+ // the defining type of an opaque type is always
+ // some other type (e.g. not itself)
+ // Essentially, none of the normal obligations apply here -
+ // we're just passing around some unknown opaque type,
+ // without actually looking at the underlying type it
+ // gets 'revealed' into
+ debug!(
+ "eq_opaque_type_and_type: non-defining use of {:?}",
+ opaque_type_key.def_id,
+ );
+ }
+ !concrete_is_opaque
+ });
+ opaque_type_values
},
);
@@ -1239,14 +1285,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
return Ok(());
}
- let infcx = self.infcx;
- let tcx = infcx.tcx;
let param_env = self.param_env;
let body = self.body;
let mir_def_id = body.source.def_id().expect_local();
- // the "concrete opaque types" maps
- let concrete_opaque_types = &tcx.typeck(mir_def_id).concrete_opaque_types;
let mut opaque_type_values = VecMap::new();
debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id);
@@ -1296,88 +1338,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.eq(output_ty, revealed_ty)?,
);
- // For each opaque type `Foo` inferred by this value, we want to equate
- // the inference variable `?T` with the revealed type that was computed
- // earlier by type check.
for &(opaque_type_key, opaque_decl) in &opaque_type_map {
- let resolved_ty = infcx.resolve_vars_if_possible(opaque_decl.concrete_ty);
- let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
- *def_id == opaque_type_key.def_id
- } else {
- false
- };
-
- // The revealed type computed by the earlier phase of type check.
- // In our example, this would be `(U, u32)`. Note that this references
- // the type parameter `U` from the definition of `Foo`.
- let concrete_ty = match concrete_opaque_types
- .get_by(|(key, _)| key.def_id == opaque_type_key.def_id)
- {
- None => {
- if !concrete_is_opaque {
- tcx.sess.delay_span_bug(
- body.span,
- &format!(
- "Non-defining use of {:?} with revealed type",
- opaque_type_key.def_id,
- ),
- );
- }
- continue;
- }
- Some(concrete_ty) => concrete_ty,
- };
- debug!("concrete_ty = {:?}", concrete_ty);
-
- // Apply the substitution, in this case `[U -> T]`, so that the
- // concrete type becomes `Foo<(T, u32)>`
- let subst_opaque_defn_ty = concrete_ty.subst(tcx, opaque_type_key.substs);
-
- // "Renumber" this, meaning that we replace all the regions
- // with fresh inference variables. Not relevant to our example.
- let renumbered_opaque_defn_ty =
- renumber::renumber_regions(infcx, subst_opaque_defn_ty);
-
- debug!(
- "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
- concrete_ty, resolved_ty, renumbered_opaque_defn_ty,
- );
-
- if !concrete_is_opaque {
- // Equate the instantiated opaque type `opaque_decl.concrete_ty` (`?T`,
- // in our example) with the renumbered version that we took from
- // the type check results (`Foo<(T, u32)>`).
- obligations.add(
- infcx
- .at(&ObligationCause::dummy(), param_env)
- .eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
- );
- opaque_type_values.insert(opaque_type_key, renumbered_opaque_defn_ty);
- } else {
- // We're using an opaque `impl Trait` type without
- // 'revealing' it. For example, code like this:
- //
- // type Foo = impl Debug;
- // fn foo1() -> Foo { ... }
- // fn foo2() -> Foo { foo1() }
- //
- // In `foo2`, we're not revealing the type of `Foo` - we're
- // just treating it as the opaque type.
- //
- // When this occurs, we do *not* want to try to equate
- // the concrete type with the underlying defining type
- // of the opaque type - this will always fail, since
- // the defining type of an opaque type is always
- // some other type (e.g. not itself)
- // Essentially, none of the normal obligations apply here -
- // we're just passing around some unknown opaque type,
- // without actually looking at the underlying type it
- // gets 'revealed' into
- debug!(
- "eq_opaque_type_and_type: non-defining use of {:?}",
- opaque_type_key.def_id,
- );
- }
+ opaque_type_values.insert(opaque_type_key, opaque_decl.concrete_ty);
}
debug!("eq_opaque_type_and_type: equated");
@@ -1405,7 +1367,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
locations,
ConstraintCategory::OpaqueType,
CustomTypeOp::new(
- |_cx| {
+ |infcx| {
infcx.constrain_opaque_type(
opaque_type_key,
&opaque_decl,
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index 646ae8ced7eb4..cfc538ef500a1 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -897,16 +897,19 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
permitted = true;
}
}
- let mut const_impls = true;
- tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
- if const_impls {
- if let hir::Constness::NotConst = tcx.impl_constness(imp) {
- const_impls = false;
+ if !permitted {
+ // if trait's impls are all const, permit the call.
+ let mut const_impls = true;
+ tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
+ if const_impls {
+ if let hir::Constness::NotConst = tcx.impl_constness(imp) {
+ const_impls = false;
+ }
}
+ });
+ if const_impls {
+ permitted = true;
}
- });
- if const_impls {
- permitted = true;
}
}
diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs
index 1993e0a602fa5..0ad360c7d89c3 100644
--- a/compiler/rustc_query_impl/src/keys.rs
+++ b/compiler/rustc_query_impl/src/keys.rs
@@ -1,9 +1,9 @@
//! Defines the set of legal keys that can be used in queries.
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
-use rustc_hir::HirId;
use rustc_middle::infer::canonical::Canonical;
use rustc_middle::mir;
+use rustc_middle::traits;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::subst::{GenericArg, SubstsRef};
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -397,7 +397,7 @@ impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) {
}
}
-impl<'tcx> Key for (ty::Predicate<'tcx>, HirId) {
+impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
true
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index f3ce78d2d78f8..86d495c3353b3 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1,7 +1,7 @@
use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
-use crate::config::{self, CrateType, OutputType, PrintRequest, SwitchWithOptPath};
+use crate::config::{self, CrateType, OutputType, SwitchWithOptPath};
use crate::filesearch;
use crate::lint::{self, LintId};
use crate::parse::ParseSess;
@@ -1440,25 +1440,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}
}
- // PGO does not work reliably with panic=unwind on Windows. Let's make it
- // an error to combine the two for now. It always runs into an assertions
- // if LLVM is built with assertions, but without assertions it sometimes
- // does not crash and will probably generate a corrupted binary.
- // We should only display this error if we're actually going to run PGO.
- // If we're just supposed to print out some data, don't show the error (#61002).
- if sess.opts.cg.profile_generate.enabled()
- && sess.target.is_like_msvc
- && sess.panic_strategy() == PanicStrategy::Unwind
- && sess.opts.prints.iter().all(|&p| p == PrintRequest::NativeStaticLibs)
- {
- sess.err(
- "Profile-guided optimization does not yet work in conjunction \
- with `-Cpanic=unwind` on Windows when targeting MSVC. \
- See issue #61002 \
- for more information.",
- );
- }
-
// Sanitizers can only be used on platforms that we know have working sanitizer codegen.
let supported_sanitizers = sess.target.options.supported_sanitizers;
let unsupported_sanitizers = sess.opts.debugging_opts.sanitizer - supported_sanitizers;
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index 39013a317fd9c..95c81c5c729be 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -83,6 +83,7 @@ pub struct OpaqueTypeDecl<'tcx> {
}
/// Whether member constraints should be generated for all opaque types
+#[derive(Debug)]
pub enum GenerateMemberConstraints {
/// The default, used by typeck
WhenRequired,
@@ -354,8 +355,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
opaque_types: &OpaqueTypeMap<'tcx>,
free_region_relations: &FRR,
) {
- debug!("constrain_opaque_types()");
-
for &(opaque_type_key, opaque_defn) in opaque_types {
self.constrain_opaque_type(
opaque_type_key,
@@ -367,6 +366,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
/// See `constrain_opaque_types` for documentation.
+ #[instrument(level = "debug", skip(self, free_region_relations))]
fn constrain_opaque_type>(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
@@ -376,15 +376,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
) {
let def_id = opaque_type_key.def_id;
- debug!("constrain_opaque_type()");
- debug!("constrain_opaque_type: def_id={:?}", def_id);
- debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn);
-
let tcx = self.tcx;
let concrete_ty = self.resolve_vars_if_possible(opaque_defn.concrete_ty);
- debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty);
+ debug!(?concrete_ty);
let first_own_region = match opaque_defn.origin {
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => {
@@ -397,7 +393,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// type foo::<'p0..'pn>::Foo<'q0..'qm>
// fn foo() -> foo::<'static..'static>::Foo<'l0..'lm>.
//
- // For these types we onlt iterate over `'l0..lm` below.
+ // For these types we only iterate over `'l0..lm` below.
tcx.generics_of(def_id).parent_count
}
// These opaque type inherit all lifetime parameters from their
@@ -410,10 +406,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// If there are required region bounds, we can use them.
if opaque_defn.has_required_region_bounds {
let bounds = tcx.explicit_item_bounds(def_id);
- debug!("constrain_opaque_type: predicates: {:#?}", bounds);
+ debug!("{:#?}", bounds);
let bounds: Vec<_> =
bounds.iter().map(|(bound, _)| bound.subst(tcx, opaque_type_key.substs)).collect();
- debug!("constrain_opaque_type: bounds={:#?}", bounds);
+ debug!("{:#?}", bounds);
let opaque_type = tcx.mk_opaque(def_id, opaque_type_key.substs);
let required_region_bounds =
@@ -452,8 +448,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
};
// Compute the least upper bound of it with the other regions.
- debug!("constrain_opaque_types: least_region={:?}", least_region);
- debug!("constrain_opaque_types: subst_region={:?}", subst_region);
+ debug!(?least_region);
+ debug!(?subst_region);
match least_region {
None => least_region = Some(subst_region),
Some(lr) => {
@@ -484,7 +480,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
let least_region = least_region.unwrap_or(tcx.lifetimes.re_static);
- debug!("constrain_opaque_types: least_region={:?}", least_region);
+ debug!(?least_region);
if let GenerateMemberConstraints::IfNoStaticBound = mode {
if least_region != tcx.lifetimes.re_static {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 5c4aef529e5ac..13a6733fb478a 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -242,11 +242,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
SelectionError::Unimplemented => {
// If this obligation was generated as a result of well-formed checking, see if we
// can get a better error message by performing HIR-based well formed checking.
- if let ObligationCauseCode::WellFormed(Some(wf_hir_id)) =
+ if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
root_obligation.cause.code.peel_derives()
{
if let Some(cause) =
- self.tcx.diagnostic_hir_wf_check((obligation.predicate, *wf_hir_id))
+ self.tcx.diagnostic_hir_wf_check((obligation.predicate, wf_loc.clone()))
{
obligation.cause = cause;
span = obligation.cause.span;
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 4ed07ba358de3..865e4ccc0b63f 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -40,6 +40,7 @@ use rustc_trait_selection::opaque_types::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, StatementAsExpression, TraitEngine, TraitEngineExt,
+ WellFormedLoc,
};
use std::collections::hash_map::Entry;
@@ -419,13 +420,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
span: Span,
value: T,
- hir_id: hir::HirId,
+ loc: WellFormedLoc,
) -> T
where
T: TypeFoldable<'tcx>,
{
self.inh.normalize_associated_types_in_with_cause(
- ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(hir_id))),
+ ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(loc))),
self.param_env,
value,
)
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
index 4da4835f7cfbb..13686cfec809a 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
@@ -15,7 +15,6 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
@@ -175,13 +174,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
}
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
- // FIXME: refactor this into a method
- let node = self.tcx.hir().get(self.body_id);
- if let Some(fn_like) = FnLikeNode::from_node(node) {
- fn_like.constness()
- } else {
- hir::Constness::NotConst
- }
+ self.tcx.hir().get(self.body_id).constness()
}
fn get_type_parameter_bounds(
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index b24d63917c1cf..98980c65bc815 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -22,8 +22,9 @@ use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use rustc_trait_selection::opaque_types::may_define_opaque_type;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
-use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
+use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc};
+use std::convert::TryInto;
use std::iter;
use std::ops::ControlFlow;
@@ -386,7 +387,7 @@ fn check_associated_item(
span: Span,
sig_if_method: Option<&hir::FnSig<'_>>,
) {
- let code = ObligationCauseCode::WellFormed(Some(item_id));
+ let code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner())));
for_id(tcx, item_id, span).with_fcx(|fcx| {
let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
@@ -400,7 +401,11 @@ fn check_associated_item(
match item.kind {
ty::AssocKind::Const => {
let ty = fcx.tcx.type_of(item.def_id);
- let ty = fcx.normalize_associated_types_in_wf(span, ty, item_id);
+ let ty = fcx.normalize_associated_types_in_wf(
+ span,
+ ty,
+ WellFormedLoc::Ty(item_id.expect_owner()),
+ );
fcx.register_wf_obligation(ty.into(), span, code.clone());
}
ty::AssocKind::Fn => {
@@ -422,7 +427,11 @@ fn check_associated_item(
}
if item.defaultness.has_value() {
let ty = fcx.tcx.type_of(item.def_id);
- let ty = fcx.normalize_associated_types_in_wf(span, ty, item_id);
+ let ty = fcx.normalize_associated_types_in_wf(
+ span,
+ ty,
+ WellFormedLoc::Ty(item_id.expect_owner()),
+ );
fcx.register_wf_obligation(ty.into(), span, code.clone());
}
}
@@ -621,7 +630,11 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo
for_id(tcx, item_id, ty_span).with_fcx(|fcx| {
let ty = tcx.type_of(tcx.hir().local_def_id(item_id));
- let item_ty = fcx.normalize_associated_types_in_wf(ty_span, ty, item_id);
+ let item_ty = fcx.normalize_associated_types_in_wf(
+ ty_span,
+ ty,
+ WellFormedLoc::Ty(item_id.expect_owner()),
+ );
let mut forbid_unsized = true;
if allow_foreign_ty {
@@ -634,7 +647,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo
fcx.register_wf_obligation(
item_ty.into(),
ty_span,
- ObligationCauseCode::WellFormed(Some(item_id)),
+ ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner()))),
);
if forbid_unsized {
fcx.register_bound(
@@ -684,7 +697,9 @@ fn check_impl<'tcx>(
fcx.register_wf_obligation(
self_ty.into(),
ast_self_ty.span,
- ObligationCauseCode::WellFormed(Some(item.hir_id())),
+ ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(
+ item.hir_id().expect_owner(),
+ ))),
);
}
}
@@ -901,11 +916,48 @@ fn check_fn_or_method<'fcx, 'tcx>(
implied_bounds: &mut Vec>,
) {
let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
- let sig = fcx.normalize_associated_types_in(span, sig);
- for (&input_ty, ty) in iter::zip(sig.inputs(), hir_decl.inputs) {
- fcx.register_wf_obligation(input_ty.into(), ty.span, ObligationCauseCode::WellFormed(None));
+ // Normalize the input and output types one at a time, using a different
+ // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
+ // on the entire `FnSig`, since this would use the same `WellFormedLoc`
+ // for each type, preventing the HIR wf check from generating
+ // a nice error message.
+ let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig;
+ inputs_and_output =
+ fcx.tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| {
+ fcx.normalize_associated_types_in_wf(
+ span,
+ ty,
+ WellFormedLoc::Param {
+ function: def_id.expect_local(),
+ // Note that the `param_idx` of the output type is
+ // one greater than the index of the last input type.
+ param_idx: i.try_into().unwrap(),
+ },
+ )
+ }));
+ // Manually call `normalize_assocaited_types_in` on the other types
+ // in `FnSig`. This ensures that if the types of these fields
+ // ever change to include projections, we will start normalizing
+ // them automatically.
+ let sig = ty::FnSig {
+ inputs_and_output,
+ c_variadic: fcx.normalize_associated_types_in(span, c_variadic),
+ unsafety: fcx.normalize_associated_types_in(span, unsafety),
+ abi: fcx.normalize_associated_types_in(span, abi),
+ };
+
+ for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() {
+ fcx.register_wf_obligation(
+ input_ty.into(),
+ ty.span,
+ ObligationCauseCode::WellFormed(Some(WellFormedLoc::Param {
+ function: def_id.expect_local(),
+ param_idx: i.try_into().unwrap(),
+ })),
+ );
}
+
implied_bounds.extend(sig.inputs());
fcx.register_wf_obligation(
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 506ca98b96026..1a4c2eb515584 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -35,7 +35,6 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::weak_lang_items;
use rustc_hir::{GenericParamKind, HirId, Node};
-use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::hir::map::Map;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::Linkage;
@@ -358,11 +357,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
}
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
- if let Some(fn_like) = FnLikeNode::from_node(self.node()) {
- fn_like.constness()
- } else {
- hir::Constness::NotConst
- }
+ self.node().constness()
}
fn get_type_parameter_bounds(
diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs
index a8ec7b79e571f..c1af10f5ce451 100644
--- a/compiler/rustc_typeck/src/hir_wf_check.rs
+++ b/compiler/rustc_typeck/src/hir_wf_check.rs
@@ -3,10 +3,10 @@ use rustc_hir as hir;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::HirId;
use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::TraitEngine;
+use rustc_infer::traits::{ObligationCause, WellFormedLoc};
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, ToPredicate, TyCtxt};
+use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder};
use rustc_trait_selection::traits;
pub fn provide(providers: &mut Providers) {
@@ -17,21 +17,20 @@ pub fn provide(providers: &mut Providers) {
// need access to `ItemCtxt`
fn diagnostic_hir_wf_check<'tcx>(
tcx: TyCtxt<'tcx>,
- (predicate, hir_id): (ty::Predicate<'tcx>, HirId),
+ (predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc),
) -> Option> {
let hir = tcx.hir();
- // HIR wfcheck should only ever happen as part of improving an existing error
- tcx.sess.delay_span_bug(hir.span(hir_id), "Performed HIR wfcheck without an existing error!");
- // Currently, we only handle WF checking for items (e.g. associated items).
- // It would be nice to extend this to handle wf checks inside functions.
- let def_id = match tcx.hir().opt_local_def_id(hir_id) {
- Some(def_id) => def_id,
- None => return None,
+ let def_id = match loc {
+ WellFormedLoc::Ty(def_id) => def_id,
+ WellFormedLoc::Param { function, param_idx: _ } => function,
};
+ let hir_id = HirId::make_owner(def_id);
+
+ // HIR wfcheck should only ever happen as part of improving an existing error
+ tcx.sess
+ .delay_span_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!");
- // FIXME - figure out how we want to handle wf-checking for
- // things inside a function body.
let icx = ItemCtxt::new(tcx, def_id.to_def_id());
// To perform HIR-based WF checking, we iterate over all HIR types
@@ -72,7 +71,8 @@ fn diagnostic_hir_wf_check<'tcx>(
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
self.tcx.infer_ctxt().enter(|infcx| {
let mut fulfill = traits::FulfillmentContext::new();
- let tcx_ty = self.icx.to_ty(ty);
+ let tcx_ty =
+ self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
let cause = traits::ObligationCause::new(
ty.span,
self.hir_id,
@@ -119,19 +119,66 @@ fn diagnostic_hir_wf_check<'tcx>(
depth: 0,
};
- let ty = match tcx.hir().get(hir_id) {
- hir::Node::ImplItem(item) => match item.kind {
- hir::ImplItemKind::TyAlias(ty) => Some(ty),
- _ => None,
- },
- hir::Node::TraitItem(item) => match item.kind {
- hir::TraitItemKind::Type(_, ty) => ty,
- _ => None,
+ // Get the starting `hir::Ty` using our `WellFormedLoc`.
+ // We will walk 'into' this type to try to find
+ // a more precise span for our predicate.
+ let ty = match loc {
+ WellFormedLoc::Ty(_) => match hir.get(hir_id) {
+ hir::Node::ImplItem(item) => match item.kind {
+ hir::ImplItemKind::TyAlias(ty) => Some(ty),
+ ref item => bug!("Unexpected ImplItem {:?}", item),
+ },
+ hir::Node::TraitItem(item) => match item.kind {
+ hir::TraitItemKind::Type(_, ty) => ty,
+ ref item => bug!("Unexpected TraitItem {:?}", item),
+ },
+ hir::Node::Item(item) => match item.kind {
+ hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
+ hir::ItemKind::Impl(ref impl_) => {
+ assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
+ Some(impl_.self_ty)
+ }
+ ref item => bug!("Unexpected item {:?}", item),
+ },
+ ref node => bug!("Unexpected node {:?}", node),
},
- _ => None,
+ WellFormedLoc::Param { function: _, param_idx } => {
+ let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap();
+ // Get return type
+ if param_idx as usize == fn_decl.inputs.len() {
+ match fn_decl.output {
+ hir::FnRetTy::Return(ty) => Some(ty),
+ // The unit type `()` is always well-formed
+ hir::FnRetTy::DefaultReturn(_span) => None,
+ }
+ } else {
+ Some(&fn_decl.inputs[param_idx as usize])
+ }
+ }
};
if let Some(ty) = ty {
visitor.visit_ty(ty);
}
visitor.cause
}
+
+struct EraseAllBoundRegions<'tcx> {
+ tcx: TyCtxt<'tcx>,
+}
+
+// Higher ranked regions are complicated.
+// To make matters worse, the HIR WF check can instantiate them
+// outside of a `Binder`, due to the way we (ab)use
+// `ItemCtxt::to_ty`. To make things simpler, we just erase all
+// of them, regardless of depth. At worse, this will give
+// us an inaccurate span for an error message, but cannot
+// lead to unsoundess (we call `delay_span_bug` at the start
+// of `diagnostic_hir_wf_check`).
+impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> {
+ fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
+ self.tcx
+ }
+ fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
+ if let ty::ReLateBound(..) = r { &ty::ReErased } else { r }
+ }
+}
diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs
index ad93fa610c481..0bd1ea645779f 100644
--- a/library/std/src/sys/unix/args.rs
+++ b/library/std/src/sys/unix/args.rs
@@ -77,10 +77,18 @@ mod imp {
use crate::ptr;
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
+ // The system-provided argc and argv, which we store in static memory
+ // here so that we can defer the work of parsing them until its actually
+ // needed.
+ //
+ // Note that we never mutate argv/argc, the argv array, or the argv
+ // strings, which allows the code in this file to be very simple.
static ARGC: AtomicIsize = AtomicIsize::new(0);
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
unsafe fn really_init(argc: isize, argv: *const *const u8) {
+ // These don't need to be ordered with each other or other stores,
+ // because they only hold the unmodified system-provide argv/argc.
ARGC.store(argc, Ordering::Relaxed);
ARGV.store(argv as *mut _, Ordering::Relaxed);
}
@@ -122,8 +130,14 @@ mod imp {
fn clone() -> Vec {
unsafe {
- // Load ARGC and ARGV without a lock. If the store to either ARGV or
- // ARGC isn't visible yet, we'll return an empty argument list.
+ // Load ARGC and ARGV, which hold the unmodified system-provided
+ // argc/argv, so we can read the pointed-to memory without atomics
+ // or synchronization.
+ //
+ // If either ARGC or ARGV is still zero or null, then either there
+ // really are no arguments, or someone is asking for `args()`
+ // before initialization has completed, and we return an empty
+ // list.
let argv = ARGV.load(Ordering::Relaxed);
let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
(0..argc)
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 8c28d0b60fa32..77d2684b5d2a4 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -2,7 +2,7 @@
//! library.
//!
//! This module contains some of the real meat in the rustbuild build system
-//! which is where Cargo is used to compiler the standard library, libtest, and
+//! which is where Cargo is used to compile the standard library, libtest, and
//! compiler. This module is also responsible for assembling the sysroot as it
//! goes along from the output of the previous stage.
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index e21469dc9c343..908e292d968ef 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -57,7 +57,7 @@ pub(crate) fn opts() -> Options {
/// A subset of [`opts()`] used for rendering summaries.
pub(crate) fn summary_opts() -> Options {
- Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION
+ Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION | Options::ENABLE_TABLES
}
/// When `to_string` is called, this struct will emit the HTML corresponding to
@@ -522,6 +522,10 @@ fn check_if_allowed_tag(t: &Tag<'_>) -> bool {
)
}
+fn is_forbidden_tag(t: &Tag<'_>) -> bool {
+ matches!(t, Tag::CodeBlock(_) | Tag::Table(_) | Tag::TableHead | Tag::TableRow | Tag::TableCell)
+}
+
impl<'a, I: Iterator
- >> Iterator for SummaryLine<'a, I> {
type Item = Event<'a>;
@@ -535,14 +539,17 @@ impl<'a, I: Iterator
- >> Iterator for SummaryLine<'a, I> {
if let Some(event) = self.inner.next() {
let mut is_start = true;
let is_allowed_tag = match event {
- Event::Start(Tag::CodeBlock(_)) | Event::End(Tag::CodeBlock(_)) => {
- return None;
- }
Event::Start(ref c) => {
+ if is_forbidden_tag(c) {
+ return None;
+ }
self.depth += 1;
check_if_allowed_tag(c)
}
Event::End(ref c) => {
+ if is_forbidden_tag(c) {
+ return None;
+ }
self.depth -= 1;
is_start = false;
check_if_allowed_tag(c)
diff --git a/src/test/codegen/pgo-instrumentation.rs b/src/test/codegen/pgo-instrumentation.rs
index c085f3c829ea4..05c2d2fc0d8c1 100644
--- a/src/test/codegen/pgo-instrumentation.rs
+++ b/src/test/codegen/pgo-instrumentation.rs
@@ -1,8 +1,7 @@
// Test that `-Cprofile-generate` creates expected instrumentation artifacts in LLVM IR.
-// Compiling with `-Cpanic=abort` because PGO+unwinding isn't supported on all platforms.
// needs-profiler-support
-// compile-flags: -Cprofile-generate -Ccodegen-units=1 -Cpanic=abort
+// compile-flags: -Cprofile-generate -Ccodegen-units=1
// CHECK: @__llvm_profile_raw_version =
// CHECK-DAG: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = {{.*}}global
diff --git a/src/test/run-make-fulldeps/pgo-branch-weights/Makefile b/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
index 18828b66ce874..9773e3f1fdfc4 100644
--- a/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
+++ b/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
@@ -6,19 +6,6 @@
-include ../tools.mk
-# This test makes sure that instrumented binaries record the right counts for
-# functions being called and branches being taken. We run an instrumented binary
-# with an argument that causes a know path through the program and then check
-# that the expected counts get added to the use-phase LLVM IR.
-
-# LLVM doesn't support instrumenting binaries that use SEH:
-# https://github.com/rust-lang/rust/issues/61002
-#
-# Things work fine with -Cpanic=abort though.
-ifdef IS_MSVC
-COMMON_FLAGS=-Cpanic=abort
-endif
-
# For some very small programs GNU ld seems to not properly handle
# instrumentation sections correctly. Neither Gold nor LLD have that problem.
ifeq ($(UNAME),Linux)
diff --git a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
index f1ac39aa0ea8a..a7d5c56163257 100644
--- a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
@@ -8,14 +8,6 @@
COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Cprofile-generate="$(TMPDIR)"
-# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
-# https://github.com/rust-lang/rust/issues/61002
-#
-# Things work fine with -Cpanic=abort though.
-ifdef IS_MSVC
-COMPILE_FLAGS+= -Cpanic=abort
-endif
-
all:
$(RUSTC) $(COMPILE_FLAGS) test.rs
$(call RUN,test) || exit 1
diff --git a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
index 3fbfeb09eb373..425bfc28a9766 100644
--- a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
@@ -4,14 +4,6 @@
COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)"
-# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
-# https://github.com/rust-lang/rust/issues/61002
-#
-# Things work fine with -Cpanic=abort though.
-ifdef IS_MSVC
-COMPILE_FLAGS+= -Cpanic=abort
-endif
-
all:
$(RUSTC) $(COMPILE_FLAGS) --emit=llvm-ir test.rs
# We expect symbols starting with "__llvm_profile_".
diff --git a/src/test/run-make-fulldeps/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile
index 69b19801bf091..6533355be3418 100644
--- a/src/test/run-make-fulldeps/pgo-gen/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen/Makefile
@@ -8,14 +8,6 @@
COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)"
-# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
-# https://github.com/rust-lang/rust/issues/61002
-#
-# Things work fine with -Cpanic=abort though.
-ifdef IS_MSVC
-COMPILE_FLAGS+= -Cpanic=abort
-endif
-
all:
$(RUSTC) $(COMPILE_FLAGS) test.rs
$(call RUN,test) || exit 1
diff --git a/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile b/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
index 876a9b2c43991..c0195dcbb31be 100644
--- a/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
+++ b/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
@@ -6,20 +6,6 @@
-include ../tools.mk
-# This test makes sure that indirect call promotion is performed. The test
-# programs calls the same function a thousand times through a function pointer.
-# Only PGO data provides the information that it actually always is the same
-# function. We verify that the indirect call promotion pass inserts a check
-# whether it can make a direct call instead of the indirect call.
-
-# LLVM doesn't support instrumenting binaries that use SEH:
-# https://github.com/rust-lang/rust/issues/61002
-#
-# Things work fine with -Cpanic=abort though.
-ifdef IS_MSVC
-COMMON_FLAGS=-Cpanic=abort
-endif
-
all:
# We don't compile `opaque` with either optimizations or instrumentation.
# We don't compile `opaque` with either optimizations or instrumentation.
diff --git a/src/test/run-make-fulldeps/pgo-use/Makefile b/src/test/run-make-fulldeps/pgo-use/Makefile
index 01bc211df1616..d7863c9c587a5 100644
--- a/src/test/run-make-fulldeps/pgo-use/Makefile
+++ b/src/test/run-make-fulldeps/pgo-use/Makefile
@@ -18,14 +18,6 @@
COMMON_FLAGS=-Copt-level=2 -Ccodegen-units=1 -Cllvm-args=-disable-preinline
-# LLVM doesn't support instrumenting binaries that use SEH:
-# https://github.com/rust-lang/rust/issues/61002
-#
-# Things work fine with -Cpanic=abort though.
-ifdef IS_MSVC
-COMMON_FLAGS+= -Cpanic=abort
-endif
-
ifeq ($(UNAME),Darwin)
# macOS does not have the `tac` command, but `tail -r` does the same thing
TAC := tail -r
diff --git a/src/test/rustdoc-gui/item-summary-table.goml b/src/test/rustdoc-gui/item-summary-table.goml
new file mode 100644
index 0000000000000..6bf4e288c4377
--- /dev/null
+++ b/src/test/rustdoc-gui/item-summary-table.goml
@@ -0,0 +1,6 @@
+// This test ensures that
elements aren't display in items summary.
+goto: file://|DOC_PATH|/lib2/summary_table/index.html
+// We check that we picked the right item first.
+assert-text: (".item-table .item-left", "Foo")
+// Then we check that its summary is empty.
+assert-text: (".item-table .item-right", "")
diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs
index cd00348cad3d1..d18c91d48680b 100644
--- a/src/test/rustdoc-gui/src/lib2/lib.rs
+++ b/src/test/rustdoc-gui/src/lib2/lib.rs
@@ -57,3 +57,10 @@ pub mod long_trait {
pub trait ALongNameBecauseItHelpsTestingTheCurrentProblem: DerefMut
+ From + Send + Sync + AsRef + 'static {}
}
+
+pub mod summary_table {
+ /// | header 1 | header 2 |
+ /// | -------- | -------- |
+ /// | content | content |
+ pub struct Foo;
+}
diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
index 73b23da5bcb66..7950dd3e99e29 100644
--- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
+++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
@@ -29,7 +29,6 @@ impl Bar for AssocNoCopy {
impl Thing for AssocNoCopy {
type Out = Box>;
//~^ ERROR the trait bound `String: Copy` is not satisfied
- //~| ERROR the trait bound `String: Copy` is not satisfied
fn func() -> Self::Out {
Box::new(AssocNoCopy)
diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
index 414d74d4786d9..0f1d35be0eb7a 100644
--- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
+++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
@@ -4,12 +4,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
LL | type Out = Box>;
| ^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
-error[E0277]: the trait bound `String: Copy` is not satisfied
- --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:30:28
- |
-LL | type Out = Box>;
- | ^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
index e8c11a32bf7fd..25e80159b0b18 100644
--- a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
+++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
@@ -1,8 +1,11 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-for-unimpl-trait.rs:10:8
+ --> $DIR/associated-types-for-unimpl-trait.rs:10:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh(&self, foo: U, bar: ::Value) {}
- | ^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
index e3be434698ab9..19500f58aa688 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
@@ -1,8 +1,11 @@
error[E0277]: the trait bound `T: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-bound.rs:11:8
+ --> $DIR/associated-types-no-suitable-bound.rs:11:21
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh(foo: ::Value) {}
- | ^^^^ the trait `Get` is not implemented for `T`
+ | ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
index 9dc3414e9edf0..0e978f20a6634 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
@@ -1,8 +1,11 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:8
+ --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh(&self, foo: U, bar: ::Value) {}
- | ^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
index c2aed3f9de548..1ec3c05983aef 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
@@ -1,8 +1,11 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait.rs:17:8
+ --> $DIR/associated-types-no-suitable-supertrait.rs:17:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh(&self, foo: U, bar: ::Value) {}
- | ^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
@@ -10,10 +13,13 @@ LL | fn uhoh(&self, foo: U, bar: ::Value) where Self: Ge
| ^^^^^^^^^^^^^^^
error[E0277]: the trait bound `(T, U): Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait.rs:22:8
+ --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh(&self, foo: U, bar: <(T, U) as Get>::Value) {}
- | ^^^^ the trait `Get` is not implemented for `(T, U)`
+ | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
index fb842d968676d..b6ee1ed733c3e 100644
--- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
+++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
@@ -1,8 +1,11 @@
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:8
+ --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn okay(&self, foo: U, bar: ::Value);
- | ^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr b/src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr
index e0e6029252c00..319e6c2c032a0 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/object-safety-err-ret.rs:17:15
+ --> $DIR/object-safety-err-ret.rs:17:16
|
LL | fn use_dyn(v: &dyn Foo) {
- | ^^^^^^^^ `Foo` cannot be made into an object
+ | ^^^^^^^ `Foo` cannot be made into an object
|
= help: consider moving `test` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr
index eb68a6298d1ac..cead9776e4abb 100644
--- a/src/test/ui/error-codes/E0038.stderr
+++ b/src/test/ui/error-codes/E0038.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Trait` cannot be made into an object
- --> $DIR/E0038.rs:5:16
+ --> $DIR/E0038.rs:5:20
|
LL | fn call_foo(x: Box) {
- | ^^^^^^^^^^^^^^ `Trait` cannot be made into an object
+ | ^^^^^^^^^ `Trait` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
index 12195bc1071a0..c13c05f146a7e 100644
--- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
+++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
- --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38
+ --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:39
|
LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) {
- | ^^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
--> $DIR/feature-gate-object_safe_for_dispatch.rs:4:23
@@ -35,10 +35,10 @@ LL | fn static_fn() where Self: Sized {}
| ^^^^^^^^^^^^^^^^^
error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
- --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35
+ --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:39
|
LL | fn takes_non_object_safe_box(obj: Box) {
- | ^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
diff --git a/src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr b/src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr
index 50ce6427e8b58..a3ced35155f37 100644
--- a/src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr
+++ b/src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr
@@ -51,4 +51,5 @@ LL | #[optimize(banana)]
error: aborting due to 6 previous errors
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0658, E0722.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr
index eb8e101a83d79..8651789688eaa 100644
--- a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr
+++ b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/gat-in-trait-path.rs:21:13
+ --> $DIR/gat-in-trait-path.rs:21:17
|
LL | fn f(_arg : Box Foo = &'a ()>>) {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
= help: consider moving `A` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.stderr
index 8cc9f2816a166..b4b89ab047363 100644
--- a/src/test/ui/generic-associated-types/issue-67510-pass.stderr
+++ b/src/test/ui/generic-associated-types/issue-67510-pass.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `X` cannot be made into an object
- --> $DIR/issue-67510-pass.rs:7:19
+ --> $DIR/issue-67510-pass.rs:7:23
|
LL | fn _func1<'a>(_x: Box=&'a ()>>) {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
= help: consider moving `Y` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
diff --git a/src/test/ui/generic-associated-types/trait-objects.stderr b/src/test/ui/generic-associated-types/trait-objects.stderr
index a121566bbd884..6429bb8159e1f 100644
--- a/src/test/ui/generic-associated-types/trait-objects.stderr
+++ b/src/test/ui/generic-associated-types/trait-objects.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `StreamingIterator` cannot be made into an object
- --> $DIR/trait-objects.rs:10:16
+ --> $DIR/trait-objects.rs:10:21
|
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator- = &'a i32>) -> usize {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
|
= help: consider moving `Item` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs
index 087f4582b21c3..c2fbbf94fd666 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.rs
+++ b/src/test/ui/impl-trait/auto-trait-leak.rs
@@ -12,7 +12,6 @@ fn main() {
fn cycle1() -> impl Clone {
//~^ ERROR cycle detected
send(cycle2().clone());
- //~^ ERROR cannot be sent between threads safely
Rc::new(Cell::new(5))
}
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index e578c4b4f819e..3eb141cc2bb55 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
note: ...which requires computing type of `cycle2::{opaque#0}`...
- --> $DIR/auto-trait-leak.rs:20:16
+ --> $DIR/auto-trait-leak.rs:19:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires borrow-checking `cycle2`...
- --> $DIR/auto-trait-leak.rs:20:1
+ --> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle2`...
- --> $DIR/auto-trait-leak.rs:20:1
+ --> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle2`...
- --> $DIR/auto-trait-leak.rs:20:1
+ --> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle2`...
- --> $DIR/auto-trait-leak.rs:20:1
+ --> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle2`...
- --> $DIR/auto-trait-leak.rs:20:1
+ --> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
- --> $DIR/auto-trait-leak.rs:20:1
+ --> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,22 +84,6 @@ LL | | Rc::new(String::from("foo"))
LL | | }
| |_^
-error[E0277]: `Rc` cannot be sent between threads safely
- --> $DIR/auto-trait-leak.rs:14:5
- |
-LL | fn send(_: T) {}
- | ---- required by this bound in `send`
-...
-LL | send(cycle2().clone());
- | ^^^^ `Rc` cannot be sent between threads safely
-...
-LL | fn cycle2() -> impl Clone {
- | ---------- within this `impl Clone`
- |
- = help: within `impl Clone`, the trait `Send` is not implemented for `Rc`
- = note: required because it appears within the type `impl Clone`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-Some errors have detailed explanations: E0277, E0391.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/impl-trait/issue-86465.rs b/src/test/ui/impl-trait/issue-86465.rs
new file mode 100644
index 0000000000000..23a3748c12c6a
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-86465.rs
@@ -0,0 +1,10 @@
+#![feature(min_type_alias_impl_trait)]
+
+type X<'a, 'b> = impl std::fmt::Debug;
+
+fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+ //~^ ERROR concrete type differs from previous defining opaque type use
+ (a, a)
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issue-86465.stderr b/src/test/ui/impl-trait/issue-86465.stderr
new file mode 100644
index 0000000000000..595b16aa68554
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-86465.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/issue-86465.rs:5:1
+ |
+LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a u32`, got `&'b u32`
+ |
+note: previous use here
+ --> $DIR/issue-86465.rs:5:1
+ |
+LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
index 4372de245078f..e9d6208773454 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
@@ -9,7 +9,7 @@ LL | fn elided(x: &i32) -> impl Copy { x }
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
- | ^^^^^^^^^^^^^^
+ | ^^^^
error: lifetime may not live long enough
--> $DIR/must_outlive_least_region_or_bound.rs:5:32
@@ -23,7 +23,7 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
- | ^^^^^^^^^^^^^^
+ | ^^^^
error: lifetime may not live long enough
--> $DIR/must_outlive_least_region_or_bound.rs:7:46
diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
index 65178cc9d24c2..6c5264671a912 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
@@ -9,7 +9,7 @@ LL | fn iter_values_anon(&self) -> impl Iterator
- {
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn iter_values_anon(&self) -> impl Iterator
- + '_ {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^
error: lifetime may not live long enough
--> $DIR/static-return-lifetime-infered.rs:9:37
@@ -23,7 +23,7 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator
- {
help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator
- + 'a {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-18611.stderr b/src/test/ui/issues/issue-18611.stderr
index 8872f51753c94..0e942e80e2544 100644
--- a/src/test/ui/issues/issue-18611.stderr
+++ b/src/test/ui/issues/issue-18611.stderr
@@ -1,8 +1,11 @@
error[E0277]: the trait bound `isize: HasState` is not satisfied
- --> $DIR/issue-18611.rs:1:4
+ --> $DIR/issue-18611.rs:1:18
|
LL | fn add_state(op: ::State) {
- | ^^^^^^^^^ the trait `HasState` is not implemented for `isize`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
+...
+LL | trait HasState {
+ | -------------- required by this bound in `HasState`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr
index 86b530e85a80a..2a5416ce85ba6 100644
--- a/src/test/ui/issues/issue-18959.stderr
+++ b/src/test/ui/issues/issue-18959.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Bar` cannot be made into an object
- --> $DIR/issue-18959.rs:11:11
+ --> $DIR/issue-18959.rs:11:12
|
LL | fn foo(b: &dyn Bar) {
- | ^^^^^^^^ `Bar` cannot be made into an object
+ | ^^^^^^^ `Bar` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs
new file mode 100644
index 0000000000000..536c1d7374023
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs
@@ -0,0 +1,15 @@
+// check-pass
+#![feature(const_fn_trait_bound)]
+#![feature(const_trait_impl)]
+
+trait MyPartialEq {
+ fn eq(&self, other: &Self) -> bool;
+}
+
+impl const MyPartialEq for T {
+ fn eq(&self, other: &Self) -> bool {
+ PartialEq::eq(self, other)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
index f2e556c63cbf3..a678731934f6e 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
@@ -9,7 +9,7 @@ LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
- | ^^^^^^^^^^^^^^^
+ | ^^^^
error: aborting due to previous error
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
index 73766c31b93b6..962593e411e92 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
@@ -9,7 +9,7 @@ LL | fn f(self: Pin<&Self>) -> impl Clone { self }
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
- | ^^^^^^^^^^^^^^^
+ | ^^^^
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
index 2407d13714a2a..05ba7808600b0 100644
--- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
+++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
@@ -9,7 +9,7 @@ LL | fn iter(&self) -> impl Iterator
- > {
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn iter(&self) -> impl Iterator
- > + '_ {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^
error: lifetime may not live long enough
--> $DIR/trait-object-nested-in-impl-trait.rs:39:9
@@ -47,7 +47,7 @@ LL | fn iter<'a>(&'a self) -> impl Iterator
- > {
help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
|
LL | fn iter<'a>(&'a self) -> impl Iterator
- > + 'a {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^
error: aborting due to 4 previous errors
diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr
index 797406f869fe6..f332b7213d8bc 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr
+++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Trait` cannot be made into an object
- --> $DIR/object-unsafe-trait-references-self.rs:6:11
+ --> $DIR/object-unsafe-trait-references-self.rs:6:12
|
LL | fn bar(x: &dyn Trait) {}
- | ^^^^^^^^^^ `Trait` cannot be made into an object
+ | ^^^^^^^^^ `Trait` cannot be made into an object
|
= help: consider moving `baz` to another trait
= help: consider moving `bat` to another trait
@@ -17,10 +17,10 @@ LL | fn bat(&self) -> Self {}
| ^^^^ ...because method `bat` references the `Self` type in its return type
error[E0038]: the trait `Other` cannot be made into an object
- --> $DIR/object-unsafe-trait-references-self.rs:10:11
+ --> $DIR/object-unsafe-trait-references-self.rs:10:12
|
LL | fn foo(x: &dyn Other) {}
- | ^^^^^^^^^^ `Other` cannot be made into an object
+ | ^^^^^^^^^ `Other` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
--> $DIR/object-unsafe-trait-references-self.rs:8:14
diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
index a2caf846cc5fe..4c18f6d79d077 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
+++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
@@ -1,8 +1,8 @@
error[E0038]: the trait `Trait` cannot be made into an object
- --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:11
+ --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:12
|
LL | fn bar(x: &dyn Trait) {}
- | ^^^^^^^^^^ `Trait` cannot be made into an object
+ | ^^^^^^^^^ `Trait` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit
--> $DIR/object-unsafe-trait-should-use-where-sized.rs:5:8
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
index 6394a1f8e8509..90a753b5a6de1 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
@@ -36,16 +36,7 @@ LL | type WrongGeneric = impl 'static;
LL | fn wrong_generic(t: T) -> WrongGeneric {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
-error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/generic_type_does_not_live_long_enough.rs:12:24
- |
-LL | type WrongGeneric = impl 'static;
- | ^^^^^^^^^^^^
- |
- = help: consider adding an explicit lifetime bound `T: 'static`...
- = note: ...so that the type `T` will meet its required lifetime bounds
-
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors; 1 warning emitted
Some errors have detailed explanations: E0308, E0310.
For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
index 49ead8b094c19..e50282201074e 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
@@ -27,16 +27,7 @@ LL | type WrongGeneric = impl 'static;
LL | fn wrong_generic(t: T) -> WrongGeneric {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
-error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/generic_type_does_not_live_long_enough.rs:12:24
- |
-LL | type WrongGeneric = impl 'static;
- | ^^^^^^^^^^^^
- |
- = help: consider adding an explicit lifetime bound `T: 'static`...
- = note: ...so that the type `T` will meet its required lifetime bounds
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
Some errors have detailed explanations: E0308, E0310.
For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
index 3dda34ff668ce..9f647d9e737fe 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
@@ -11,7 +11,6 @@ fn main() {
type WrongGeneric = impl 'static;
//~^ ERROR the parameter type `T` may not live long enough
-//~| ERROR the parameter type `T` may not live long enough
//~| ERROR: at least one trait must be specified
fn wrong_generic(t: T) -> WrongGeneric {
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
index d90f328708a7b..61e8da91bbaa9 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
@@ -16,52 +16,5 @@ LL | type Bar = impl Baz;
= note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-error[E0308]: mismatched types
- --> $DIR/issue-57611-trait-alias.rs:20:16
- |
-LL | type Bar = impl Baz;
- | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
- |
- = note: expected type `for<'r> Fn<(&'r X,)>`
- found type `Fn<(&' X,)>`
-note: this closure does not fulfill the lifetime requirements
- --> $DIR/issue-57611-trait-alias.rs:28:9
- |
-LL | |x| x
- | ^^^^^
-
-error: implementation of `FnOnce` is not general enough
- --> $DIR/issue-57611-trait-alias.rs:20:16
- |
-LL | type Bar = impl Baz;
- | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
- |
- = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
- = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error[E0308]: mismatched types
- --> $DIR/issue-57611-trait-alias.rs:20:16
- |
-LL | type Bar = impl Baz;
- | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
- |
- = note: expected type `for<'r> Fn<(&'r X,)>`
- found type `Fn<(&' X,)>`
-note: this closure does not fulfill the lifetime requirements
- --> $DIR/issue-57611-trait-alias.rs:28:9
- |
-LL | |x| x
- | ^^^^^
-
-error: implementation of `FnOnce` is not general enough
- --> $DIR/issue-57611-trait-alias.rs:20:16
- |
-LL | type Bar = impl Baz;
- | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
- |
- = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
- = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error: aborting due to 5 previous errors; 1 warning emitted
+error: aborting due to previous error; 1 warning emitted
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
index d019f40757eed..f65e91e52c713 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
@@ -7,52 +7,5 @@ LL | type Bar = impl Baz;
= note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-error[E0308]: mismatched types
- --> $DIR/issue-57611-trait-alias.rs:20:16
- |
-LL | type Bar = impl Baz;
- | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
- |
- = note: expected type `for<'r> Fn<(&'r X,)>`
- found type `Fn<(&' X,)>`
-note: this closure does not fulfill the lifetime requirements
- --> $DIR/issue-57611-trait-alias.rs:28:9
- |
-LL | |x| x
- | ^^^^^
-
-error: implementation of `FnOnce` is not general enough
- --> $DIR/issue-57611-trait-alias.rs:20:16
- |
-LL | type Bar = impl Baz;
- | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
- |
- = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
- = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error[E0308]: mismatched types
- --> $DIR/issue-57611-trait-alias.rs:20:16
- |
-LL | type Bar = impl Baz;
- | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
- |
- = note: expected type `for<'r> Fn<(&'r X,)>`
- found type `Fn<(&' X,)>`
-note: this closure does not fulfill the lifetime requirements
- --> $DIR/issue-57611-trait-alias.rs:28:9
- |
-LL | |x| x
- | ^^^^^
-
-error: implementation of `FnOnce` is not general enough
- --> $DIR/issue-57611-trait-alias.rs:20:16
- |
-LL | type Bar = impl Baz;
- | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
- |
- = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
- = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error: aborting due to 5 previous errors
+error: aborting due to previous error
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
index ccc727e0bf01b..508ecdd88a482 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
@@ -19,10 +19,6 @@ struct X;
impl Foo for X {
type Bar = impl Baz;
//~^ ERROR implementation of `FnOnce` is not general enough
- //~| ERROR implementation of `FnOnce` is not general enough
- //~| ERROR implementation of `FnOnce` is not general enough
- //~| ERROR mismatched types
- //~| ERROR mismatched types
fn bar(&self) -> Self::Bar {
|x| x
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs
index b7c8a58a65629..cee5e5a01cc2a 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60371.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs
@@ -9,7 +9,6 @@ trait Bug {
impl Bug for &() {
type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable
//~^ ERROR the trait bound `(): Bug` is not satisfied
- //~^^ ERROR the trait bound `(): Bug` is not satisfied
const FUN: fn() -> Self::Item = || ();
//~^ ERROR type alias impl trait is not permitted here
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
index 4906ea9c2e261..a9df74689df29 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
@@ -8,7 +8,7 @@ LL | type Item = impl Bug;
= help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
error[E0658]: type alias impl trait is not permitted here
- --> $DIR/issue-60371.rs:14:40
+ --> $DIR/issue-60371.rs:13:40
|
LL | const FUN: fn() -> Self::Item = || ();
| ^
@@ -25,16 +25,7 @@ LL | type Item = impl Bug;
= help: the following implementations were found:
<&() as Bug>
-error[E0277]: the trait bound `(): Bug` is not satisfied
- --> $DIR/issue-60371.rs:10:17
- |
-LL | type Item = impl Bug;
- | ^^^^^^^^ the trait `Bug` is not implemented for `()`
- |
- = help: the following implementations were found:
- <&() as Bug>
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0658.
For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.rs b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs
new file mode 100644
index 0000000000000..4b0f2afee5484
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs
@@ -0,0 +1,19 @@
+#![feature(member_constraints)]
+#![feature(type_alias_impl_trait)]
+//~^ WARN incomplete
+
+pub trait A {
+ type B;
+ fn f(&self) -> Self::B;
+}
+impl<'a, 'b> A for () {
+ //~^ ERROR the lifetime parameter `'a` is not constrained
+ //~| ERROR the lifetime parameter `'b` is not constrained
+ type B = impl core::fmt::Debug;
+ //~^ ERROR is unstable
+
+
+ fn f(&self) -> Self::B {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
new file mode 100644
index 0000000000000..4506a6e23d5c0
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
@@ -0,0 +1,34 @@
+error[E0658]: `impl Trait` in type aliases is unstable
+ --> $DIR/issue-74761-2.rs:12:14
+ |
+LL | type B = impl core::fmt::Debug;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #63063 for more information
+ = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
+
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-74761-2.rs:2:12
+ |
+LL | #![feature(type_alias_impl_trait)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #63063 for more information
+
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-74761-2.rs:9:6
+ |
+LL | impl<'a, 'b> A for () {
+ | ^^ unconstrained lifetime parameter
+
+error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-74761-2.rs:9:10
+ |
+LL | impl<'a, 'b> A for () {
+ | ^^ unconstrained lifetime parameter
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0207, E0658.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
index 38aa18fe40ee7..11756017ad846 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
@@ -5,9 +5,9 @@
#![feature(min_type_alias_impl_trait)]
type X = impl ToString;
-//~^ ERROR could not find defining uses
fn f(a: A, b: B) -> (X, X) {
+ //~^ ERROR concrete type differs from previous defining opaque type
(a.clone(), a)
}
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
index c00973c0761b0..52b0462de988c 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
@@ -1,8 +1,14 @@
-error: could not find defining uses
- --> $DIR/multiple-def-uses-in-one-fn2.rs:7:52
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
|
-LL | type X = impl ToString;
- | ^^^^^^^^^^^^^
+LL | fn f(a: A, b: B) -> (X, X) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `B`
+ |
+note: previous use here
+ --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
+ |
+LL | fn f(a: A, b: B) -> (X, X) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
index 17e900058113d..5f25365666c7f 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
@@ -11,6 +11,7 @@ fn f(a: A, b: B) -> (X, X)
}
fn g(a: A, b: B) -> (X, X) {
+ //~^ ERROR concrete type differs from previous defining opaque type
(a, b)
//~^ ERROR mismatched types
}
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
index bbe709dccab4e..3d943b77af57d 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
@@ -1,10 +1,11 @@
error[E0308]: mismatched types
- --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9
+ --> $DIR/multiple-def-uses-in-one-fn3.rs:15:9
|
LL | fn g(a: A, b: B) -> (X, X) {
| - - found type parameter
| |
| expected type parameter
+LL |
LL | (a, b)
| ^ expected type parameter `A`, found type parameter `B`
|
@@ -13,6 +14,18 @@ LL | (a, b)
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
-error: aborting due to previous error
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/multiple-def-uses-in-one-fn3.rs:13:1
+ |
+LL | fn g(a: A, b: B) -> (X, X) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `[type error]`
+ |
+note: previous use here
+ --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1
+ |
+LL | fn f(a: A, b: B) -> (X, X) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
index a0eb7d10bd94a..f6b48938f9b04 100644
--- a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
+++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
@@ -1,8 +1,11 @@
error[E0277]: the trait bound `(): Foo` is not satisfied
- --> $DIR/wf-foreign-fn-decl-ret.rs:11:12
+ --> $DIR/wf-foreign-fn-decl-ret.rs:11:25
|
+LL | pub trait Foo {
+ | ------------- required by this bound in `Foo`
+...
LL | pub fn lint_me() -> <() as Foo>::Assoc;
- | ^^^^^^^ the trait `Foo` is not implemented for `()`
+ | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
--> $DIR/wf-foreign-fn-decl-ret.rs:14:32
diff --git a/src/test/ui/wf/wf-in-fn-arg.stderr b/src/test/ui/wf/wf-in-fn-arg.stderr
index 9687658feba43..ca90e9222dea9 100644
--- a/src/test/ui/wf/wf-in-fn-arg.stderr
+++ b/src/test/ui/wf/wf-in-fn-arg.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `T: Copy` is not satisfied
- --> $DIR/wf-in-fn-arg.rs:10:14
+ --> $DIR/wf-in-fn-arg.rs:10:15
|
LL | struct MustBeCopy {
| ---- required by this bound in `MustBeCopy`
...
LL | fn bar(_: &MustBeCopy)
- | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
diff --git a/src/test/ui/wf/wf-trait-default-fn-arg.stderr b/src/test/ui/wf/wf-trait-default-fn-arg.stderr
index c3d5d2b9669b8..2a129538f7633 100644
--- a/src/test/ui/wf/wf-trait-default-fn-arg.stderr
+++ b/src/test/ui/wf/wf-trait-default-fn-arg.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `Self: Eq` is not satisfied
- --> $DIR/wf-trait-default-fn-arg.rs:11:22
+ --> $DIR/wf-trait-default-fn-arg.rs:11:23
|
LL | struct Bar { value: Box }
| -- required by this bound in `Bar`
...
LL | fn bar(&self, x: &Bar) {
- | ^^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/test/ui/wf/wf-trait-fn-arg.stderr b/src/test/ui/wf/wf-trait-fn-arg.stderr
index 4510f50feea58..7693aa6d2d583 100644
--- a/src/test/ui/wf/wf-trait-fn-arg.stderr
+++ b/src/test/ui/wf/wf-trait-fn-arg.stderr
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `Self: Eq` is not satisfied
- --> $DIR/wf-trait-fn-arg.rs:10:22
+ --> $DIR/wf-trait-fn-arg.rs:10:23
|
LL | struct Bar { value: Box }
| -- required by this bound in `Bar`
...
LL | fn bar(&self, x: &Bar);
- | ^^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
|
help: consider further restricting `Self`
|
diff --git a/src/tools/cargo b/src/tools/cargo
index 27277d966b3cf..4e143fd131e0c 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 27277d966b3cfa454d6dea7f724cb961c036251c
+Subproject commit 4e143fd131e0c16cefd008456e974236ca54e62e
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
index fe00358888a24..ea105f9396a9d 160000
--- a/src/tools/rust-analyzer
+++ b/src/tools/rust-analyzer
@@ -1 +1 @@
-Subproject commit fe00358888a24c64878abc15f09b0e60e16db9d6
+Subproject commit ea105f9396a9dab68e71efb06016b7c76c83ba7c