diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 11cdbe84accb7..df23eaf24bc6d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -6,7 +6,7 @@ use rustc_infer::infer::{ error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin, }; use rustc_middle::mir::{ConstraintCategory, ReturnConstraint}; -use rustc_middle::ty::subst::Subst; +use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; @@ -334,13 +334,43 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { match variance_info { ty::VarianceDiagInfo::None => {} - ty::VarianceDiagInfo::Mut { kind, ty } => { - let kind_name = match kind { - ty::VarianceDiagMutKind::Ref => "reference", - ty::VarianceDiagMutKind::RawPtr => "pointer", + ty::VarianceDiagInfo::Invariant { ty, param_index } => { + let (desc, note) = match ty.kind() { + ty::RawPtr(ty_mut) => { + assert_eq!(ty_mut.mutbl, rustc_hir::Mutability::Mut); + ( + format!("a mutable pointer to {}", ty_mut.ty), + "mutable pointers are invariant over their type parameter".to_string(), + ) + } + ty::Ref(_, inner_ty, mutbl) => { + assert_eq!(*mutbl, rustc_hir::Mutability::Mut); + ( + format!("a mutable reference to {}", inner_ty), + "mutable references are invariant over their type parameter" + .to_string(), + ) + } + ty::Adt(adt, substs) => { + let generic_arg = substs[param_index as usize]; + let identity_substs = + InternalSubsts::identity_for_item(self.infcx.tcx, adt.did); + let base_ty = self.infcx.tcx.mk_adt(adt, identity_substs); + let base_generic_arg = identity_substs[param_index as usize]; + let adt_desc = adt.descr(); + + let desc = format!( + "the type {ty}, which makes the generic argument {generic_arg} invariant" + ); + let note = format!( + "the {adt_desc} {base_ty} is invariant over the parameter {base_generic_arg}" + ); + (desc, note) + } + _ => panic!("Unexpected type {:?}", ty), }; - diag.note(&format!("requirement occurs because of a mutable {kind_name} to {ty}",)); - diag.note(&format!("mutable {kind_name}s are invariant over their type parameter")); + diag.note(&format!("requirement occurs because of {desc}",)); + diag.note(¬e); diag.help("see for more information about variance"); } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 5e48fbf253db8..da71edbd2d941 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -572,8 +572,9 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { // (e.g., #41849). relate::relate_substs(self, None, a_subst, b_subst) } else { - let opt_variances = self.tcx().variances_of(item_def_id); - relate::relate_substs(self, Some(&opt_variances), a_subst, b_subst) + let tcx = self.tcx(); + let opt_variances = tcx.variances_of(item_def_id); + relate::relate_substs(self, Some((item_def_id, &opt_variances)), a_subst, b_subst) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 37d99766da9d2..78ccfbd5e8cdc 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -77,7 +77,7 @@ pub use self::sty::{ GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts, InlineConstSubstsParts, ParamConst, ParamTy, PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, - UpvarSubsts, VarianceDiagInfo, VarianceDiagMutKind, + UpvarSubsts, VarianceDiagInfo, }; pub use self::trait_def::TraitDef; diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 905a5c47d2b3d..63ed318cadb89 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -6,7 +6,7 @@ use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar}; use crate::ty::error::{ExpectedFound, TypeError}; -use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; +use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_hir as ast; use rustc_hir::def_id::DefId; @@ -59,8 +59,9 @@ pub trait TypeRelation<'tcx>: Sized { item_def_id, a_subst, b_subst ); - let opt_variances = self.tcx().variances_of(item_def_id); - relate_substs(self, Some(opt_variances), a_subst, b_subst) + let tcx = self.tcx(); + let opt_variances = tcx.variances_of(item_def_id); + relate_substs(self, Some((item_def_id, opt_variances)), a_subst, b_subst) } /// Switch variance for the purpose of relating `a` and `b`. @@ -116,7 +117,7 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>( relation: &mut R, a: ty::TypeAndMut<'tcx>, b: ty::TypeAndMut<'tcx>, - kind: ty::VarianceDiagMutKind, + base_ty: Ty<'tcx>, ) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>> { debug!("{}.mts({:?}, {:?})", relation.tag(), a, b); if a.mutbl != b.mutbl { @@ -125,7 +126,9 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>( let mutbl = a.mutbl; let (variance, info) = match mutbl { ast::Mutability::Not => (ty::Covariant, ty::VarianceDiagInfo::None), - ast::Mutability::Mut => (ty::Invariant, ty::VarianceDiagInfo::Mut { kind, ty: a.ty }), + ast::Mutability::Mut => { + (ty::Invariant, ty::VarianceDiagInfo::Invariant { ty: base_ty, param_index: 0 }) + } }; let ty = relation.relate_with_variance(variance, info, a.ty, b.ty)?; Ok(ty::TypeAndMut { ty, mutbl }) @@ -134,15 +137,29 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>( pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>( relation: &mut R, - variances: Option<&[ty::Variance]>, + variances: Option<(DefId, &[ty::Variance])>, a_subst: SubstsRef<'tcx>, b_subst: SubstsRef<'tcx>, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { let tcx = relation.tcx(); + let mut cached_ty = None; let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| { - let variance = variances.map_or(ty::Invariant, |v| v[i]); - relation.relate_with_variance(variance, ty::VarianceDiagInfo::default(), a, b) + let (variance, variance_info) = match variances { + Some((ty_def_id, variances)) => { + let variance = variances[i]; + let variance_info = if variance == ty::Invariant { + let ty = + cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst)); + ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } + } else { + ty::VarianceDiagInfo::default() + }; + (variance, variance_info) + } + None => (ty::Invariant, ty::VarianceDiagInfo::default()), + }; + relation.relate_with_variance(variance, variance_info, a, b) }); tcx.mk_substs(params) @@ -436,7 +453,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( } (&ty::RawPtr(a_mt), &ty::RawPtr(b_mt)) => { - let mt = relate_type_and_mut(relation, a_mt, b_mt, ty::VarianceDiagMutKind::RawPtr)?; + let mt = relate_type_and_mut(relation, a_mt, b_mt, a)?; Ok(tcx.mk_ptr(mt)) } @@ -449,7 +466,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( )?; let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl }; let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl }; - let mt = relate_type_and_mut(relation, a_mt, b_mt, ty::VarianceDiagMutKind::Ref)?; + let mt = relate_type_and_mut(relation, a_mt, b_mt, a)?; Ok(tcx.mk_ref(r, mt)) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8706661b25021..c24a1d8eb529f 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2282,36 +2282,26 @@ pub enum VarianceDiagInfo<'tcx> { /// We will not add any additional information to error messages. #[default] None, - /// We switched our variance because a type occurs inside - /// the generic argument of a mutable reference or pointer - /// (`*mut T` or `&mut T`). In either case, our variance - /// will always be `Invariant`. - Mut { - /// Tracks whether we had a mutable pointer or reference, - /// for better error messages - kind: VarianceDiagMutKind, - /// The type parameter of the mutable pointer/reference - /// (the `T` in `&mut T` or `*mut T`). + /// We switched our variance because a generic argument occurs inside + /// the invariant generic argument of another type. + Invariant { + /// The generic type containing the generic parameter + /// that changes the variance (e.g. `*mut T`, `MyStruct`) ty: Ty<'tcx>, + /// The index of the generic parameter being used + /// (e.g. `0` for `*mut T`, `1` for `MyStruct<'CovariantParam, 'InvariantParam>`) + param_index: u32, }, } -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum VarianceDiagMutKind { - /// A mutable raw pointer (`*mut T`) - RawPtr, - /// A mutable reference (`&mut T`) - Ref, -} - impl<'tcx> VarianceDiagInfo<'tcx> { /// Mirrors `Variance::xform` - used to 'combine' the existing /// and new `VarianceDiagInfo`s when our variance changes. pub fn xform(self, other: VarianceDiagInfo<'tcx>) -> VarianceDiagInfo<'tcx> { - // For now, just use the first `VarianceDiagInfo::Mut` that we see + // For now, just use the first `VarianceDiagInfo::Invariant` that we see match self { VarianceDiagInfo::None => other, - VarianceDiagInfo::Mut { .. } => self, + VarianceDiagInfo::Invariant { .. } => self, } } } diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr index 4fc336122fa9d..01f800811abbb 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.nll.stderr @@ -10,6 +10,9 @@ LL | (a, b) | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant + = note: the struct Type<'a> is invariant over the parameter 'a + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/project-fn-ret-invariant.rs:56:5 @@ -23,6 +26,9 @@ LL | (a, b) | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant + = note: the struct Type<'a> is invariant over the parameter 'a + = help: see for more information about variance help: `'a` and `'b` must be the same: replace one with the other diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr index 44850df7b2f42..e925a424c37e1 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.nll.stderr @@ -10,6 +10,9 @@ LL | let a = bar(f, x); | ^^^^^^^^^ argument requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant + = note: the struct Type<'a> is invariant over the parameter 'a + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/project-fn-ret-invariant.rs:40:13 @@ -23,6 +26,9 @@ LL | let b = bar(f, y); | ^^^^^^^^^ argument requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant + = note: the struct Type<'a> is invariant over the parameter 'a + = help: see for more information about variance help: `'a` and `'b` must be the same: replace one with the other diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr index c417cdd543e4d..0457f142e19d5 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr @@ -6,6 +6,10 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> { ... LL | bar(foo, x) | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant + = note: the struct Type<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index cf73403bbae07..4b03fe1549413 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -7,6 +7,10 @@ LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f | lifetime `'f` defined here LL | ap | ^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'f` + | + = note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant + = note: the struct VaListImpl<'f> is invariant over the parameter 'f + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:8:5 @@ -17,6 +21,10 @@ LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f | lifetime `'f` defined here LL | ap | ^^ returning this value requires that `'1` must outlive `'f` + | + = note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant + = note: the struct VaListImpl<'f> is invariant over the parameter 'f + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:14:5 @@ -25,6 +33,10 @@ LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'stati | -- has type `VaListImpl<'1>` LL | ap | ^^ returning this value requires that `'1` must outlive `'static` + | + = note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant + = note: the struct VaListImpl<'f> is invariant over the parameter 'f + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:18:31 @@ -44,6 +56,10 @@ LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut | has type `&mut VaListImpl<'1>` LL | *ap0 = ap1; | ^^^^ assignment requires that `'1` must outlive `'2` + | + = note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant + = note: the struct VaListImpl<'f> is invariant over the parameter 'f + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:22:5 @@ -54,6 +70,10 @@ LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut | has type `&mut VaListImpl<'1>` LL | *ap0 = ap1; | ^^^^ assignment requires that `'2` must outlive `'1` + | + = note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant + = note: the struct VaListImpl<'f> is invariant over the parameter 'f + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:28:5 @@ -106,6 +126,10 @@ LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut | has type `&mut VaListImpl<'1>` LL | *ap0 = ap1.clone(); | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | + = note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant + = note: the struct VaListImpl<'f> is invariant over the parameter 'f + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:35:12 @@ -116,6 +140,10 @@ LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut | has type `&mut VaListImpl<'1>` LL | *ap0 = ap1.clone(); | ^^^^^^^^^^^ argument requires that `'2` must outlive `'1` + | + = note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant + = note: the struct VaListImpl<'f> is invariant over the parameter 'f + = help: see for more information about variance error: aborting due to 11 previous errors diff --git a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr index e25acebf7f6a8..b4c54d52e5c75 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.nll.stderr @@ -13,6 +13,9 @@ LL | | fn(Inv<'y>)) } | |______________- in this macro invocation | = help: consider adding the following bound: `'x: 'y` + = note: requirement occurs because of the type Inv<'_>, which makes the generic argument '_ invariant + = note: the struct Inv<'a> is invariant over the parameter 'a + = help: see for more information about variance = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) error: lifetime may not live long enough @@ -30,6 +33,9 @@ LL | | fn(Inv<'y>)) } | |______________- in this macro invocation | = help: consider adding the following bound: `'x: 'y` + = note: requirement occurs because of the type Inv<'_>, which makes the generic argument '_ invariant + = note: the struct Inv<'a> is invariant over the parameter 'a + = help: see for more information about variance = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index d77793291c5c5..cf563072dff60 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -51,6 +51,10 @@ LL | | }); | | | | |______`cell_a` escapes the function body here | argument requires that `'a` must outlive `'static` + | + = note: requirement occurs because of the type Cell<&'_#10r u32>, which makes the generic argument &'_#10r u32 invariant + = note: the struct Cell is invariant over the parameter T + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index cc67270ad20c1..453f6801d7e6b 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -51,6 +51,10 @@ LL | | }); | | | | |______`cell_a` escapes the function body here | argument requires that `'a` must outlive `'static` + | + = note: requirement occurs because of the type Cell<&'_#11r u32>, which makes the generic argument &'_#11r u32 invariant + = note: the struct Cell is invariant over the parameter T + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/nll/where_clauses_in_structs.stderr b/src/test/ui/nll/where_clauses_in_structs.stderr index 8499b00f6f556..952667d518d58 100644 --- a/src/test/ui/nll/where_clauses_in_structs.stderr +++ b/src/test/ui/nll/where_clauses_in_structs.stderr @@ -9,6 +9,9 @@ LL | Foo { x, y }; | ^ this usage requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type Cell<&u32>, which makes the generic argument &u32 invariant + = note: the struct Cell is invariant over the parameter T + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr b/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr index e220cbf555956..376534bf573d2 100644 --- a/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr +++ b/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr @@ -11,6 +11,10 @@ LL | x.unwrap() | | | `x` escapes the function body here | argument requires that `'a` must outlive `'static` + | + = note: requirement occurs because of the type Invariant<'_>, which makes the generic argument '_ invariant + = note: the struct Invariant<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr index 47796e50a888f..32f3080ea3714 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr @@ -10,6 +10,9 @@ LL | a.bigger_region(b) | ^^^^^^^^^^^^^^^^^^ argument requires that `'y` must outlive `'x` | = help: consider adding the following bound: `'y: 'x` + = note: requirement occurs because of the type Inv<'_>, which makes the generic argument '_ invariant + = note: the struct Inv<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr index 83d6e13dc0a68..62032bcb6092c 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr @@ -15,6 +15,9 @@ LL | f.method(b); | argument requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type Inv<'_>, which makes the generic argument '_ invariant + = note: the struct Inv<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr index 0c1e3989b234a..fede5f2d7795f 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr @@ -5,6 +5,10 @@ LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | -- lifetime `'r` defined here LL | b_isize | ^^^^^^^ returning this value requires that `'r` must outlive `'static` + | + = note: requirement occurs because of the type Invariant<'_>, which makes the generic argument '_ invariant + = note: the struct Invariant<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr index 0edeb2723998f..8f5f366745352 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr @@ -5,6 +5,10 @@ LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | -- lifetime `'r` defined here LL | b_isize | ^^^^^^^ returning this value requires that `'r` must outlive `'static` + | + = note: requirement occurs because of the type Invariant<'_>, which makes the generic argument '_ invariant + = note: the struct Invariant<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr index 724dd7e3f6d3f..8079fb0ef0d7e 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr @@ -5,6 +5,10 @@ LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | -- lifetime `'r` defined here LL | b_isize | ^^^^^^^ returning this value requires that `'r` must outlive `'static` + | + = note: requirement occurs because of the type Invariant<'_>, which makes the generic argument '_ invariant + = note: the struct Invariant<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/regions/regions-infer-not-param.nll.stderr b/src/test/ui/regions/regions-infer-not-param.nll.stderr index fcc2ec31f3e02..e211f9d1391f9 100644 --- a/src/test/ui/regions/regions-infer-not-param.nll.stderr +++ b/src/test/ui/regions/regions-infer-not-param.nll.stderr @@ -17,6 +17,9 @@ LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | lifetime `'a` defined here | = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type Indirect2<'_>, which makes the generic argument '_ invariant + = note: the struct Indirect2<'a> is invariant over the parameter 'a + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/regions-infer-not-param.rs:19:63 @@ -27,6 +30,9 @@ LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | lifetime `'a` defined here | = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type Indirect2<'_>, which makes the generic argument '_ invariant + = note: the struct Indirect2<'a> is invariant over the parameter 'a + = help: see for more information about variance help: `'b` and `'a` must be the same: replace one with the other diff --git a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr index d51db99f81f7b..8e8ca8e47cce8 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr @@ -10,6 +10,9 @@ LL | let _: Invariant<'short> = c; | ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` | = help: consider adding the following bound: `'short: 'long` + = note: requirement occurs because of the type Invariant<'_>, which makes the generic argument '_ invariant + = note: the struct Invariant<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr index 15853e6ca5d69..f9a3d727f7af9 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr @@ -6,6 +6,10 @@ LL | fn use_<'b>(c: Invariant<'b>) { ... LL | let _: Invariant<'static> = c; | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'static` + | + = note: requirement occurs because of the type Invariant<'_>, which makes the generic argument '_ invariant + = note: the struct Invariant<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/variance/variance-btree-invariant-types.nll.stderr b/src/test/ui/variance/variance-btree-invariant-types.nll.stderr index 1f06949c0331b..867d9f8238a96 100644 --- a/src/test/ui/variance/variance-btree-invariant-types.nll.stderr +++ b/src/test/ui/variance/variance-btree-invariant-types.nll.stderr @@ -5,6 +5,10 @@ LL | fn iter_cov_key<'a, 'new>(v: IterMut<'a, &'static (), ()>) -> IterMut<'a, & | ---- lifetime `'new` defined here LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::IterMut<'_, &(), ()>, which makes the generic argument &() invariant + = note: the struct std::collections::btree_map::IterMut<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:7:5 @@ -13,6 +17,10 @@ LL | fn iter_cov_val<'a, 'new>(v: IterMut<'a, (), &'static ()>) -> IterMut<'a, ( | ---- lifetime `'new` defined here LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::IterMut<'_, (), &()>, which makes the generic argument () invariant + = note: the struct std::collections::btree_map::IterMut<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:10:5 @@ -21,6 +29,10 @@ LL | fn iter_contra_key<'a, 'new>(v: IterMut<'a, &'new (), ()>) -> IterMut<'a, & | ---- lifetime `'new` defined here LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::IterMut<'_, &(), ()>, which makes the generic argument &() invariant + = note: the struct std::collections::btree_map::IterMut<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:13:5 @@ -29,6 +41,10 @@ LL | fn iter_contra_val<'a, 'new>(v: IterMut<'a, (), &'new ()>) -> IterMut<'a, ( | ---- lifetime `'new` defined here LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::IterMut<'_, (), &()>, which makes the generic argument () invariant + = note: the struct std::collections::btree_map::IterMut<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:17:5 @@ -37,6 +53,10 @@ LL | fn range_cov_key<'a, 'new>(v: RangeMut<'a, &'static (), ()>) -> RangeMut<'a | ---- lifetime `'new` defined here LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type RangeMut<'_, &(), ()>, which makes the generic argument &() invariant + = note: the struct RangeMut<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:20:5 @@ -45,6 +65,10 @@ LL | fn range_cov_val<'a, 'new>(v: RangeMut<'a, (), &'static ()>) -> RangeMut<'a | ---- lifetime `'new` defined here LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type RangeMut<'_, (), &()>, which makes the generic argument () invariant + = note: the struct RangeMut<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:23:5 @@ -53,6 +77,10 @@ LL | fn range_contra_key<'a, 'new>(v: RangeMut<'a, &'new (), ()>) -> RangeMut<'a | ---- lifetime `'new` defined here LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type RangeMut<'_, &(), ()>, which makes the generic argument &() invariant + = note: the struct RangeMut<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:26:5 @@ -61,6 +89,10 @@ LL | fn range_contra_val<'a, 'new>(v: RangeMut<'a, (), &'new ()>) -> RangeMut<'a | ---- lifetime `'new` defined here LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type RangeMut<'_, (), &()>, which makes the generic argument () invariant + = note: the struct RangeMut<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:31:5 @@ -70,6 +102,10 @@ LL | fn occ_cov_key<'a, 'new>(v: OccupiedEntry<'a, &'static (), ()>) LL | -> OccupiedEntry<'a, &'new (), ()> { LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::OccupiedEntry<'_, &(), ()>, which makes the generic argument &() invariant + = note: the struct std::collections::btree_map::OccupiedEntry<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:35:5 @@ -79,6 +115,10 @@ LL | fn occ_cov_val<'a, 'new>(v: OccupiedEntry<'a, (), &'static ()>) LL | -> OccupiedEntry<'a, (), &'new ()> { LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::OccupiedEntry<'_, (), &()>, which makes the generic argument () invariant + = note: the struct std::collections::btree_map::OccupiedEntry<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:39:5 @@ -88,6 +128,10 @@ LL | fn occ_contra_key<'a, 'new>(v: OccupiedEntry<'a, &'new (), ()>) LL | -> OccupiedEntry<'a, &'static (), ()> { LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::OccupiedEntry<'_, &(), ()>, which makes the generic argument &() invariant + = note: the struct std::collections::btree_map::OccupiedEntry<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:43:5 @@ -97,6 +141,10 @@ LL | fn occ_contra_val<'a, 'new>(v: OccupiedEntry<'a, (), &'new ()>) LL | -> OccupiedEntry<'a, (), &'static ()> { LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::OccupiedEntry<'_, (), &()>, which makes the generic argument () invariant + = note: the struct std::collections::btree_map::OccupiedEntry<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:48:5 @@ -106,6 +154,10 @@ LL | fn vac_cov_key<'a, 'new>(v: VacantEntry<'a, &'static (), ()>) LL | -> VacantEntry<'a, &'new (), ()> { LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::VacantEntry<'_, &(), ()>, which makes the generic argument &() invariant + = note: the struct std::collections::btree_map::VacantEntry<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:52:5 @@ -115,6 +167,10 @@ LL | fn vac_cov_val<'a, 'new>(v: VacantEntry<'a, (), &'static ()>) LL | -> VacantEntry<'a, (), &'new ()> { LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::VacantEntry<'_, (), &()>, which makes the generic argument () invariant + = note: the struct std::collections::btree_map::VacantEntry<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:56:5 @@ -124,6 +180,10 @@ LL | fn vac_contra_key<'a, 'new>(v: VacantEntry<'a, &'new (), ()>) LL | -> VacantEntry<'a, &'static (), ()> { LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::VacantEntry<'_, &(), ()>, which makes the generic argument &() invariant + = note: the struct std::collections::btree_map::VacantEntry<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-btree-invariant-types.rs:60:5 @@ -133,6 +193,10 @@ LL | fn vac_contra_val<'a, 'new>(v: VacantEntry<'a, (), &'new ()>) LL | -> VacantEntry<'a, (), &'static ()> { LL | v | ^ returning this value requires that `'new` must outlive `'static` + | + = note: requirement occurs because of the type std::collections::btree_map::VacantEntry<'_, (), &()>, which makes the generic argument () invariant + = note: the struct std::collections::btree_map::VacantEntry<'a, K, V> is invariant over the parameter K + = help: see for more information about variance error: aborting due to 16 previous errors diff --git a/src/test/ui/variance/variance-cell-is-invariant.nll.stderr b/src/test/ui/variance/variance-cell-is-invariant.nll.stderr index 1fcdfc4b5bbb2..d6a85680141dc 100644 --- a/src/test/ui/variance/variance-cell-is-invariant.nll.stderr +++ b/src/test/ui/variance/variance-cell-is-invariant.nll.stderr @@ -10,6 +10,9 @@ LL | let _: Foo<'long> = c; | ^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` | = help: consider adding the following bound: `'short: 'long` + = note: requirement occurs because of the type Foo<'_>, which makes the generic argument '_ invariant + = note: the struct Foo<'a> is invariant over the parameter 'a + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr b/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr index 385d83adaf830..6890cb115c398 100644 --- a/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr +++ b/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr @@ -10,6 +10,9 @@ LL | v | ^ returning this value requires that `'min` must outlive `'max` | = help: consider adding the following bound: `'min: 'max` + = note: requirement occurs because of the type SomeStruct<&()>, which makes the generic argument &() invariant + = note: the struct SomeStruct is invariant over the parameter T + = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variance-use-invariant-struct-1.rs:19:5 @@ -23,6 +26,9 @@ LL | v | ^ returning this value requires that `'min` must outlive `'max` | = help: consider adding the following bound: `'min: 'max` + = note: requirement occurs because of the type SomeStruct<&()>, which makes the generic argument &() invariant + = note: the struct SomeStruct is invariant over the parameter T + = help: see for more information about variance error: aborting due to 2 previous errors