diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index d52e54191006..71a4623cd629 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1,6 +1,5 @@
//! Code for projecting associated types out of trait references.
-use super::elaborate_predicates;
use super::specialization_graph;
use super::translate_substs;
use super::util;
@@ -53,13 +52,16 @@ pub enum ProjectionTyError<'tcx> {
#[derive(PartialEq, Eq, Debug)]
enum ProjectionTyCandidate<'tcx> {
- // from a where-clause in the env or object type
+ /// From a where-clause in the env or object type
ParamEnv(ty::PolyProjectionPredicate<'tcx>),
- // from the definition of `Trait` when you have something like <::B as Trait2>::C
+ /// From the definition of `Trait` when you have something like <::B as Trait2>::C
TraitDef(ty::PolyProjectionPredicate<'tcx>),
- // from a "impl" (or a "pseudo-impl" returned by select)
+ /// Bounds specified on an object type
+ Object(ty::PolyProjectionPredicate<'tcx>),
+
+ /// From a "impl" (or a "pseudo-impl" returned by select)
Select(Selection<'tcx>),
}
@@ -561,14 +563,6 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
} else {
obligations.extend(ty.obligations);
}
-
- obligations.push(get_paranoid_cache_value_obligation(
- infcx,
- param_env,
- projection_ty,
- cause,
- depth,
- ));
return Ok(Some(ty.value));
}
Err(ProjectionCacheEntry::Error) => {
@@ -703,45 +697,6 @@ fn prune_cache_value_obligations<'a, 'tcx>(
NormalizedTy { value: result.value, obligations }
}
-/// Whenever we give back a cache result for a projection like `::Item ==> X`, we *always* include the obligation to prove
-/// that `T: Trait` (we may also include some other obligations). This
-/// may or may not be necessary -- in principle, all the obligations
-/// that must be proven to show that `T: Trait` were also returned
-/// when the cache was first populated. But there are some vague concerns,
-/// and so we take the precautionary measure of including `T: Trait` in
-/// the result:
-///
-/// Concern #1. The current setup is fragile. Perhaps someone could
-/// have failed to prove the concerns from when the cache was
-/// populated, but also not have used a snapshot, in which case the
-/// cache could remain populated even though `T: Trait` has not been
-/// shown. In this case, the "other code" is at fault -- when you
-/// project something, you are supposed to either have a snapshot or
-/// else prove all the resulting obligations -- but it's still easy to
-/// get wrong.
-///
-/// Concern #2. Even within the snapshot, if those original
-/// obligations are not yet proven, then we are able to do projections
-/// that may yet turn out to be wrong. This *may* lead to some sort
-/// of trouble, though we don't have a concrete example of how that
-/// can occur yet. But it seems risky at best.
-fn get_paranoid_cache_value_obligation<'a, 'tcx>(
- infcx: &'a InferCtxt<'a, 'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- projection_ty: ty::ProjectionTy<'tcx>,
- cause: ObligationCause<'tcx>,
- depth: usize,
-) -> PredicateObligation<'tcx> {
- let trait_ref = projection_ty.trait_ref(infcx.tcx).to_poly_trait_ref();
- Obligation {
- cause,
- recursion_depth: depth,
- param_env,
- predicate: trait_ref.without_const().to_predicate(infcx.tcx),
- }
-}
-
/// If we are projecting `::Item`, but `T: Trait` does not
/// hold. In various error cases, we cannot generate a valid
/// normalized projection. Therefore, we create an inference variable
@@ -848,12 +803,21 @@ fn project_type<'cx, 'tcx>(
assemble_candidates_from_trait_def(selcx, obligation, &obligation_trait_ref, &mut candidates);
- assemble_candidates_from_impls(selcx, obligation, &obligation_trait_ref, &mut candidates);
+ assemble_candidates_from_object_ty(selcx, obligation, &obligation_trait_ref, &mut candidates);
+
+ if let ProjectionTyCandidateSet::Single(ProjectionTyCandidate::Object(_)) = candidates {
+ // Avoid normalization cycle from selection (see
+ // `assemble_candidates_from_object_ty`).
+ // FIXME(lazy_normalization): Lazy normalization should save us from
+ // having to do special case this.
+ } else {
+ assemble_candidates_from_impls(selcx, obligation, &obligation_trait_ref, &mut candidates);
+ };
match candidates {
- ProjectionTyCandidateSet::Single(candidate) => Ok(ProjectedTy::Progress(
- confirm_candidate(selcx, obligation, &obligation_trait_ref, candidate),
- )),
+ ProjectionTyCandidateSet::Single(candidate) => {
+ Ok(ProjectedTy::Progress(confirm_candidate(selcx, obligation, candidate)))
+ }
ProjectionTyCandidateSet::None => Ok(ProjectedTy::NoProgress(
selcx
.tcx()
@@ -932,6 +896,53 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
)
}
+/// In the case of a trait object like
+/// ` as Iterator>::Item` we can use the existential
+/// predicate in the trait object.
+///
+/// We don't go through the select candidate for these bounds to avoid cycles:
+/// In the above case, `dyn Iterator- : Iterator` would create a
+/// nested obligation of ` as Iterator>::Item: Sized`,
+/// this then has to be normalized without having to prove
+/// `dyn Iterator
- : Iterator` again.
+fn assemble_candidates_from_object_ty<'cx, 'tcx>(
+ selcx: &mut SelectionContext<'cx, 'tcx>,
+ obligation: &ProjectionTyObligation<'tcx>,
+ obligation_trait_ref: &ty::TraitRef<'tcx>,
+ candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
+) {
+ debug!("assemble_candidates_from_object_ty(..)");
+
+ let tcx = selcx.tcx();
+
+ let self_ty = obligation_trait_ref.self_ty();
+ let object_ty = selcx.infcx().shallow_resolve(self_ty);
+ let data = match object_ty.kind {
+ ty::Dynamic(ref data, ..) => data,
+ ty::Infer(ty::TyVar(_)) => {
+ // If the self-type is an inference variable, then it MAY wind up
+ // being an object type, so induce an ambiguity.
+ candidate_set.mark_ambiguous();
+ return;
+ }
+ _ => return,
+ };
+ let env_predicates = data
+ .projection_bounds()
+ .filter(|bound| bound.item_def_id() == obligation.predicate.item_def_id)
+ .map(|p| p.with_self_ty(tcx, object_ty).to_predicate(tcx));
+
+ assemble_candidates_from_predicates(
+ selcx,
+ obligation,
+ obligation_trait_ref,
+ candidate_set,
+ ProjectionTyCandidate::Object,
+ env_predicates,
+ false,
+ );
+}
+
fn assemble_candidates_from_predicates<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
@@ -1000,7 +1011,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
super::ImplSource::Closure(_)
| super::ImplSource::Generator(_)
| super::ImplSource::FnPointer(_)
- | super::ImplSource::Object(_)
| super::ImplSource::TraitAlias(_) => {
debug!("assemble_candidates_from_impls: impl_source={:?}", impl_source);
true
@@ -1125,6 +1135,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// in `assemble_candidates_from_param_env`.
false
}
+ super::ImplSource::Object(_) => {
+ // Handled by the `Object` projection candidate. See
+ // `assemble_candidates_from_object_ty` for an explanation of
+ // why we special case object types.
+ false
+ }
super::ImplSource::AutoImpl(..) | super::ImplSource::Builtin(..) => {
// These traits have no associated types.
selcx.tcx().sess.delay_span_bug(
@@ -1150,13 +1166,13 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
fn confirm_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
- obligation_trait_ref: &ty::TraitRef<'tcx>,
candidate: ProjectionTyCandidate<'tcx>,
) -> Progress<'tcx> {
debug!("confirm_candidate(candidate={:?}, obligation={:?})", candidate, obligation);
let mut progress = match candidate {
- ProjectionTyCandidate::ParamEnv(poly_projection) => {
+ ProjectionTyCandidate::ParamEnv(poly_projection)
+ | ProjectionTyCandidate::Object(poly_projection) => {
confirm_param_env_candidate(selcx, obligation, poly_projection, false)
}
@@ -1165,7 +1181,7 @@ fn confirm_candidate<'cx, 'tcx>(
}
ProjectionTyCandidate::Select(impl_source) => {
- confirm_select_candidate(selcx, obligation, obligation_trait_ref, impl_source)
+ confirm_select_candidate(selcx, obligation, impl_source)
}
};
// When checking for cycle during evaluation, we compare predicates with
@@ -1182,7 +1198,6 @@ fn confirm_candidate<'cx, 'tcx>(
fn confirm_select_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
- obligation_trait_ref: &ty::TraitRef<'tcx>,
impl_source: Selection<'tcx>,
) -> Progress<'tcx> {
match impl_source {
@@ -1193,10 +1208,8 @@ fn confirm_select_candidate<'cx, 'tcx>(
super::ImplSource::DiscriminantKind(data) => {
confirm_discriminant_kind_candidate(selcx, obligation, data)
}
- super::ImplSource::Object(_) => {
- confirm_object_candidate(selcx, obligation, obligation_trait_ref)
- }
- super::ImplSource::AutoImpl(..)
+ super::ImplSource::Object(_)
+ | super::ImplSource::AutoImpl(..)
| super::ImplSource::Param(..)
| super::ImplSource::Builtin(..)
| super::ImplSource::TraitAlias(..) =>
@@ -1211,72 +1224,6 @@ fn confirm_select_candidate<'cx, 'tcx>(
}
}
-fn confirm_object_candidate<'cx, 'tcx>(
- selcx: &mut SelectionContext<'cx, 'tcx>,
- obligation: &ProjectionTyObligation<'tcx>,
- obligation_trait_ref: &ty::TraitRef<'tcx>,
-) -> Progress<'tcx> {
- let self_ty = obligation_trait_ref.self_ty();
- let object_ty = selcx.infcx().shallow_resolve(self_ty);
- debug!("confirm_object_candidate(object_ty={:?})", object_ty);
- let data = match object_ty.kind() {
- ty::Dynamic(data, ..) => data,
- _ => span_bug!(
- obligation.cause.span,
- "confirm_object_candidate called with non-object: {:?}",
- object_ty
- ),
- };
- let env_predicates = data
- .projection_bounds()
- .map(|p| p.with_self_ty(selcx.tcx(), object_ty).to_predicate(selcx.tcx()));
- let env_predicate = {
- let env_predicates = elaborate_predicates(selcx.tcx(), env_predicates);
-
- // select only those projections that are actually projecting an
- // item with the correct name
-
- let env_predicates = env_predicates.filter_map(|o| match o.predicate.skip_binders() {
- ty::PredicateAtom::Projection(data)
- if data.projection_ty.item_def_id == obligation.predicate.item_def_id =>
- {
- Some(ty::Binder::bind(data))
- }
- _ => None,
- });
-
- // select those with a relevant trait-ref
- let mut env_predicates = env_predicates.filter(|data| {
- let data_poly_trait_ref = data.to_poly_trait_ref(selcx.tcx());
- let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
- selcx.infcx().probe(|_| {
- selcx
- .infcx()
- .at(&obligation.cause, obligation.param_env)
- .sup(obligation_poly_trait_ref, data_poly_trait_ref)
- .is_ok()
- })
- });
-
- // select the first matching one; there really ought to be one or
- // else the object type is not WF, since an object type should
- // include all of its projections explicitly
- match env_predicates.next() {
- Some(env_predicate) => env_predicate,
- None => {
- debug!(
- "confirm_object_candidate: no env-predicate \
- found in object type `{:?}`; ill-formed",
- object_ty
- );
- return Progress::error(selcx.tcx());
- }
- }
- };
-
- confirm_param_env_candidate(selcx, obligation, env_predicate, false)
-}
-
fn confirm_generator_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index e6fce78f269c..1e68554fecf5 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -9,11 +9,10 @@
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::lang_items::LangItem;
use rustc_index::bit_set::GrowableBitSet;
+use rustc_infer::infer::InferOk;
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
-use rustc_infer::infer::{self, InferOk};
-use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{ToPolyTraitRef, ToPredicate, WithConstness};
use rustc_span::def_id::DefId;
@@ -434,100 +433,54 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
vtable_base = nonmatching.map(|t| super::util::count_own_vtable_entries(tcx, t)).sum();
}
- // Check supertraits hold
- nested.extend(util::supertraits(tcx, obligation_trait_ref).skip(1).map(|super_trait| {
- Obligation::new(
- obligation.cause.clone(),
- obligation.param_env,
- super_trait.without_const().to_predicate(tcx),
- )
- }));
-
let upcast_trait_ref = upcast_trait_ref.unwrap();
+ // Check supertraits hold
+ nested.extend(
+ tcx.super_predicates_of(trait_predicate.def_id())
+ .instantiate(tcx, trait_predicate.trait_ref.substs)
+ .predicates
+ .into_iter()
+ .map(|super_trait| {
+ Obligation::new(obligation.cause.clone(), obligation.param_env, super_trait)
+ }),
+ );
+
let assoc_types: Vec<_> = tcx
- .associated_items(upcast_trait_ref.def_id())
+ .associated_items(trait_predicate.def_id())
.in_definition_order()
.filter_map(
|item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None },
)
.collect();
- if !assoc_types.is_empty() {
- let predicates: Vec<_> =
- data.iter()
- .filter_map(|pred| match pred {
- ty::ExistentialPredicate::Projection(proj) => {
- if assoc_types.contains(&proj.item_def_id) {
- match self.infcx.commit_if_ok(|_| {
- self.infcx
- .at(&obligation.cause, obligation.param_env)
- .sup(
- ty::Binder::dummy(
- proj.trait_ref(tcx).with_self_ty(tcx, self_ty),
- ),
- upcast_trait_ref,
- )
- .map(|InferOk { obligations, .. }| obligations)
- .map_err(|_| ())
- }) {
- Ok(obligations) => {
- nested.extend(obligations);
- Some(proj)
- }
- Err(_) => None,
- }
- } else {
- None
- }
- }
- ty::ExistentialPredicate::AutoTrait(_)
- | ty::ExistentialPredicate::Trait(_) => None,
- })
- .collect();
-
- let upcast_trait_ref = upcast_trait_ref
- .no_bound_vars()
- .expect("sup shouldn't return binder with bound vars");
- let mut normalizer = ObjectAssociatedTypeNormalizer {
- infcx: self.infcx,
- object_ty: self_ty,
- object_bounds: &predicates,
- param_env: obligation.param_env,
- cause: &obligation.cause,
- nested: &mut nested,
- };
- for assoc_type in assoc_types {
- if !tcx.generics_of(assoc_type).params.is_empty() {
- // FIXME(generic_associated_types) generate placeholders to
- // extend the trait substs.
- tcx.sess.span_fatal(
- obligation.cause.span,
- "generic associated types in trait objects are not supported yet",
- );
- }
- // This maybe belongs in wf, but that can't (doesn't) handle
- // higher-ranked things.
- // Prevent, e.g., `dyn Iterator
- `.
- for bound in self.tcx().item_bounds(assoc_type) {
- let subst_bound = bound.subst(tcx, upcast_trait_ref.substs);
- // Normalize projections the trait object manually to
- // avoid evaluation overflow.
- let object_normalized = subst_bound.fold_with(&mut normalizer);
- let normalized_bound = normalize_with_depth_to(
- self,
- obligation.param_env,
- obligation.cause.clone(),
- obligation.recursion_depth + 1,
- &object_normalized,
- normalizer.nested,
- );
- normalizer.nested.push(Obligation::new(
- obligation.cause.clone(),
- obligation.param_env.clone(),
- normalized_bound,
- ));
- }
+ for assoc_type in assoc_types {
+ if !tcx.generics_of(assoc_type).params.is_empty() {
+ // FIXME(generic_associated_types) generate placeholders to
+ // extend the trait substs.
+ tcx.sess.span_fatal(
+ obligation.cause.span,
+ "generic associated types in trait objects are not supported yet",
+ );
+ }
+ // This maybe belongs in wf, but that can't (doesn't) handle
+ // higher-ranked things.
+ // Prevent, e.g., `dyn Iterator
- `.
+ for bound in self.tcx().item_bounds(assoc_type) {
+ let subst_bound = bound.subst(tcx, trait_predicate.trait_ref.substs);
+ let normalized_bound = normalize_with_depth_to(
+ self,
+ obligation.param_env,
+ obligation.cause.clone(),
+ obligation.recursion_depth + 1,
+ &subst_bound,
+ &mut nested,
+ );
+ nested.push(Obligation::new(
+ obligation.cause.clone(),
+ obligation.param_env.clone(),
+ normalized_bound,
+ ));
}
}
@@ -972,50 +925,3 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Ok(ImplSourceBuiltinData { nested })
}
}
-
-struct ObjectAssociatedTypeNormalizer<'a, 'tcx> {
- infcx: &'a infer::InferCtxt<'a, 'tcx>,
- object_ty: Ty<'tcx>,
- object_bounds: &'a [ty::ExistentialProjection<'tcx>],
- param_env: ty::ParamEnv<'tcx>,
- cause: &'a ObligationCause<'tcx>,
- nested: &'a mut Vec>,
-}
-
-impl<'tcx> TypeFolder<'tcx> for ObjectAssociatedTypeNormalizer<'_, 'tcx> {
- fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
- self.infcx.tcx
- }
-
- fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
- if !t.has_projections() {
- return t;
- }
- if let ty::Projection(proj) = t.kind {
- if let ty::Dynamic(..) = proj.self_ty().kind {
- for bound in self.object_bounds {
- if proj.item_def_id == bound.item_def_id {
- // FIXME(generic_associated_types): This isn't relating
- // the substs for the associated type.
- match self.infcx.commit_if_ok(|_| {
- self.infcx.at(self.cause, self.param_env).sub(
- bound
- .with_self_ty(self.infcx.tcx, self.object_ty)
- .projection_ty
- .trait_ref(self.infcx.tcx),
- proj.trait_ref(self.infcx.tcx),
- )
- }) {
- Ok(InferOk { value: (), obligations }) => {
- self.nested.extend(obligations);
- return bound.ty;
- }
- Err(_) => {}
- }
- }
- }
- }
- }
- t.super_fold_with(self)
- }
-}
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 147b0c74d16e..d0c0e658c921 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -441,8 +441,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> Result {
debug!(
"evaluate_predicate_recursively(obligation={:?}, previous_stack={:?})",
- previous_stack.head(),
- obligation
+ obligation,
+ previous_stack.head()
);
// `previous_stack` stores a `TraitObligation`, while `obligation` is
diff --git a/src/test/ui/regions/regions-enum-not-wf.rs b/src/test/ui/regions/regions-enum-not-wf.rs
index 781cdb7286a0..6de08f66d753 100644
--- a/src/test/ui/regions/regions-enum-not-wf.rs
+++ b/src/test/ui/regions/regions-enum-not-wf.rs
@@ -5,17 +5,18 @@
#![allow(dead_code)]
trait Dummy<'a> {
- type Out;
+ type Out;
}
impl<'a, T> Dummy<'a> for T
-where T: 'a
+where
+ T: 'a,
{
- type Out = ();
+ type Out = ();
}
type RequireOutlives<'a, T> = >::Out;
enum Ref1<'a, T> {
- Ref1Variant1(RequireOutlives<'a, T>) //~ ERROR the parameter type `T` may not live long enough
+ Ref1Variant1(RequireOutlives<'a, T>), //~ ERROR the parameter type `T` may not live long enough
}
enum Ref2<'a, T> {
@@ -23,18 +24,18 @@ enum Ref2<'a, T> {
Ref2Variant2(isize, RequireOutlives<'a, T>), //~ ERROR the parameter type `T` may not live long enough
}
-enum RefOk<'a, T:'a> {
- RefOkVariant1(&'a T)
+enum RefOk<'a, T: 'a> {
+ RefOkVariant1(&'a T),
}
// This is now well formed. RFC 2093
enum RefIndirect<'a, T> {
- RefIndirectVariant1(isize, RefOk<'a,T>)
+ RefIndirectVariant1(isize, RefOk<'a, T>),
}
-enum RefDouble<'a, 'b, T> { //~ ERROR the parameter type `T` may not live long enough [E0309]
- RefDoubleVariant1(&'a RequireOutlives<'b, T>)
- //~^ the parameter type `T` may not live long enough [E0309]
+enum RefDouble<'a, 'b, T> {
+ RefDoubleVariant1(&'a RequireOutlives<'b, T>),
+ //~^ the parameter type `T` may not live long enough [E0309]
}
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/regions/regions-enum-not-wf.stderr b/src/test/ui/regions/regions-enum-not-wf.stderr
index e32a36f72cd1..36686eaf92f3 100644
--- a/src/test/ui/regions/regions-enum-not-wf.stderr
+++ b/src/test/ui/regions/regions-enum-not-wf.stderr
@@ -1,13 +1,13 @@
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/regions-enum-not-wf.rs:18:18
+ --> $DIR/regions-enum-not-wf.rs:19:18
|
LL | enum Ref1<'a, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
-LL | Ref1Variant1(RequireOutlives<'a, T>)
+LL | Ref1Variant1(RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/regions-enum-not-wf.rs:23:25
+ --> $DIR/regions-enum-not-wf.rs:24:25
|
LL | enum Ref2<'a, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
@@ -16,25 +16,13 @@ LL | Ref2Variant2(isize, RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/regions-enum-not-wf.rs:35:1
- |
-LL | enum RefDouble<'a, 'b, T> {
- | ^ - help: consider adding an explicit lifetime bound...: `T: 'b`
- | _|
- | |
-LL | | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
-LL | |
-LL | | }
- | |_^ ...so that the type `T` will meet its required lifetime bounds
-
-error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/regions-enum-not-wf.rs:36:23
+ --> $DIR/regions-enum-not-wf.rs:37:23
|
LL | enum RefDouble<'a, 'b, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'b`
-LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
+LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...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
For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.rs b/src/test/ui/regions/regions-normalize-in-where-clause-list.rs
index e912805d855d..9912e88c2ec5 100644
--- a/src/test/ui/regions/regions-normalize-in-where-clause-list.rs
+++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.rs
@@ -6,7 +6,8 @@ trait Project<'a, 'b> {
}
impl<'a, 'b> Project<'a, 'b> for ()
- where 'a: 'b
+where
+ 'a: 'b,
{
type Item = ();
}
@@ -14,16 +15,18 @@ impl<'a, 'b> Project<'a, 'b> for ()
// No error here, we have 'a: 'b. We used to report an error here
// though, see https://github.com/rust-lang/rust/issues/45937.
fn foo<'a: 'b, 'b>()
- where <() as Project<'a, 'b>>::Item : Eq
+where
+ <() as Project<'a, 'b>>::Item: Eq,
{
}
// Here we get an error: we need `'a: 'b`.
-fn bar<'a, 'b>() //~ ERROR cannot infer
- //~| ERROR cannot infer
- //~| ERROR cannot infer
- where <() as Project<'a, 'b>>::Item : Eq
+fn bar<'a, 'b>()
+//~^ ERROR cannot infer
+//~| ERROR cannot infer
+where
+ <() as Project<'a, 'b>>::Item: Eq,
{
}
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
index 10ecb8d52629..24bf64261e9d 100644
--- a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
+++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
@@ -1,5 +1,5 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
- --> $DIR/regions-normalize-in-where-clause-list.rs:22:1
+ --> $DIR/regions-normalize-in-where-clause-list.rs:24:1
|
LL | / fn bar<'a, 'b>()
LL | |
@@ -7,18 +7,18 @@ LL | |
LL | | where <() as Project<'a, 'b>>::Item : Eq
| |____________________________________________^
|
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:8...
- --> $DIR/regions-normalize-in-where-clause-list.rs:22:8
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 24:8...
+ --> $DIR/regions-normalize-in-where-clause-list.rs:24:8
|
LL | fn bar<'a, 'b>()
| ^^
-note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the function body at 22:12...
- --> $DIR/regions-normalize-in-where-clause-list.rs:22:12
+note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the function body at 24:12...
+ --> $DIR/regions-normalize-in-where-clause-list.rs:24:12
|
LL | fn bar<'a, 'b>()
| ^^
note: ...so that the types are compatible
- --> $DIR/regions-normalize-in-where-clause-list.rs:22:1
+ --> $DIR/regions-normalize-in-where-clause-list.rs:24:1
|
LL | / fn bar<'a, 'b>()
LL | |
@@ -64,24 +64,24 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
LL | fn bar<'a, 'b>()
| ^^^
|
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:8...
- --> $DIR/regions-normalize-in-where-clause-list.rs:22:8
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 24:8...
+ --> $DIR/regions-normalize-in-where-clause-list.rs:24:8
|
LL | fn bar<'a, 'b>()
| ^^
-note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the function body at 22:12...
- --> $DIR/regions-normalize-in-where-clause-list.rs:22:12
+note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the function body at 24:12...
+ --> $DIR/regions-normalize-in-where-clause-list.rs:24:12
|
LL | fn bar<'a, 'b>()
| ^^
note: ...so that the types are compatible
- --> $DIR/regions-normalize-in-where-clause-list.rs:22:4
+ --> $DIR/regions-normalize-in-where-clause-list.rs:24:4
|
LL | fn bar<'a, 'b>()
| ^^^
= note: expected `Project<'a, 'b>`
found `Project<'_, '_>`
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs
index 781cdb7286a0..6de08f66d753 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs
@@ -5,17 +5,18 @@
#![allow(dead_code)]
trait Dummy<'a> {
- type Out;
+ type Out;
}
impl<'a, T> Dummy<'a> for T
-where T: 'a
+where
+ T: 'a,
{
- type Out = ();
+ type Out = ();
}
type RequireOutlives<'a, T> = >::Out;
enum Ref1<'a, T> {
- Ref1Variant1(RequireOutlives<'a, T>) //~ ERROR the parameter type `T` may not live long enough
+ Ref1Variant1(RequireOutlives<'a, T>), //~ ERROR the parameter type `T` may not live long enough
}
enum Ref2<'a, T> {
@@ -23,18 +24,18 @@ enum Ref2<'a, T> {
Ref2Variant2(isize, RequireOutlives<'a, T>), //~ ERROR the parameter type `T` may not live long enough
}
-enum RefOk<'a, T:'a> {
- RefOkVariant1(&'a T)
+enum RefOk<'a, T: 'a> {
+ RefOkVariant1(&'a T),
}
// This is now well formed. RFC 2093
enum RefIndirect<'a, T> {
- RefIndirectVariant1(isize, RefOk<'a,T>)
+ RefIndirectVariant1(isize, RefOk<'a, T>),
}
-enum RefDouble<'a, 'b, T> { //~ ERROR the parameter type `T` may not live long enough [E0309]
- RefDoubleVariant1(&'a RequireOutlives<'b, T>)
- //~^ the parameter type `T` may not live long enough [E0309]
+enum RefDouble<'a, 'b, T> {
+ RefDoubleVariant1(&'a RequireOutlives<'b, T>),
+ //~^ the parameter type `T` may not live long enough [E0309]
}
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
index e32a36f72cd1..36686eaf92f3 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
@@ -1,13 +1,13 @@
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/regions-enum-not-wf.rs:18:18
+ --> $DIR/regions-enum-not-wf.rs:19:18
|
LL | enum Ref1<'a, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
-LL | Ref1Variant1(RequireOutlives<'a, T>)
+LL | Ref1Variant1(RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/regions-enum-not-wf.rs:23:25
+ --> $DIR/regions-enum-not-wf.rs:24:25
|
LL | enum Ref2<'a, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
@@ -16,25 +16,13 @@ LL | Ref2Variant2(isize, RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/regions-enum-not-wf.rs:35:1
- |
-LL | enum RefDouble<'a, 'b, T> {
- | ^ - help: consider adding an explicit lifetime bound...: `T: 'b`
- | _|
- | |
-LL | | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
-LL | |
-LL | | }
- | |_^ ...so that the type `T` will meet its required lifetime bounds
-
-error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/regions-enum-not-wf.rs:36:23
+ --> $DIR/regions-enum-not-wf.rs:37:23
|
LL | enum RefDouble<'a, 'b, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'b`
-LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
+LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...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
For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/traits/cycle-cache-err-60010.rs b/src/test/ui/traits/cycle-cache-err-60010.rs
index 62d558fde888..98bfcb8d67b5 100644
--- a/src/test/ui/traits/cycle-cache-err-60010.rs
+++ b/src/test/ui/traits/cycle-cache-err-60010.rs
@@ -24,7 +24,7 @@ struct Runtime {
_storage: Box,
}
struct SalsaStorage {
- _parse: >::Data, //~ ERROR overflow
+ _parse: >::Data,
}
impl Database for RootDatabase {
@@ -67,6 +67,7 @@ pub(crate) fn goto_implementation(db: &RootDatabase) -> u32 {
// we used to fail to report an error here because we got the
// caching wrong.
SourceDatabase::parse(db);
+ //~^ ERROR overflow
22
}
diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr
index 25b1f427f3a1..738b052a11eb 100644
--- a/src/test/ui/traits/cycle-cache-err-60010.stderr
+++ b/src/test/ui/traits/cycle-cache-err-60010.stderr
@@ -1,10 +1,18 @@
-error[E0275]: overflow evaluating the requirement `RootDatabase: SourceDatabase`
- --> $DIR/cycle-cache-err-60010.rs:27:13
+error[E0275]: overflow evaluating the requirement `SalsaStorage: std::panic::RefUnwindSafe`
+ --> $DIR/cycle-cache-err-60010.rs:69:5
|
-LL | _parse: >::Data,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn parse(&self) {
+ | --------------- required by `SourceDatabase::parse`
+...
+LL | SourceDatabase::parse(db);
+ | ^^^^^^^^^^^^^^^^^^^^^
|
- = note: required because of the requirements on the impl of `Query` for `ParseQuery`
+ = note: required because it appears within the type `*const SalsaStorage`
+ = note: required because it appears within the type `std::ptr::Unique`
+ = note: required because it appears within the type `std::boxed::Box`
+ = note: required because it appears within the type `Runtime`
+ = note: required because it appears within the type `RootDatabase`
+ = note: required because of the requirements on the impl of `SourceDatabase` for `RootDatabase`
error[E0275]: overflow evaluating the requirement `Runtime: RefUnwindSafe`
--> $DIR/cycle-cache-err-60010.rs:31:20