Skip to content

Commit cae1647

Browse files
committed
Auto merge of #55937 - davidtwco:issue-54943, r=pnkfelix
NLL: User type annotations refactor, associated constant patterns and ref bindings. Fixes #55511 and Fixes #55401. Contributes to #54943. This PR performs a large refactoring on user type annotations, checks user type annotations for associated constants in patterns and that user type annotations for `ref` bindings are respected. r? @nikomatsakis
2 parents 36500de + c20ba65 commit cae1647

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+804
-500
lines changed

src/librustc/ich/impls_mir.rs

-17
Original file line numberDiff line numberDiff line change
@@ -494,22 +494,5 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubj
494494

495495
impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });
496496

497-
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::UserTypeAnnotation<'gcx> {
498-
fn hash_stable<W: StableHasherResult>(&self,
499-
hcx: &mut StableHashingContext<'a>,
500-
hasher: &mut StableHasher<W>) {
501-
mem::discriminant(self).hash_stable(hcx, hasher);
502-
match *self {
503-
mir::UserTypeAnnotation::Ty(ref ty) => {
504-
ty.hash_stable(hcx, hasher);
505-
}
506-
mir::UserTypeAnnotation::TypeOf(ref def_id, ref substs) => {
507-
def_id.hash_stable(hcx, hasher);
508-
substs.hash_stable(hcx, hasher);
509-
}
510-
}
511-
}
512-
}
513-
514497
impl_stable_hash_for!(struct mir::UserTypeProjection<'tcx> { base, projs });
515498
impl_stable_hash_for!(struct mir::UserTypeProjections<'tcx> { contents });

src/librustc/ich/impls_ty.rs

+26
Original file line numberDiff line numberDiff line change
@@ -1251,3 +1251,29 @@ impl_stable_hash_for!(
12511251
goal,
12521252
}
12531253
);
1254+
1255+
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::UserTypeAnnotation<'gcx> {
1256+
fn hash_stable<W: StableHasherResult>(&self,
1257+
hcx: &mut StableHashingContext<'a>,
1258+
hasher: &mut StableHasher<W>) {
1259+
mem::discriminant(self).hash_stable(hcx, hasher);
1260+
match *self {
1261+
ty::UserTypeAnnotation::Ty(ref ty) => {
1262+
ty.hash_stable(hcx, hasher);
1263+
}
1264+
ty::UserTypeAnnotation::TypeOf(ref def_id, ref substs) => {
1265+
def_id.hash_stable(hcx, hasher);
1266+
substs.hash_stable(hcx, hasher);
1267+
}
1268+
}
1269+
}
1270+
}
1271+
1272+
impl<'a> HashStable<StableHashingContext<'a>> for ty::UserTypeAnnotationIndex {
1273+
#[inline]
1274+
fn hash_stable<W: StableHasherResult>(&self,
1275+
hcx: &mut StableHashingContext<'a>,
1276+
hasher: &mut StableHasher<W>) {
1277+
self.index().hash_stable(hcx, hasher);
1278+
}
1279+
}

src/librustc/mir/mod.rs

+92-33
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ use syntax::ast::{self, Name};
2727
use syntax::symbol::InternedString;
2828
use syntax_pos::{Span, DUMMY_SP};
2929
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
30-
use ty::subst::{CanonicalUserSubsts, Subst, Substs};
31-
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt};
30+
use ty::subst::{Subst, Substs};
3231
use ty::layout::VariantIdx;
32+
use ty::{
33+
self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt,
34+
UserTypeAnnotationIndex, UserTypeAnnotation,
35+
};
3336
use util::ppaux;
3437

3538
pub use mir::interpret::AssertMessage;
@@ -121,6 +124,9 @@ pub struct Mir<'tcx> {
121124
/// variables and temporaries.
122125
pub local_decls: LocalDecls<'tcx>,
123126

127+
/// User type annotations
128+
pub user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
129+
124130
/// Number of arguments this function takes.
125131
///
126132
/// Starting at local 1, `arg_count` locals will be provided by the caller
@@ -161,7 +167,8 @@ impl<'tcx> Mir<'tcx> {
161167
source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
162168
promoted: IndexVec<Promoted, Mir<'tcx>>,
163169
yield_ty: Option<Ty<'tcx>>,
164-
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
170+
local_decls: LocalDecls<'tcx>,
171+
user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
165172
arg_count: usize,
166173
upvar_decls: Vec<UpvarDecl>,
167174
span: Span,
@@ -185,6 +192,7 @@ impl<'tcx> Mir<'tcx> {
185192
generator_drop: None,
186193
generator_layout: None,
187194
local_decls,
195+
user_type_annotations,
188196
arg_count,
189197
upvar_decls,
190198
spread_arg: None,
@@ -418,6 +426,7 @@ impl_stable_hash_for!(struct Mir<'tcx> {
418426
generator_drop,
419427
generator_layout,
420428
local_decls,
429+
user_type_annotations,
421430
arg_count,
422431
upvar_decls,
423432
spread_arg,
@@ -2232,7 +2241,7 @@ pub enum AggregateKind<'tcx> {
22322241
&'tcx AdtDef,
22332242
VariantIdx,
22342243
&'tcx Substs<'tcx>,
2235-
Option<UserTypeAnnotation<'tcx>>,
2244+
Option<UserTypeAnnotationIndex>,
22362245
Option<usize>,
22372246
),
22382247

@@ -2446,38 +2455,11 @@ pub struct Constant<'tcx> {
24462455
/// indicate that `Vec<_>` was explicitly specified.
24472456
///
24482457
/// Needed for NLL to impose user-given type constraints.
2449-
pub user_ty: Option<UserTypeAnnotation<'tcx>>,
2458+
pub user_ty: Option<UserTypeAnnotationIndex>,
24502459

24512460
pub literal: &'tcx ty::Const<'tcx>,
24522461
}
24532462

2454-
/// A user-given type annotation attached to a constant. These arise
2455-
/// from constants that are named via paths, like `Foo::<A>::new` and
2456-
/// so forth.
2457-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
2458-
pub enum UserTypeAnnotation<'tcx> {
2459-
Ty(CanonicalTy<'tcx>),
2460-
2461-
/// The canonical type is the result of `type_of(def_id)` with the
2462-
/// given substitutions applied.
2463-
TypeOf(DefId, CanonicalUserSubsts<'tcx>),
2464-
}
2465-
2466-
EnumTypeFoldableImpl! {
2467-
impl<'tcx> TypeFoldable<'tcx> for UserTypeAnnotation<'tcx> {
2468-
(UserTypeAnnotation::Ty)(ty),
2469-
(UserTypeAnnotation::TypeOf)(def, substs),
2470-
}
2471-
}
2472-
2473-
EnumLiftImpl! {
2474-
impl<'a, 'tcx> Lift<'tcx> for UserTypeAnnotation<'a> {
2475-
type Lifted = UserTypeAnnotation<'tcx>;
2476-
(UserTypeAnnotation::Ty)(ty),
2477-
(UserTypeAnnotation::TypeOf)(def, substs),
2478-
}
2479-
}
2480-
24812463
/// A collection of projections into user types.
24822464
///
24832465
/// They are projections because a binding can occur a part of a
@@ -2537,6 +2519,48 @@ impl<'tcx> UserTypeProjections<'tcx> {
25372519
pub fn projections(&self) -> impl Iterator<Item=&UserTypeProjection<'tcx>> {
25382520
self.contents.iter().map(|&(ref user_type, _span)| user_type)
25392521
}
2522+
2523+
pub fn push_projection(
2524+
mut self,
2525+
user_ty: &UserTypeProjection<'tcx>,
2526+
span: Span,
2527+
) -> Self {
2528+
self.contents.push((user_ty.clone(), span));
2529+
self
2530+
}
2531+
2532+
fn map_projections(
2533+
mut self,
2534+
mut f: impl FnMut(UserTypeProjection<'tcx>) -> UserTypeProjection<'tcx>
2535+
) -> Self {
2536+
self.contents = self.contents.drain(..).map(|(proj, span)| (f(proj), span)).collect();
2537+
self
2538+
}
2539+
2540+
pub fn index(self) -> Self {
2541+
self.map_projections(|pat_ty_proj| pat_ty_proj.index())
2542+
}
2543+
2544+
pub fn subslice(self, from: u32, to: u32) -> Self {
2545+
self.map_projections(|pat_ty_proj| pat_ty_proj.subslice(from, to))
2546+
}
2547+
2548+
pub fn deref(self) -> Self {
2549+
self.map_projections(|pat_ty_proj| pat_ty_proj.deref())
2550+
}
2551+
2552+
pub fn leaf(self, field: Field) -> Self {
2553+
self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field))
2554+
}
2555+
2556+
pub fn variant(
2557+
self,
2558+
adt_def: &'tcx AdtDef,
2559+
variant_index: VariantIdx,
2560+
field: Field,
2561+
) -> Self {
2562+
self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
2563+
}
25402564
}
25412565

25422566
/// Encodes the effect of a user-supplied type annotation on the
@@ -2556,12 +2580,45 @@ impl<'tcx> UserTypeProjections<'tcx> {
25562580
/// determined by finding the type of the `.0` field from `T`.
25572581
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
25582582
pub struct UserTypeProjection<'tcx> {
2559-
pub base: UserTypeAnnotation<'tcx>,
2583+
pub base: UserTypeAnnotationIndex,
25602584
pub projs: Vec<ProjectionElem<'tcx, (), ()>>,
25612585
}
25622586

25632587
impl<'tcx> Copy for ProjectionKind<'tcx> { }
25642588

2589+
impl<'tcx> UserTypeProjection<'tcx> {
2590+
pub(crate) fn index(mut self) -> Self {
2591+
self.projs.push(ProjectionElem::Index(()));
2592+
self
2593+
}
2594+
2595+
pub(crate) fn subslice(mut self, from: u32, to: u32) -> Self {
2596+
self.projs.push(ProjectionElem::Subslice { from, to });
2597+
self
2598+
}
2599+
2600+
pub(crate) fn deref(mut self) -> Self {
2601+
self.projs.push(ProjectionElem::Deref);
2602+
self
2603+
}
2604+
2605+
pub(crate) fn leaf(mut self, field: Field) -> Self {
2606+
self.projs.push(ProjectionElem::Field(field, ()));
2607+
self
2608+
}
2609+
2610+
pub(crate) fn variant(
2611+
mut self,
2612+
adt_def: &'tcx AdtDef,
2613+
variant_index: VariantIdx,
2614+
field: Field,
2615+
) -> Self {
2616+
self.projs.push(ProjectionElem::Downcast(adt_def, variant_index));
2617+
self.projs.push(ProjectionElem::Field(field, ()));
2618+
self
2619+
}
2620+
}
2621+
25652622
CloneTypeFoldableAndLiftImpls! { ProjectionKind<'tcx>, }
25662623

25672624
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection<'tcx> {
@@ -2970,6 +3027,7 @@ CloneTypeFoldableAndLiftImpls! {
29703027
SourceScope,
29713028
SourceScopeData,
29723029
SourceScopeLocalData,
3030+
UserTypeAnnotationIndex,
29733031
}
29743032

29753033
BraceStructTypeFoldableImpl! {
@@ -2983,6 +3041,7 @@ BraceStructTypeFoldableImpl! {
29833041
generator_drop,
29843042
generator_layout,
29853043
local_decls,
3044+
user_type_annotations,
29863045
arg_count,
29873046
upvar_decls,
29883047
spread_arg,

src/librustc/mir/visit.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use hir::def_id::DefId;
2+
use infer::canonical::Canonical;
23
use ty::subst::Substs;
34
use ty::{ClosureSubsts, GeneratorSubsts, Region, Ty};
45
use mir::*;
@@ -219,9 +220,10 @@ macro_rules! make_mir_visitor {
219220

220221
fn visit_user_type_annotation(
221222
&mut self,
222-
ty: & $($mutability)* UserTypeAnnotation<'tcx>,
223+
index: UserTypeAnnotationIndex,
224+
ty: & $($mutability)* Canonical<'tcx, UserTypeAnnotation<'tcx>>,
223225
) {
224-
self.super_user_type_annotation(ty);
226+
self.super_user_type_annotation(index, ty);
225227
}
226228

227229
fn visit_region(&mut self,
@@ -307,6 +309,14 @@ macro_rules! make_mir_visitor {
307309
self.visit_local_decl(local, & $($mutability)* mir.local_decls[local]);
308310
}
309311

312+
for index in mir.user_type_annotations.indices() {
313+
let (span, annotation) = & $($mutability)* mir.user_type_annotations[index];
314+
self.visit_user_type_annotation(
315+
index, annotation
316+
);
317+
self.visit_span(span);
318+
}
319+
310320
self.visit_span(&$($mutability)* mir.span);
311321
}
312322

@@ -865,18 +875,14 @@ macro_rules! make_mir_visitor {
865875

866876
fn super_user_type_projection(
867877
&mut self,
868-
ty: & $($mutability)* UserTypeProjection<'tcx>,
878+
_ty: & $($mutability)* UserTypeProjection<'tcx>,
869879
) {
870-
let UserTypeProjection {
871-
ref $($mutability)* base,
872-
projs: _, // Note: Does not visit projection elems!
873-
} = *ty;
874-
self.visit_user_type_annotation(base);
875880
}
876881

877882
fn super_user_type_annotation(
878883
&mut self,
879-
_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
884+
_index: UserTypeAnnotationIndex,
885+
_ty: & $($mutability)* Canonical<'tcx, UserTypeAnnotation<'tcx>>,
880886
) {
881887
}
882888

src/librustc/traits/query/type_op/ascribe_user_type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl<'tcx> AscribeUserType<'tcx> {
2222
user_substs: UserSubsts<'tcx>,
2323
projs: &'tcx ty::List<ProjectionKind<'tcx>>,
2424
) -> Self {
25-
AscribeUserType { mir_ty, variance, def_id, user_substs, projs }
25+
Self { mir_ty, variance, def_id, user_substs, projs }
2626
}
2727
}
2828

0 commit comments

Comments
 (0)