diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 22edee33c5c1b..59cc1786ef6fc 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -151,7 +151,6 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { fn visit_ascribe_user_ty( &mut self, _place: &Place<'tcx>, - _variance: &ty::Variance, _user_ty: &UserTypeProjection, _location: Location, ) { diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 2876d60527fe7..eb92ab9a80a71 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -6,7 +6,7 @@ use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; /// Replaces all free regions appearing in the MIR with fresh -/// inference variables, returning the number of variables created. +/// inference variables. #[instrument(skip(infcx, body, promoted), level = "debug")] pub fn renumber_mir<'tcx>( infcx: &InferCtxt<'_, 'tcx>, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 46924f50d2e1b..c24fc0a1adbbe 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -365,7 +365,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { if let Some(annotation_index) = constant.user_ty { if let Err(terr) = self.cx.relate_type_and_user_type( constant.literal.ty(), - ty::Variance::Invariant, &UserTypeProjection { base: annotation_index, projs: vec![] }, location.to_locations(), ConstraintCategory::Boring, @@ -425,6 +424,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { ConstraintCategory::Boring, self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( constant.literal.ty(), + ty::Variance::Invariant, uv.def.did, UserSubsts { substs: uv.substs, user_self_ty: None }, )), @@ -492,7 +492,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { if let Err(terr) = self.cx.relate_type_and_user_type( ty, - ty::Variance::Invariant, user_ty, Locations::All(*span), ConstraintCategory::TypeAnnotation, @@ -1068,15 +1067,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.user_type_annotations ); for user_annotation in self.user_type_annotations { - let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; + let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty, variance } = + *user_annotation; let inferred_ty = self.normalize(inferred_ty, Locations::All(span)); let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty); match annotation { UserType::Ty(mut ty) => { ty = self.normalize(ty, Locations::All(span)); - if let Err(terr) = self.eq_types( + // `ty` and `inferred_ty` are swapped for + // better diagnostics. + if let Err(terr) = self.relate_types( ty, + variance.xform(ty::Variance::Contravariant), inferred_ty, Locations::All(span), ConstraintCategory::BoringNoLocation, @@ -1104,6 +1107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::BoringNoLocation, self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( inferred_ty, + variance, def_id, user_substs, )), @@ -1174,7 +1178,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn relate_type_and_user_type( &mut self, a: Ty<'tcx>, - v: ty::Variance, user_ty: &UserTypeProjection, locations: Locations, category: ConstraintCategory, @@ -1202,7 +1205,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); let ty = curr_projected_ty.ty; - self.relate_types(ty, v.xform(ty::Variance::Contravariant), a, locations, category)?; + self.relate_types(ty, ty::Variance::Invariant, a, locations, category)?; Ok(()) } @@ -1397,7 +1400,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(annotation_index) = self.rvalue_user_ty(rv) { if let Err(terr) = self.relate_type_and_user_type( rv_ty, - ty::Variance::Invariant, &UserTypeProjection { base: annotation_index, projs: vec![] }, location.to_locations(), ConstraintCategory::Boring, @@ -1449,11 +1451,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); }; } - StatementKind::AscribeUserType(box (ref place, ref projection), variance) => { + StatementKind::AscribeUserType(box (ref place, ref projection)) => { let place_ty = place.ty(body, tcx).ty; if let Err(terr) = self.relate_type_and_user_type( place_ty, - variance, projection, Locations::All(stmt.source_info.span), ConstraintCategory::TypeAnnotation, diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 274fb211b7bbb..03c95b4810cac 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -517,7 +517,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag(_, _) - | StatementKind::AscribeUserType(_, _) + | StatementKind::AscribeUserType(_) | StatementKind::Coverage(_) | StatementKind::Nop => {} } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 7e5f8018dfc42..082e7a2a0b713 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1581,7 +1581,7 @@ pub enum StatementKind<'tcx> { /// - `Contravariant` -- requires that `T_y :> T` /// - `Invariant` -- requires that `T_y == T` /// - `Bivariant` -- no effect - AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance), + AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>), /// Marks the start of a "coverage region", injected with '-Cinstrument-coverage'. A /// `Coverage` statement carries metadata about the coverage region, used to inject a coverage @@ -1705,8 +1705,8 @@ impl Debug for Statement<'_> { SetDiscriminant { ref place, variant_index } => { write!(fmt, "discriminant({:?}) = {:?}", place, variant_index) } - AscribeUserType(box (ref place, ref c_ty), ref variance) => { - write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty) + AscribeUserType(box (ref place, ref c_ty)) => { + write!(fmt, "AscribeUserType({:?}, {:?})", place, c_ty) } Coverage(box self::Coverage { ref kind, code_region: Some(ref rgn) }) => { write!(fmt, "Coverage::{:?} for {:?}", kind, rgn) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index a618800cc1bd2..b4d6e7deab33a 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -128,10 +128,9 @@ macro_rules! make_mir_visitor { fn visit_ascribe_user_ty(&mut self, place: & $($mutability)? Place<'tcx>, - variance: & $($mutability)? ty::Variance, user_ty: & $($mutability)? UserTypeProjection, location: Location) { - self.super_ascribe_user_ty(place, variance, user_ty, location); + self.super_ascribe_user_ty(place, user_ty, location); } fn visit_coverage(&mut self, @@ -413,9 +412,8 @@ macro_rules! make_mir_visitor { } StatementKind::AscribeUserType( box(ref $($mutability)? place, ref $($mutability)? user_ty), - variance ) => { - self.visit_ascribe_user_ty(place, variance, user_ty, location); + self.visit_ascribe_user_ty(place, user_ty, location); } StatementKind::Coverage(coverage) => { self.visit_coverage( @@ -775,7 +773,6 @@ macro_rules! make_mir_visitor { fn super_ascribe_user_ty(&mut self, place: & $($mutability)? Place<'tcx>, - _variance: & $($mutability)? ty::Variance, user_ty: & $($mutability)? UserTypeProjection, location: Location) { self.visit_place( diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 04bc0c8b52114..ab47c47a5d852 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -552,14 +552,16 @@ impl<'tcx> PatTyProj<'tcx> { pub fn user_ty( self, annotations: &mut CanonicalUserTypeAnnotations<'tcx>, - inferred_ty: Ty<'tcx>, span: Span, + inferred_ty: Ty<'tcx>, + variance: ty::Variance, ) -> UserTypeProjection { UserTypeProjection { base: annotations.push(CanonicalUserTypeAnnotation { span, user_ty: self.user_ty, inferred_ty, + variance, }), projs: Vec::new(), } diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 07cfe83b01438..83e2accfdd69b 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -20,20 +20,26 @@ use std::mem; pub mod type_op { use crate::ty::fold::TypeFoldable; use crate::ty::subst::UserSubsts; - use crate::ty::{Predicate, Ty}; + use crate::ty::{self, Predicate, Ty}; use rustc_hir::def_id::DefId; use std::fmt; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct AscribeUserType<'tcx> { pub mir_ty: Ty<'tcx>, + pub variance: ty::Variance, pub def_id: DefId, pub user_substs: UserSubsts<'tcx>, } impl<'tcx> AscribeUserType<'tcx> { - pub fn new(mir_ty: Ty<'tcx>, def_id: DefId, user_substs: UserSubsts<'tcx>) -> Self { - Self { mir_ty, def_id, user_substs } + pub fn new( + mir_ty: Ty<'tcx>, + variance: ty::Variance, + def_id: DefId, + user_substs: UserSubsts<'tcx>, + ) -> Self { + Self { mir_ty, variance, def_id, user_substs } } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 41145d250173f..1166b359d9db5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -22,6 +22,7 @@ use crate::ty::{ FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, + Variance, }; use rustc_ast as ast; use rustc_attr as attr; @@ -833,6 +834,13 @@ pub struct CanonicalUserTypeAnnotation<'tcx> { pub user_ty: CanonicalUserType<'tcx>, pub span: Span, pub inferred_ty: Ty<'tcx>, + /// The variance relation inferred type and the user type. + /// + /// If this is covariant, then `inferred_ty` has to be a subtype of `user_ty`. + /// + /// As the variance is already applied from `user_ty` to `inferred_ty`, all + /// other uses of `inferred_ty` should be invariant. + pub variance: Variance, } /// Canonicalized user type annotation. diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 0c0b0f2bd05af..d698a32b42fb9 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -4,7 +4,7 @@ use crate::build::Builder; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::CanonicalUserTypeAnnotation; +use rustc_middle::ty::{CanonicalUserTypeAnnotation, Variance}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that @@ -22,6 +22,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span, user_ty, inferred_ty: ty, + variance: Variance::Invariant, }) }); assert_eq!(literal.ty(), ty); diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 1e94c41d88daa..5342382163b44 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -493,6 +493,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: source_info.span, user_ty, inferred_ty: expr.ty, + variance: Variance::Invariant, }); let place = place_builder.clone().into_place(this.tcx, this.typeck_results); @@ -500,13 +501,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, Statement { source_info, - kind: StatementKind::AscribeUserType( - Box::new(( - place, - UserTypeProjection { base: annotation_index, projs: vec![] }, - )), - Variance::Invariant, - ), + kind: StatementKind::AscribeUserType(Box::new(( + place, + UserTypeProjection { base: annotation_index, projs: vec![] }, + ))), }, ); } @@ -522,18 +520,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: source_info.span, user_ty, inferred_ty: expr.ty, + variance: Variance::Invariant, }); this.cfg.push( block, Statement { source_info, - kind: StatementKind::AscribeUserType( - Box::new(( - Place::from(temp), - UserTypeProjection { base: annotation_index, projs: vec![] }, - )), - Variance::Invariant, - ), + kind: StatementKind::AscribeUserType(Box::new(( + Place::from(temp), + UserTypeProjection { base: annotation_index, projs: vec![] }, + ))), }, ); } diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index c706e6ef1d466..57636aae9cd71 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::{self, CanonicalUserTypeAnnotation}; +use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Variance}; use std::iter; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -364,6 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: source_info.span, user_ty: ty, inferred_ty, + variance: Variance::Invariant, }) }); let adt = Box::new(AggregateKind::Adt( diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index ec8cb30965d75..69a6a43e698bd 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -19,7 +19,7 @@ use rustc_index::bit_set::BitSet; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{self, *}; -use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty}; +use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance}; use rustc_span::symbol::Symbol; use rustc_span::{BytePos, Pos, Span}; use rustc_target::abi::VariantIdx; @@ -538,31 +538,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let ty_source_info = self.source_info(user_ty_span); let user_ty = pat_ascription_ty.user_ty( &mut self.canonical_user_type_annotations, - place.ty(&self.local_decls, self.tcx).ty, ty_source_info.span, + place.ty(&self.local_decls, self.tcx).ty, + Variance::Invariant, ); self.cfg.push( block, Statement { source_info: ty_source_info, - kind: StatementKind::AscribeUserType( - Box::new((place, user_ty)), - // We always use invariant as the variance here. This is because the - // variance field from the ascription refers to the variance to use - // when applying the type to the value being matched, but this - // ascription applies rather to the type of the binding. e.g., in this - // example: - // - // ``` - // let x: T = - // ``` - // - // We are creating an ascription that defines the type of `x` to be - // exactly `T` (i.e., with invariance). The variance field, in - // contrast, is intended to be used to relate `T` to the type of - // ``. - ty::Variance::Invariant, - ), + kind: StatementKind::AscribeUserType(Box::new((place, user_ty))), }, ); @@ -796,6 +780,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: user_ty_span, user_ty: user_ty.user_ty, inferred_ty: subpattern.ty, + variance: Variance::Invariant, }; let projection = UserTypeProjection { base: self.canonical_user_type_annotations.push(annotation), @@ -2076,17 +2061,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let user_ty = ascription.user_ty.user_ty( &mut self.canonical_user_type_annotations, - ascription.source.ty(&self.local_decls, self.tcx).ty, source_info.span, + ascription.source.ty(&self.local_decls, self.tcx).ty, + ascription.variance, ); self.cfg.push( block, Statement { source_info, - kind: StatementKind::AscribeUserType( - Box::new((ascription.source, user_ty)), - ascription.variance, - ), + kind: StatementKind::AscribeUserType(Box::new((ascription.source, user_ty))), }, ); } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index d1cb2826dedfc..036d7e8b5d8cb 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -833,7 +833,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option | StatementKind::Assign(_) | StatementKind::SetDiscriminant { .. } | StatementKind::Retag(_, _) - | StatementKind::AscribeUserType(_, _) => { + | StatementKind::AscribeUserType(_) => { Some(statement.source_info.span) } } diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index d265720e18296..00d143b04e279 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -244,7 +244,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData< StatementKind::FakeRead(_) | StatementKind::StorageLive(_) | StatementKind::Retag(_, _) - | StatementKind::AscribeUserType(_, _) + | StatementKind::AscribeUserType(_) | StatementKind::Coverage(_) | StatementKind::StorageDead(_) | StatementKind::CopyNonOverlapping(_) @@ -311,7 +311,7 @@ fn find_determining_place<'tcx>( | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag(_, _) - | StatementKind::AscribeUserType(_, _) + | StatementKind::AscribeUserType(_) | StatementKind::Coverage(_) | StatementKind::CopyNonOverlapping(_) | StatementKind::Nop => {} diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 6fcac9fcdc622..0dcd6cf87148d 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -53,14 +53,14 @@ pub fn type_op_ascribe_user_type_with_span<'a, 'tcx: 'a>( key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>, span: Option, ) -> Result<(), NoSolution> { - let (param_env, AscribeUserType { mir_ty, def_id, user_substs }) = key.into_parts(); + let (param_env, AscribeUserType { mir_ty, variance, def_id, user_substs }) = key.into_parts(); debug!( "type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}", mir_ty, def_id, user_substs ); let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx }; - cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs, span)?; + cx.relate_mir_and_user_ty(mir_ty, variance, def_id, user_substs, span)?; Ok(()) } @@ -121,6 +121,7 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { fn relate_mir_and_user_ty( &mut self, mir_ty: Ty<'tcx>, + variance: ty::Variance, def_id: DefId, user_substs: UserSubsts<'tcx>, span: Option, @@ -133,7 +134,7 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); let ty = self.normalize(ty); - self.relate(mir_ty, Variance::Invariant, ty)?; + self.relate(mir_ty, variance, ty)?; // Prove the predicates coming along with `def_id`. // diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index e26f0033156bc..0c2d8ffd2821c 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -447,7 +447,7 @@ impl UnifyKey for FloatVid { } } -#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash)] +#[derive(Copy, Clone, Decodable, Encodable, Hash, PartialEq, Eq)] pub enum Variance { Covariant, // T <: T iff A <: B -- e.g., function return type Invariant, // T <: T iff B == A -- e.g., type of mutable cell diff --git a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index 9fa478f8a826c..409d70f301d51 100644 --- a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -139,7 +139,7 @@ fn address_of_reborrow() -> () { StorageLive(_5); // scope 2 at $DIR/address-of.rs:7:5: 7:18 StorageLive(_6); // scope 2 at $DIR/address-of.rs:7:5: 7:18 _6 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:7:5: 7:6 - AscribeUserType(_6, o, UserTypeProjection { base: UserType(0), projs: [] }); // scope 2 at $DIR/address-of.rs:7:5: 7:18 + AscribeUserType(_6, UserTypeProjection { base: UserType(0), projs: [] }); // scope 2 at $DIR/address-of.rs:7:5: 7:18 _5 = _6; // scope 2 at $DIR/address-of.rs:7:5: 7:18 StorageDead(_6); // scope 2 at $DIR/address-of.rs:7:18: 7:19 StorageDead(_5); // scope 2 at $DIR/address-of.rs:7:18: 7:19 @@ -152,7 +152,7 @@ fn address_of_reborrow() -> () { _10 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:9:5: 9:6 _9 = move _10 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:9:5: 9:6 StorageDead(_10); // scope 2 at $DIR/address-of.rs:9:5: 9:6 - AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/address-of.rs:9:5: 9:25 + AscribeUserType(_9, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/address-of.rs:9:5: 9:25 _8 = _9; // scope 2 at $DIR/address-of.rs:9:5: 9:25 StorageDead(_9); // scope 2 at $DIR/address-of.rs:9:25: 9:26 StorageDead(_8); // scope 2 at $DIR/address-of.rs:9:25: 9:26 @@ -171,29 +171,29 @@ fn address_of_reborrow() -> () { StorageLive(_15); // scope 2 at $DIR/address-of.rs:13:9: 13:10 _15 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:13:23: 13:24 FakeRead(ForLet(None), _15); // scope 2 at $DIR/address-of.rs:13:9: 13:10 - AscribeUserType(_15, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address-of.rs:13:12: 13:20 + AscribeUserType(_15, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address-of.rs:13:12: 13:20 StorageLive(_16); // scope 3 at $DIR/address-of.rs:14:9: 14:10 _16 = &raw const (*_1); // scope 3 at $DIR/address-of.rs:14:31: 14:32 FakeRead(ForLet(None), _16); // scope 3 at $DIR/address-of.rs:14:9: 14:10 - AscribeUserType(_16, o, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address-of.rs:14:12: 14:28 + AscribeUserType(_16, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address-of.rs:14:12: 14:28 StorageLive(_17); // scope 4 at $DIR/address-of.rs:15:9: 15:10 StorageLive(_18); // scope 4 at $DIR/address-of.rs:15:30: 15:31 _18 = &raw const (*_1); // scope 4 at $DIR/address-of.rs:15:30: 15:31 _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 4 at $DIR/address-of.rs:15:30: 15:31 StorageDead(_18); // scope 4 at $DIR/address-of.rs:15:30: 15:31 FakeRead(ForLet(None), _17); // scope 4 at $DIR/address-of.rs:15:9: 15:10 - AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address-of.rs:15:12: 15:27 + AscribeUserType(_17, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address-of.rs:15:12: 15:27 StorageLive(_19); // scope 5 at $DIR/address-of.rs:16:9: 16:10 StorageLive(_20); // scope 5 at $DIR/address-of.rs:16:27: 16:28 _20 = &raw const (*_1); // scope 5 at $DIR/address-of.rs:16:27: 16:28 _19 = move _20 as *const [i32] (Pointer(Unsize)); // scope 5 at $DIR/address-of.rs:16:27: 16:28 StorageDead(_20); // scope 5 at $DIR/address-of.rs:16:27: 16:28 FakeRead(ForLet(None), _19); // scope 5 at $DIR/address-of.rs:16:9: 16:10 - AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address-of.rs:16:12: 16:24 + AscribeUserType(_19, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address-of.rs:16:12: 16:24 StorageLive(_21); // scope 6 at $DIR/address-of.rs:18:5: 18:18 StorageLive(_22); // scope 6 at $DIR/address-of.rs:18:5: 18:18 _22 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:18:5: 18:6 - AscribeUserType(_22, o, UserTypeProjection { base: UserType(10), projs: [] }); // scope 6 at $DIR/address-of.rs:18:5: 18:18 + AscribeUserType(_22, UserTypeProjection { base: UserType(10), projs: [] }); // scope 6 at $DIR/address-of.rs:18:5: 18:18 _21 = _22; // scope 6 at $DIR/address-of.rs:18:5: 18:18 StorageDead(_22); // scope 6 at $DIR/address-of.rs:18:18: 18:19 StorageDead(_21); // scope 6 at $DIR/address-of.rs:18:18: 18:19 @@ -206,7 +206,7 @@ fn address_of_reborrow() -> () { _26 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:20:5: 20:6 _25 = move _26 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:20:5: 20:6 StorageDead(_26); // scope 6 at $DIR/address-of.rs:20:5: 20:6 - AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] }); // scope 6 at $DIR/address-of.rs:20:5: 20:25 + AscribeUserType(_25, UserTypeProjection { base: UserType(11), projs: [] }); // scope 6 at $DIR/address-of.rs:20:5: 20:25 _24 = _25; // scope 6 at $DIR/address-of.rs:20:5: 20:25 StorageDead(_25); // scope 6 at $DIR/address-of.rs:20:25: 20:26 StorageDead(_24); // scope 6 at $DIR/address-of.rs:20:25: 20:26 @@ -219,29 +219,29 @@ fn address_of_reborrow() -> () { StorageLive(_29); // scope 6 at $DIR/address-of.rs:23:9: 23:10 _29 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:23:23: 23:24 FakeRead(ForLet(None), _29); // scope 6 at $DIR/address-of.rs:23:9: 23:10 - AscribeUserType(_29, o, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address-of.rs:23:12: 23:20 + AscribeUserType(_29, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address-of.rs:23:12: 23:20 StorageLive(_30); // scope 7 at $DIR/address-of.rs:24:9: 24:10 _30 = &raw const (*_3); // scope 7 at $DIR/address-of.rs:24:31: 24:32 FakeRead(ForLet(None), _30); // scope 7 at $DIR/address-of.rs:24:9: 24:10 - AscribeUserType(_30, o, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address-of.rs:24:12: 24:28 + AscribeUserType(_30, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address-of.rs:24:12: 24:28 StorageLive(_31); // scope 8 at $DIR/address-of.rs:25:9: 25:10 StorageLive(_32); // scope 8 at $DIR/address-of.rs:25:30: 25:31 _32 = &raw const (*_3); // scope 8 at $DIR/address-of.rs:25:30: 25:31 _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 8 at $DIR/address-of.rs:25:30: 25:31 StorageDead(_32); // scope 8 at $DIR/address-of.rs:25:30: 25:31 FakeRead(ForLet(None), _31); // scope 8 at $DIR/address-of.rs:25:9: 25:10 - AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address-of.rs:25:12: 25:27 + AscribeUserType(_31, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address-of.rs:25:12: 25:27 StorageLive(_33); // scope 9 at $DIR/address-of.rs:26:9: 26:10 StorageLive(_34); // scope 9 at $DIR/address-of.rs:26:27: 26:28 _34 = &raw const (*_3); // scope 9 at $DIR/address-of.rs:26:27: 26:28 _33 = move _34 as *const [i32] (Pointer(Unsize)); // scope 9 at $DIR/address-of.rs:26:27: 26:28 StorageDead(_34); // scope 9 at $DIR/address-of.rs:26:27: 26:28 FakeRead(ForLet(None), _33); // scope 9 at $DIR/address-of.rs:26:9: 26:10 - AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address-of.rs:26:12: 26:24 + AscribeUserType(_33, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address-of.rs:26:12: 26:24 StorageLive(_35); // scope 10 at $DIR/address-of.rs:28:5: 28:16 StorageLive(_36); // scope 10 at $DIR/address-of.rs:28:5: 28:16 _36 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:28:5: 28:6 - AscribeUserType(_36, o, UserTypeProjection { base: UserType(20), projs: [] }); // scope 10 at $DIR/address-of.rs:28:5: 28:16 + AscribeUserType(_36, UserTypeProjection { base: UserType(20), projs: [] }); // scope 10 at $DIR/address-of.rs:28:5: 28:16 _35 = _36; // scope 10 at $DIR/address-of.rs:28:5: 28:16 StorageDead(_36); // scope 10 at $DIR/address-of.rs:28:16: 28:17 StorageDead(_35); // scope 10 at $DIR/address-of.rs:28:16: 28:17 @@ -254,7 +254,7 @@ fn address_of_reborrow() -> () { _40 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:30:5: 30:6 _39 = move _40 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:30:5: 30:6 StorageDead(_40); // scope 10 at $DIR/address-of.rs:30:5: 30:6 - AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] }); // scope 10 at $DIR/address-of.rs:30:5: 30:23 + AscribeUserType(_39, UserTypeProjection { base: UserType(21), projs: [] }); // scope 10 at $DIR/address-of.rs:30:5: 30:23 _38 = _39; // scope 10 at $DIR/address-of.rs:30:5: 30:23 StorageDead(_39); // scope 10 at $DIR/address-of.rs:30:23: 30:24 StorageDead(_38); // scope 10 at $DIR/address-of.rs:30:23: 30:24 @@ -267,25 +267,25 @@ fn address_of_reborrow() -> () { StorageLive(_43); // scope 10 at $DIR/address-of.rs:33:9: 33:10 _43 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:33:21: 33:22 FakeRead(ForLet(None), _43); // scope 10 at $DIR/address-of.rs:33:9: 33:10 - AscribeUserType(_43, o, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address-of.rs:33:12: 33:18 + AscribeUserType(_43, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address-of.rs:33:12: 33:18 StorageLive(_44); // scope 11 at $DIR/address-of.rs:34:9: 34:10 _44 = &raw mut (*_3); // scope 11 at $DIR/address-of.rs:34:29: 34:30 FakeRead(ForLet(None), _44); // scope 11 at $DIR/address-of.rs:34:9: 34:10 - AscribeUserType(_44, o, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address-of.rs:34:12: 34:26 + AscribeUserType(_44, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address-of.rs:34:12: 34:26 StorageLive(_45); // scope 12 at $DIR/address-of.rs:35:9: 35:10 StorageLive(_46); // scope 12 at $DIR/address-of.rs:35:28: 35:29 _46 = &raw mut (*_3); // scope 12 at $DIR/address-of.rs:35:28: 35:29 _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 12 at $DIR/address-of.rs:35:28: 35:29 StorageDead(_46); // scope 12 at $DIR/address-of.rs:35:28: 35:29 FakeRead(ForLet(None), _45); // scope 12 at $DIR/address-of.rs:35:9: 35:10 - AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address-of.rs:35:12: 35:25 + AscribeUserType(_45, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address-of.rs:35:12: 35:25 StorageLive(_47); // scope 13 at $DIR/address-of.rs:36:9: 36:10 StorageLive(_48); // scope 13 at $DIR/address-of.rs:36:25: 36:26 _48 = &raw mut (*_3); // scope 13 at $DIR/address-of.rs:36:25: 36:26 _47 = move _48 as *mut [i32] (Pointer(Unsize)); // scope 13 at $DIR/address-of.rs:36:25: 36:26 StorageDead(_48); // scope 13 at $DIR/address-of.rs:36:25: 36:26 FakeRead(ForLet(None), _47); // scope 13 at $DIR/address-of.rs:36:9: 36:10 - AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address-of.rs:36:12: 36:22 + AscribeUserType(_47, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address-of.rs:36:12: 36:22 _0 = const (); // scope 0 at $DIR/address-of.rs:3:26: 37:2 StorageDead(_47); // scope 13 at $DIR/address-of.rs:37:1: 37:2 StorageDead(_45); // scope 12 at $DIR/address-of.rs:37:1: 37:2 diff --git a/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir index e751b825c0505..4293ba777d74d 100644 --- a/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir @@ -37,7 +37,7 @@ fn main() -> () { StorageLive(_4); // scope 2 at $DIR/basic_assignment.rs:18:9: 18:15 _4 = Option::>::None; // scope 2 at $DIR/basic_assignment.rs:18:36: 18:40 FakeRead(ForLet(None), _4); // scope 2 at $DIR/basic_assignment.rs:18:9: 18:15 - AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/basic_assignment.rs:18:17: 18:33 + AscribeUserType(_4, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/basic_assignment.rs:18:17: 18:33 StorageLive(_5); // scope 3 at $DIR/basic_assignment.rs:19:9: 19:15 StorageLive(_6); // scope 4 at $DIR/basic_assignment.rs:23:14: 23:20 _6 = move _4; // scope 4 at $DIR/basic_assignment.rs:23:14: 23:20 diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir index 3c26b20c35e2d..8b796fcb8e1fc 100644 --- a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir @@ -30,7 +30,7 @@ fn main() -> () { bb1: { StorageDead(_3); // scope 2 at $DIR/issue-72181-1.rs:17:43: 17:44 FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10 - AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:16:12: 16:16 + AscribeUserType(_2, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:16:12: 16:16 StorageLive(_4); // scope 1 at $DIR/issue-72181-1.rs:20:5: 20:9 StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8 _5 = move _2; // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8 diff --git a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir b/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir index f1a1f388c501a..bb38284ef828e 100644 --- a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir +++ b/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir @@ -37,7 +37,7 @@ fn main() -> () { bb1: { FakeRead(ForLet(None), _1); // scope 0 at $DIR/receiver-ptr-mutability.rs:14:9: 14:12 - AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver-ptr-mutability.rs:14:14: 14:23 + AscribeUserType(_1, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver-ptr-mutability.rs:14:14: 14:23 StorageLive(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:15:5: 15:12 StorageLive(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:15:5: 15:12 StorageLive(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:15:5: 15:8 @@ -64,7 +64,7 @@ fn main() -> () { _6 = &_7; // scope 1 at $DIR/receiver-ptr-mutability.rs:18:34: 18:41 _5 = &(*_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:34: 18:41 FakeRead(ForLet(None), _5); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:9: 18:16 - AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:18: 18:31 + AscribeUserType(_5, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:18: 18:31 StorageDead(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:41: 18:42 StorageLive(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:19:5: 19:16 StorageLive(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:19:5: 19:16 diff --git a/src/test/ui/hr-subtype/placeholder-pattern-fail.rs b/src/test/ui/hr-subtype/placeholder-pattern-fail.rs new file mode 100644 index 0000000000000..3b5b075cb582e --- /dev/null +++ b/src/test/ui/hr-subtype/placeholder-pattern-fail.rs @@ -0,0 +1,27 @@ +// Check that incorrect higher ranked subtyping +// causes an error. +struct Inv<'a>(fn(&'a ()) -> &'a ()); +fn hr_subtype<'c>(f: for<'a, 'b> fn(Inv<'a>, Inv<'a>)) { + // ok + let _: for<'a> fn(Inv<'a>, Inv<'a>) = f; + let sub: for<'a> fn(Inv<'a>, Inv<'a>) = f; + // no + let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; + //~^ ERROR mismatched types +} + +fn simple1<'c>(x: (&'c i32,)) { + let _x: (&'static i32,) = x; + //~^ ERROR mismatched types +} + +fn simple2<'c>(x: (&'c i32,)) { + let _: (&'static i32,) = x; + //~^ ERROR mismatched types +} + +fn main() { + hr_subtype(|_, _| {}); + simple1((&3,)); + simple2((&3,)); +} diff --git a/src/test/ui/hr-subtype/placeholder-pattern-fail.stderr b/src/test/ui/hr-subtype/placeholder-pattern-fail.stderr new file mode 100644 index 0000000000000..7bd5308052b0f --- /dev/null +++ b/src/test/ui/hr-subtype/placeholder-pattern-fail.stderr @@ -0,0 +1,42 @@ +error[E0308]: mismatched types + --> $DIR/placeholder-pattern-fail.rs:9:47 + | +LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; + | ^^^ one type is more general than the other + | + = note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)` + found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)` + +error[E0308]: mismatched types + --> $DIR/placeholder-pattern-fail.rs:14:31 + | +LL | let _x: (&'static i32,) = x; + | ^ lifetime mismatch + | + = note: expected tuple `(&'static i32,)` + found tuple `(&'c i32,)` +note: the lifetime `'c` as defined here... + --> $DIR/placeholder-pattern-fail.rs:13:12 + | +LL | fn simple1<'c>(x: (&'c i32,)) { + | ^^ + = note: ...does not necessarily outlive the static lifetime + +error[E0308]: mismatched types + --> $DIR/placeholder-pattern-fail.rs:19:30 + | +LL | let _: (&'static i32,) = x; + | ^ lifetime mismatch + | + = note: expected tuple `(&'static i32,)` + found tuple `(&'c i32,)` +note: the lifetime `'c` as defined here... + --> $DIR/placeholder-pattern-fail.rs:18:12 + | +LL | fn simple2<'c>(x: (&'c i32,)) { + | ^^ + = note: ...does not necessarily outlive the static lifetime + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/placeholder-pattern.rs b/src/test/ui/hr-subtype/placeholder-pattern.rs new file mode 100644 index 0000000000000..061e66e54d2f4 --- /dev/null +++ b/src/test/ui/hr-subtype/placeholder-pattern.rs @@ -0,0 +1,18 @@ +// check-pass +// Check that higher ranked subtyping correctly works when using +// placeholder patterns. +fn hr_subtype<'c>(f: for<'a, 'b> fn(&'a (), &'b ())) { + let _: for<'a> fn(&'a (), &'a ()) = f; + let _: for<'a, 'b> fn(&'a (), &'b ()) = f; + let _: for<'a> fn(&'a (), &'c ()) = f; + let _: fn(&'c (), &'c ()) = f; +} + +fn simple<'c>(x: (&'static i32,)) { + let _: (&'c i32,) = x; +} + +fn main() { + hr_subtype(|_, _| {}); + simple((&3,)); +} diff --git a/src/test/ui/lifetimes/re-empty-in-error.rs b/src/test/ui/lifetimes/re-empty-in-error.rs new file mode 100644 index 0000000000000..41c3718592dee --- /dev/null +++ b/src/test/ui/lifetimes/re-empty-in-error.rs @@ -0,0 +1,10 @@ +// We didn't have a single test mentioning +// `ReEmpty` and this test changes that. +fn foo<'a>(_a: &'a u32) where for<'b> &'b (): 'a { + //~^ NOTE type must outlive the empty lifetime as required by this binding +} + +fn main() { + foo(&10); + //~^ ERROR the type `&'b ()` does not fulfill the required lifetime +} diff --git a/src/test/ui/lifetimes/re-empty-in-error.stderr b/src/test/ui/lifetimes/re-empty-in-error.stderr new file mode 100644 index 0000000000000..227e3ca613961 --- /dev/null +++ b/src/test/ui/lifetimes/re-empty-in-error.stderr @@ -0,0 +1,15 @@ +error[E0477]: the type `&'b ()` does not fulfill the required lifetime + --> $DIR/re-empty-in-error.rs:8:5 + | +LL | foo(&10); + | ^^^ + | +note: type must outlive the empty lifetime as required by this binding + --> $DIR/re-empty-in-error.rs:3:47 + | +LL | fn foo<'a>(_a: &'a u32) where for<'b> &'b (): 'a { + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0477`. diff --git a/src/test/ui/nll/user-annotations/issue-57280-1-flipped.rs b/src/test/ui/nll/user-annotations/issue-57280-1-flipped.rs new file mode 100644 index 0000000000000..ad4b8dcfde432 --- /dev/null +++ b/src/test/ui/nll/user-annotations/issue-57280-1-flipped.rs @@ -0,0 +1,23 @@ +// This test should compile, as the lifetimes +// in matches don't really matter. +// +// We currently use contravariance when checking the +// type of match arms. + +trait Foo<'a> { + const C: &'a u32; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a>(x: &'static u32) { + match x { + <() as Foo<'a>>::C => { } + //~^ ERROR lifetime may not live long enough + &_ => { } + } +} + +fn main() {} diff --git a/src/test/ui/nll/user-annotations/issue-57280-1-flipped.stderr b/src/test/ui/nll/user-annotations/issue-57280-1-flipped.stderr new file mode 100644 index 0000000000000..7a2135a2ade83 --- /dev/null +++ b/src/test/ui/nll/user-annotations/issue-57280-1-flipped.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-57280-1-flipped.rs:17:9 + | +LL | fn foo<'a>(x: &'static u32) { + | -- lifetime `'a` defined here +LL | match x { +LL | <() as Foo<'a>>::C => { } + | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/issue-57280-1.rs b/src/test/ui/nll/user-annotations/issue-57280-1.rs similarity index 100% rename from src/test/ui/nll/issue-57280-1.rs rename to src/test/ui/nll/user-annotations/issue-57280-1.rs diff --git a/src/test/ui/nll/issue-57280.rs b/src/test/ui/nll/user-annotations/issue-57280.rs similarity index 100% rename from src/test/ui/nll/issue-57280.rs rename to src/test/ui/nll/user-annotations/issue-57280.rs