diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 8111409b8bc0e..eaa68bf1b38dd 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1007,10 +1007,11 @@ fn write_user_type_annotations( for (index, annotation) in body.user_type_annotations.iter_enumerated() { writeln!( w, - "| {:?}: {:?} at {}", + "| {:?}: user_ty: {:?}, span: {}, inferred_ty: {:?}", index.index(), annotation.user_ty, - tcx.sess.source_map().span_to_embeddable_string(annotation.span) + tcx.sess.source_map().span_to_embeddable_string(annotation.span), + annotation.inferred_ty, )?; } if !body.user_type_annotations.is_empty() { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 26e070af76406..b99e7573000c9 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -18,15 +18,11 @@ use rustc_index::vec::IndexVec; use rustc_middle::infer::canonical::Canonical; use rustc_middle::middle::region; use rustc_middle::mir::interpret::AllocId; -use rustc_middle::mir::{ - self, BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp, UserTypeProjection, -}; +use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp}; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::subst::SubstsRef; +use rustc_middle::ty::CanonicalUserTypeAnnotation; use rustc_middle::ty::{self, AdtDef, Ty, UpvarSubsts, UserType}; -use rustc_middle::ty::{ - CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, -}; use rustc_span::{Span, Symbol, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_target::asm::InlineAsmRegOrRegClass; @@ -540,13 +536,13 @@ pub enum BindingMode { ByRef(BorrowKind), } -#[derive(Clone, Debug, PartialEq, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct FieldPat<'tcx> { pub field: Field, pub pattern: Pat<'tcx>, } -#[derive(Clone, Debug, PartialEq, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Pat<'tcx> { pub ty: Ty<'tcx>, pub span: Span, @@ -559,37 +555,10 @@ impl<'tcx> Pat<'tcx> { } } -#[derive(Copy, Clone, Debug, PartialEq, HashStable)] -pub struct PatTyProj<'tcx> { - pub user_ty: CanonicalUserType<'tcx>, -} - -impl<'tcx> PatTyProj<'tcx> { - pub fn from_user_type(user_annotation: CanonicalUserType<'tcx>) -> Self { - Self { user_ty: user_annotation } - } - - pub fn user_ty( - self, - annotations: &mut CanonicalUserTypeAnnotations<'tcx>, - inferred_ty: Ty<'tcx>, - span: Span, - ) -> UserTypeProjection { - UserTypeProjection { - base: annotations.push(CanonicalUserTypeAnnotation { - span, - user_ty: self.user_ty, - inferred_ty, - }), - projs: Vec::new(), - } - } -} - -#[derive(Copy, Clone, Debug, PartialEq, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Ascription<'tcx> { - pub user_ty: PatTyProj<'tcx>, - /// Variance to use when relating the type `user_ty` to the **type of the value being + pub annotation: CanonicalUserTypeAnnotation<'tcx>, + /// Variance to use when relating the `user_ty` to the **type of the value being /// matched**. Typically, this is `Variance::Covariant`, since the value being matched must /// have a type that is some subtype of the ascribed type. /// @@ -608,12 +577,11 @@ pub struct Ascription<'tcx> { /// probably be checking for a `PartialEq` impl instead, but this preserves the behavior /// of the old type-check for now. See #57280 for details. pub variance: ty::Variance, - pub user_ty_span: Span, } -#[derive(Clone, Debug, PartialEq, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum PatKind<'tcx> { - /// A wildward pattern: `_`. + /// A wildcard pattern: `_`. Wild, AscribeUserType { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 83ecd185b3c60..fbe08dd6f0ebc 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -523,8 +523,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }, .. }, - ascription: - thir::Ascription { user_ty: pat_ascription_ty, variance: _, user_ty_span }, + ascription: thir::Ascription { annotation, variance: _ }, } => { let place = self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); @@ -535,18 +534,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cause_let = FakeReadCause::ForLet(None); self.cfg.push_fake_read(block, pattern_source_info, cause_let, place); - 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, - ); + let ty_source_info = self.source_info(annotation.span); + + let base = self.canonical_user_type_annotations.push(annotation); self.cfg.push( block, Statement { source_info: ty_source_info, kind: StatementKind::AscribeUserType( - Box::new((place, user_ty)), + Box::new((place, UserTypeProjection { base, projs: Vec::new() })), // 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 @@ -789,7 +785,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatKind::AscribeUserType { ref subpattern, - ascription: thir::Ascription { ref user_ty, user_ty_span, variance: _ }, + ascription: thir::Ascription { ref annotation, variance: _ }, } => { // This corresponds to something like // @@ -799,16 +795,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // Note that the variance doesn't apply here, as we are tracking the effect // of `user_ty` on any bindings contained with subpattern. - let annotation = CanonicalUserTypeAnnotation { - span: user_ty_span, - user_ty: user_ty.user_ty, - inferred_ty: subpattern.ty, - }; + let projection = UserTypeProjection { - base: self.canonical_user_type_annotations.push(annotation), + base: self.canonical_user_type_annotations.push(annotation.clone()), projs: Vec::new(), }; - let subpattern_user_ty = pattern_user_ty.push_projection(&projection, user_ty_span); + let subpattern_user_ty = + pattern_user_ty.push_projection(&projection, annotation.span); self.visit_primary_bindings(subpattern, subpattern_user_ty, f) } @@ -932,9 +925,8 @@ struct Binding<'tcx> { /// influence region inference. #[derive(Clone, Debug)] struct Ascription<'tcx> { - span: Span, source: Place<'tcx>, - user_ty: PatTyProj<'tcx>, + annotation: CanonicalUserTypeAnnotation<'tcx>, variance: ty::Variance, } @@ -1863,7 +1855,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { parent_bindings .iter() .flat_map(|(_, ascriptions)| ascriptions) - .chain(&candidate.ascriptions), + .cloned() + .chain(candidate.ascriptions), ); // rust-lang/rust#27282: The `autoref` business deserves some @@ -2067,32 +2060,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Append `AscribeUserType` statements onto the end of `block` /// for each ascription - fn ascribe_types<'b>( + fn ascribe_types( &mut self, block: BasicBlock, - ascriptions: impl IntoIterator>, - ) where - 'tcx: 'b, - { + ascriptions: impl IntoIterator>, + ) { for ascription in ascriptions { - let source_info = self.source_info(ascription.span); + let source_info = self.source_info(ascription.annotation.span); - debug!( - "adding user ascription at span {:?} of place {:?} and {:?}", - source_info.span, ascription.source, ascription.user_ty, - ); - - 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, - ); + let base = self.canonical_user_type_annotations.push(ascription.annotation); self.cfg.push( block, Statement { source_info, kind: StatementKind::AscribeUserType( - Box::new((ascription.source, user_ty)), + Box::new(( + ascription.source, + UserTypeProjection { base, projs: Vec::new() }, + )), ascription.variance, ), }, diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 895df5808dbe1..b4a0c965d6b73 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -152,15 +152,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match *match_pair.pattern.kind { PatKind::AscribeUserType { ref subpattern, - ascription: thir::Ascription { variance, user_ty, user_ty_span }, + ascription: thir::Ascription { ref annotation, variance }, } => { // Apply the type ascription to the value at `match_pair.place`, which is the if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results) { candidate.ascriptions.push(Ascription { - span: user_ty_span, - user_ty, + annotation: annotation.clone(), source: place_resolved.into_place(self.tcx, self.typeck_results), variance, }); diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 72ce8c24cdd5b..d0b18ce67c6d8 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -6,6 +6,7 @@ use rustc_middle::thir::*; use rustc_middle::ty; use rustc_index::vec::Idx; +use rustc_middle::ty::CanonicalUserTypeAnnotation; impl<'tcx> Cx<'tcx> { pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block { @@ -80,13 +81,17 @@ impl<'tcx> Cx<'tcx> { self.typeck_results.user_provided_types().get(ty.hir_id) { debug!("mirror_stmts: user_ty={:?}", user_ty); + let annotation = CanonicalUserTypeAnnotation { + user_ty, + span: ty.span, + inferred_ty: self.typeck_results.node_type(ty.hir_id), + }; pattern = Pat { ty: pattern.ty, span: pattern.span, kind: Box::new(PatKind::AscribeUserType { ascription: Ascription { - user_ty: PatTyProj::from_user_type(user_ty), - user_ty_span: ty.span, + annotation, variance: ty::Variance::Covariant, }, subpattern: pattern, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 1f152549a63f0..e0dec1daf63c8 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -19,8 +19,9 @@ use rustc_middle::mir::interpret::{get_slice_bytes, ConstValue}; use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput}; use rustc_middle::mir::{self, UserTypeProjection}; use rustc_middle::mir::{BorrowKind, Field, Mutability}; -use rustc_middle::thir::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange, PatTyProj}; +use rustc_middle::thir::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange}; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; +use rustc_middle::ty::CanonicalUserTypeAnnotation; use rustc_middle::ty::{self, AdtDef, ConstKind, DefIdTree, Region, Ty, TyCtxt, UserType}; use rustc_span::{Span, Symbol}; @@ -227,7 +228,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { for end in &[lo, hi] { if let Some((_, Some(ascription))) = end { let subpattern = Pat { span: pat.span, ty, kind: Box::new(kind) }; - kind = PatKind::AscribeUserType { ascription: *ascription, subpattern }; + kind = + PatKind::AscribeUserType { ascription: ascription.clone(), subpattern }; } } @@ -432,13 +434,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if let Some(user_ty) = self.user_substs_applied_to_ty_of_hir_id(hir_id) { debug!("lower_variant_or_leaf: kind={:?} user_ty={:?} span={:?}", kind, user_ty, span); + let annotation = CanonicalUserTypeAnnotation { + user_ty, + span, + inferred_ty: self.typeck_results.node_type(hir_id), + }; kind = PatKind::AscribeUserType { subpattern: Pat { span, ty, kind: Box::new(kind) }, - ascription: Ascription { - user_ty: PatTyProj::from_user_type(user_ty), - user_ty_span: span, - variance: ty::Variance::Covariant, - }, + ascription: Ascription { annotation, variance: ty::Variance::Covariant }, }; } @@ -499,18 +502,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } let user_provided_types = self.typeck_results().user_provided_types(); - if let Some(u_ty) = user_provided_types.get(id) { - let user_ty = PatTyProj::from_user_type(*u_ty); + if let Some(&user_ty) = user_provided_types.get(id) { + let annotation = CanonicalUserTypeAnnotation { + user_ty, + span, + inferred_ty: self.typeck_results().node_type(id), + }; Pat { span, kind: Box::new(PatKind::AscribeUserType { subpattern: pattern, ascription: Ascription { + annotation, /// Note that use `Contravariant` here. See the /// `variance` field documentation for details. variance: ty::Variance::Contravariant, - user_ty, - user_ty_span: span, }, }), ty: const_.ty(), @@ -645,7 +651,7 @@ impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option { } } -macro_rules! CloneImpls { +macro_rules! ClonePatternFoldableImpls { (<$lt_tcx:tt> $($ty:ty),+) => { $( impl<$lt_tcx> PatternFoldable<$lt_tcx> for $ty { @@ -657,11 +663,11 @@ macro_rules! CloneImpls { } } -CloneImpls! { <'tcx> +ClonePatternFoldableImpls! { <'tcx> Span, Field, Mutability, Symbol, hir::HirId, usize, ty::Const<'tcx>, Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>, SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>, - UserTypeProjection, PatTyProj<'tcx> + UserTypeProjection, CanonicalUserTypeAnnotation<'tcx> } impl<'tcx> PatternFoldable<'tcx> for FieldPat<'tcx> { @@ -694,14 +700,10 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { PatKind::Wild => PatKind::Wild, PatKind::AscribeUserType { ref subpattern, - ascription: Ascription { variance, ref user_ty, user_ty_span }, + ascription: Ascription { ref annotation, variance }, } => PatKind::AscribeUserType { subpattern: subpattern.fold_with(folder), - ascription: Ascription { - user_ty: user_ty.fold_with(folder), - variance, - user_ty_span, - }, + ascription: Ascription { annotation: annotation.fold_with(folder), variance }, }, PatKind::Binding { mutability, name, mode, var, ty, ref subpattern, is_primary } => { PatKind::Binding { 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..ee8e21781480c 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 @@ -1,36 +1,36 @@ // MIR for `address_of_reborrow` after SimplifyCfg-initial | User Type Annotations -| 0: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:7:5: 7:18 -| 1: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:9:5: 9:25 -| 2: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:13:12: 13:20 -| 3: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:13:12: 13:20 -| 4: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) } at $DIR/address-of.rs:14:12: 14:28 -| 5: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) } at $DIR/address-of.rs:14:12: 14:28 -| 6: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:15:12: 15:27 -| 7: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:15:12: 15:27 -| 8: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:16:12: 16:24 -| 9: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:16:12: 16:24 -| 10: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:18:5: 18:18 -| 11: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:20:5: 20:25 -| 12: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:23:12: 23:20 -| 13: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:23:12: 23:20 -| 14: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) } at $DIR/address-of.rs:24:12: 24:28 -| 15: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) } at $DIR/address-of.rs:24:12: 24:28 -| 16: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:25:12: 25:27 -| 17: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:25:12: 25:27 -| 18: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:26:12: 26:24 -| 19: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:26:12: 26:24 -| 20: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:28:5: 28:16 -| 21: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) } at $DIR/address-of.rs:30:5: 30:23 -| 22: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:33:12: 33:18 -| 23: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:33:12: 33:18 -| 24: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) } at $DIR/address-of.rs:34:12: 34:26 -| 25: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) } at $DIR/address-of.rs:34:12: 34:26 -| 26: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) } at $DIR/address-of.rs:35:12: 35:25 -| 27: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) } at $DIR/address-of.rs:35:12: 35:25 -| 28: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) } at $DIR/address-of.rs:36:12: 36:22 -| 29: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) } at $DIR/address-of.rs:36:12: 36:22 +| 0: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:7:5: 7:18, inferred_ty: *const [i32; 10] +| 1: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send +| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10] +| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10] +| 4: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10] +| 5: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10] +| 6: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send +| 7: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send +| 8: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32] +| 9: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32] +| 10: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:18:5: 18:18, inferred_ty: *const [i32; 10] +| 11: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send +| 12: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10] +| 13: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10] +| 14: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10] +| 15: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10] +| 16: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send +| 17: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send +| 18: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32] +| 19: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32] +| 20: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10] +| 21: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send +| 22: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10] +| 23: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10] +| 24: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10] +| 25: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10] +| 26: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send +| 27: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send +| 28: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32] +| 29: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32] | fn address_of_reborrow() -> () { let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:3:26: 3:26 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..a63a94b2ab599 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 @@ -1,8 +1,8 @@ // MIR for `main` after SimplifyCfg-initial | User Type Annotations -| 0: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option>) } at $DIR/basic_assignment.rs:18:17: 18:33 -| 1: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option>) } at $DIR/basic_assignment.rs:18:17: 18:33 +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option> +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option> | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/basic_assignment.rs:10:11: 10:11 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 4aff444515809..7e966b21bedd7 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 @@ -1,8 +1,8 @@ // MIR for `main` 0 mir_map | User Type Annotations -| 0: Canonical { max_universe: U0, variables: [], value: Ty(Void) } at $DIR/issue-72181-1.rs:16:12: 16:16 -| 1: Canonical { max_universe: U0, variables: [], value: Ty(Void) } at $DIR/issue-72181-1.rs:16:12: 16:16 +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/issue-72181-1.rs:15:11: 15:11 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 945290b6a82e0..5bf8655fcecdc 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 @@ -1,10 +1,10 @@ // MIR for `main` 0 mir_map | User Type Annotations -| 0: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) } at $DIR/receiver-ptr-mutability.rs:14:14: 14:23 -| 1: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) } at $DIR/receiver-ptr-mutability.rs:14:14: 14:23 -| 2: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) } at $DIR/receiver-ptr-mutability.rs:18:18: 18:31 -| 3: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) } at $DIR/receiver-ptr-mutability.rs:18:18: 18:31 +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test +| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test +| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/receiver-ptr-mutability.rs:13:11: 13:11 diff --git a/src/test/ui/hr-subtype/placeholder-pattern-fail.nll.stderr b/src/test/ui/hr-subtype/placeholder-pattern-fail.nll.stderr new file mode 100644 index 0000000000000..1836249efdb2a --- /dev/null +++ b/src/test/ui/hr-subtype/placeholder-pattern-fail.nll.stderr @@ -0,0 +1,37 @@ +error[E0308]: mismatched types + --> $DIR/placeholder-pattern-fail.rs:9:12 + | +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:9:12 + | +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: lifetime may not live long enough + --> $DIR/placeholder-pattern-fail.rs:14:13 + | +LL | fn simple1<'c>(x: (&'c i32,)) { + | -- lifetime `'c` defined here +LL | let _x: (&'static i32,) = x; + | ^^^^^^^^^^^^^^^ type annotation requires that `'c` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/placeholder-pattern-fail.rs:19:12 + | +LL | fn simple2<'c>(x: (&'c i32,)) { + | -- lifetime `'c` defined here +LL | let _: (&'static i32,) = x; + | ^^^^^^^^^^^^^^^ type annotation requires that `'c` must outlive `'static` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. 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.nll.stderr b/src/test/ui/lifetimes/re-empty-in-error.nll.stderr new file mode 100644 index 0000000000000..9becdab918675 --- /dev/null +++ b/src/test/ui/lifetimes/re-empty-in-error.nll.stderr @@ -0,0 +1,10 @@ +error: higher-ranked lifetime error + --> $DIR/re-empty-in-error.rs:8:5 + | +LL | foo(&10); + | ^^^^^^^^ + | + = note: could not prove for<'b, 'r> &'b (): 'r + +error: aborting due to previous error + 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/issue-57280-1-flipped.rs b/src/test/ui/nll/issue-57280-1-flipped.rs new file mode 100644 index 0000000000000..ad4b8dcfde432 --- /dev/null +++ b/src/test/ui/nll/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/issue-57280-1-flipped.stderr b/src/test/ui/nll/issue-57280-1-flipped.stderr new file mode 100644 index 0000000000000..7a2135a2ade83 --- /dev/null +++ b/src/test/ui/nll/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/type-alias-impl-trait/cross_inference_pattern_bug.rs b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs index 9ad7cad39d071..811832848d9dd 100644 --- a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs +++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs @@ -1,24 +1,8 @@ -// known-bug -// failure-status: 101 -// compile-flags: --edition=2021 --crate-type=lib -// rustc-env:RUST_BACKTRACE=0 - -// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked" -// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" -// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" -// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" -// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" -// normalize-stderr-test "note: compiler flags.*\n\n" -> "" -// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" -// normalize-stderr-test "#.*\n" -> "" -// normalize-stderr-test ".*delayed.*\n" -> "" - -// tracked in https://github.com/rust-lang/rust/issues/96572 - +// compile-flags: --edition=2021 #![feature(type_alias_impl_trait)] fn main() { - type T = impl Copy; + type T = impl Copy; //~ ERROR unconstrained opaque type let foo: T = (1u32, 2u32); let (a, b): (u32, u32) = foo; } diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr index 84d2705bf2453..03b172e6de570 100644 --- a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr +++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr @@ -1,32 +1,10 @@ -error: internal compiler error: no errors encountered even though `delay_span_bug` issued - -error: internal compiler error: broken MIR in DefId(0:3 ~ cross_inference_pattern_bug[646d]::main) ((_1.0: u32)): can't project out of PlaceTy { ty: main::T, variant_index: None } - --> $DIR/cross_inference_pattern_bug.rs:23:10 - | -LL | let (a, b): (u32, u32) = foo; - | ^ - | - -error: internal compiler error: TyKind::Error constructed but no error reported - | - -error: internal compiler error: TyKind::Error constructed but no error reported +error: unconstrained opaque type + --> $DIR/cross_inference_pattern_bug.rs:5:14 | - -error: internal compiler error: broken MIR in DefId(0:3 ~ cross_inference_pattern_bug[646d]::main) ((_1.1: u32)): can't project out of PlaceTy { ty: main::T, variant_index: None } - --> $DIR/cross_inference_pattern_bug.rs:23:13 - | -LL | let (a, b): (u32, u32) = foo; - | ^ - | - -error: internal compiler error: TyKind::Error constructed but no error reported - | - -error: internal compiler error: TyKind::Error constructed but no error reported +LL | type T = impl Copy; + | ^^^^^^^^^ | + = note: `T` must be used in combination with a concrete type within the same module -thread 'rustc' panicked +error: aborting due to previous error -query stack during panic: -end of query stack