Skip to content

Commit 639a3ff

Browse files
committed
add user_ty.projs support to AscribeUserType.
1 parent 82ab668 commit 639a3ff

File tree

3 files changed

+29
-10
lines changed

3 files changed

+29
-10
lines changed

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

+7-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
1212
use traits::query::Fallible;
1313
use hir::def_id::DefId;
14+
use mir::ProjectionKind;
1415
use ty::{self, ParamEnvAnd, Ty, TyCtxt};
1516
use ty::subst::UserSubsts;
1617

@@ -20,6 +21,7 @@ pub struct AscribeUserType<'tcx> {
2021
pub variance: ty::Variance,
2122
pub def_id: DefId,
2223
pub user_substs: UserSubsts<'tcx>,
24+
pub projs: &'tcx ty::List<ProjectionKind<'tcx>>,
2325
}
2426

2527
impl<'tcx> AscribeUserType<'tcx> {
@@ -28,8 +30,9 @@ impl<'tcx> AscribeUserType<'tcx> {
2830
variance: ty::Variance,
2931
def_id: DefId,
3032
user_substs: UserSubsts<'tcx>,
33+
projs: &'tcx ty::List<ProjectionKind<'tcx>>,
3134
) -> Self {
32-
AscribeUserType { mir_ty, variance, def_id, user_substs }
35+
AscribeUserType { mir_ty, variance, def_id, user_substs, projs }
3336
}
3437
}
3538

@@ -59,19 +62,19 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for AscribeUserType<'tcx>
5962

6063
BraceStructTypeFoldableImpl! {
6164
impl<'tcx> TypeFoldable<'tcx> for AscribeUserType<'tcx> {
62-
mir_ty, variance, def_id, user_substs
65+
mir_ty, variance, def_id, user_substs, projs
6366
}
6467
}
6568

6669
BraceStructLiftImpl! {
6770
impl<'a, 'tcx> Lift<'tcx> for AscribeUserType<'a> {
6871
type Lifted = AscribeUserType<'tcx>;
69-
mir_ty, variance, def_id, user_substs
72+
mir_ty, variance, def_id, user_substs, projs
7073
}
7174
}
7275

7376
impl_stable_hash_for! {
7477
struct AscribeUserType<'tcx> {
75-
mir_ty, variance, def_id, user_substs
78+
mir_ty, variance, def_id, user_substs, projs
7679
}
7780
}

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1013,12 +1013,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10131013
) = self.infcx
10141014
.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_substs);
10151015

1016-
// FIXME: add user_ty.projs support to `AscribeUserType`.
1016+
let projs = self.infcx.tcx.intern_projs(&user_ty.projs);
10171017
self.fully_perform_op(
10181018
locations,
10191019
category,
10201020
self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
1021-
a, v, def_id, user_substs,
1021+
a, v, def_id, user_substs, projs,
10221022
)),
10231023
)?;
10241024
}

src/librustc_traits/type_op.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use rustc::infer::at::ToTrace;
1212
use rustc::infer::canonical::{Canonical, QueryResponse};
1313
use rustc::infer::InferCtxt;
1414
use rustc::hir::def_id::DefId;
15+
use rustc::mir::ProjectionKind;
16+
use rustc::mir::tcx::PlaceTy;
1517
use rustc::traits::query::type_op::ascribe_user_type::AscribeUserType;
1618
use rustc::traits::query::type_op::eq::Eq;
1719
use rustc::traits::query::type_op::normalize::Normalize;
@@ -58,22 +60,23 @@ fn type_op_ascribe_user_type<'tcx>(
5860
variance,
5961
def_id,
6062
user_substs,
63+
projs,
6164
},
6265
) = key.into_parts();
6366

6467
debug!(
6568
"type_op_ascribe_user_type(\
66-
mir_ty={:?}, variance={:?}, def_id={:?}, user_substs={:?}\
69+
mir_ty={:?}, variance={:?}, def_id={:?}, user_substs={:?}, projs={:?}\
6770
)",
68-
mir_ty, variance, def_id, user_substs,
71+
mir_ty, variance, def_id, user_substs, projs,
6972
);
7073

7174
let mut cx = AscribeUserTypeCx {
7275
infcx,
7376
param_env,
7477
fulfill_cx,
7578
};
76-
cx.relate_mir_and_user_ty(mir_ty, variance, def_id, user_substs)?;
79+
cx.relate_mir_and_user_ty(mir_ty, variance, def_id, user_substs, projs)?;
7780

7881
Ok(())
7982
})
@@ -134,17 +137,30 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> {
134137
variance: Variance,
135138
def_id: DefId,
136139
user_substs: UserSubsts<'tcx>,
140+
projs: &[ProjectionKind<'tcx>],
137141
) -> Result<(), NoSolution> {
138142
let UserSubsts {
139143
substs,
140144
user_self_ty,
141145
} = user_substs;
142146

143-
let ty = self.tcx().type_of(def_id);
147+
let tcx = self.tcx();
148+
149+
let ty = tcx.type_of(def_id);
144150
let ty = self.subst(ty, substs);
145151
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
146152
let ty = self.normalize(ty);
147153

154+
let mut projected_ty = PlaceTy::from_ty(ty);
155+
for proj in projs {
156+
projected_ty = projected_ty.projection_ty_core(
157+
tcx, proj, |this, field, &()| {
158+
let ty = this.field_ty(tcx, field);
159+
self.normalize(ty)
160+
});
161+
}
162+
let ty = projected_ty.to_ty(tcx);
163+
148164
self.relate(mir_ty, variance, ty)?;
149165

150166
if let Some(UserSelfTy {

0 commit comments

Comments
 (0)