Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8c6c0f8

Browse files
committedMar 4, 2017
Auto merge of #40163 - arielb1:normalization-1702, r=nikomatsakis
More through normalization, Feb/Mar 2017 edition Fix a few normalization bugs. Fixes #27901. Fixes #28828. Fixes #38135. Fixes #39363. Fixes #39367.
2 parents 5208090 + 4aede75 commit 8c6c0f8

File tree

22 files changed

+235
-136
lines changed

22 files changed

+235
-136
lines changed
 

‎src/librustc/mir/mod.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -816,12 +816,20 @@ pub enum Lvalue<'tcx> {
816816
Local(Local),
817817

818818
/// static or static mut variable
819-
Static(DefId),
819+
Static(Box<Static<'tcx>>),
820820

821821
/// projection out of an lvalue (access a field, deref a pointer, etc)
822822
Projection(Box<LvalueProjection<'tcx>>),
823823
}
824824

825+
/// The def-id of a static, along with its normalized type (which is
826+
/// stored to avoid requiring normalization when reading MIR).
827+
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
828+
pub struct Static<'tcx> {
829+
pub def_id: DefId,
830+
pub ty: Ty<'tcx>,
831+
}
832+
825833
/// The `Projection` data structure defines things of the form `B.x`
826834
/// or `*B` or `B[index]`. Note that it is parameterized because it is
827835
/// shared between `Constant` and `Lvalue`. See the aliases
@@ -911,8 +919,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {
911919

912920
match *self {
913921
Local(id) => write!(fmt, "{:?}", id),
914-
Static(def_id) =>
915-
write!(fmt, "{}", ty::tls::with(|tcx| tcx.item_path_str(def_id))),
922+
Static(box self::Static { def_id, ty }) =>
923+
write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.item_path_str(def_id)), ty),
916924
Projection(ref data) =>
917925
match data.elem {
918926
ProjectionElem::Downcast(ref adt_def, index) =>

‎src/librustc/mir/tcx.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ impl<'tcx> Lvalue<'tcx> {
125125
match *self {
126126
Lvalue::Local(index) =>
127127
LvalueTy::Ty { ty: mir.local_decls[index].ty },
128-
Lvalue::Static(def_id) =>
129-
LvalueTy::Ty { ty: tcx.item_type(def_id) },
128+
Lvalue::Static(ref data) =>
129+
LvalueTy::Ty { ty: data.ty },
130130
Lvalue::Projection(ref proj) =>
131131
proj.base.ty(mir, tcx).projection_ty(tcx, &proj.elem),
132132
}

‎src/librustc/mir/visit.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ macro_rules! make_mir_visitor {
154154
self.super_lvalue(lvalue, context, location);
155155
}
156156

157+
fn visit_static(&mut self,
158+
static_: & $($mutability)* Static<'tcx>,
159+
context: LvalueContext<'tcx>,
160+
location: Location) {
161+
self.super_static(static_, context, location);
162+
}
163+
157164
fn visit_projection(&mut self,
158165
lvalue: & $($mutability)* LvalueProjection<'tcx>,
159166
context: LvalueContext<'tcx>,
@@ -554,15 +561,27 @@ macro_rules! make_mir_visitor {
554561
match *lvalue {
555562
Lvalue::Local(_) => {
556563
}
557-
Lvalue::Static(ref $($mutability)* def_id) => {
558-
self.visit_def_id(def_id, location);
564+
Lvalue::Static(ref $($mutability)* static_) => {
565+
self.visit_static(static_, context, location);
559566
}
560567
Lvalue::Projection(ref $($mutability)* proj) => {
561568
self.visit_projection(proj, context, location);
562569
}
563570
}
564571
}
565572

573+
fn super_static(&mut self,
574+
static_: & $($mutability)* Static<'tcx>,
575+
_context: LvalueContext<'tcx>,
576+
location: Location) {
577+
let Static {
578+
ref $($mutability)* def_id,
579+
ref $($mutability)* ty,
580+
} = *static_;
581+
self.visit_def_id(def_id, location);
582+
self.visit_ty(ty);
583+
}
584+
566585
fn super_projection(&mut self,
567586
proj: & $($mutability)* LvalueProjection<'tcx>,
568587
context: LvalueContext<'tcx>,
@@ -818,4 +837,3 @@ impl<'tcx> LvalueContext<'tcx> {
818837
self.is_mutating_use() || self.is_nonmutating_use()
819838
}
820839
}
821-

‎src/librustc_mir/build/expr/as_lvalue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
8686
block.and(Lvalue::Local(index))
8787
}
8888
ExprKind::StaticRef { id } => {
89-
block.and(Lvalue::Static(id))
89+
block.and(Lvalue::Static(Box::new(Static { def_id: id, ty: expr.ty })))
9090
}
9191

9292
ExprKind::Array { .. } |

‎src/librustc_mir/transform/type_check.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,21 @@ use syntax_pos::{Span, DUMMY_SP};
2525

2626
use rustc_data_structures::indexed_vec::Idx;
2727

28+
fn mirbug(tcx: TyCtxt, span: Span, msg: &str) {
29+
tcx.sess.diagnostic().span_bug(span, msg);
30+
}
31+
2832
macro_rules! span_mirbug {
2933
($context:expr, $elem:expr, $($message:tt)*) => ({
30-
$context.tcx().sess.span_warn(
31-
$context.last_span,
32-
&format!("broken MIR ({:?}): {}", $elem, format!($($message)*))
33-
)
34+
mirbug($context.tcx(), $context.last_span,
35+
&format!("broken MIR ({:?}): {}", $elem, format!($($message)*)))
3436
})
3537
}
3638

3739
macro_rules! span_mirbug_and_err {
3840
($context:expr, $elem:expr, $($message:tt)*) => ({
3941
{
40-
$context.tcx().sess.span_warn(
41-
$context.last_span,
42-
&format!("broken MIR ({:?}): {:?}", $elem, format!($($message)*))
43-
);
42+
span_mirbug!($context, $elem, $($message)*);
4443
$context.error()
4544
}
4645
})
@@ -125,8 +124,18 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
125124
debug!("sanitize_lvalue: {:?}", lvalue);
126125
match *lvalue {
127126
Lvalue::Local(index) => LvalueTy::Ty { ty: self.mir.local_decls[index].ty },
128-
Lvalue::Static(def_id) =>
129-
LvalueTy::Ty { ty: self.tcx().item_type(def_id) },
127+
Lvalue::Static(box Static { def_id, ty: sty }) => {
128+
let sty = self.sanitize_type(lvalue, sty);
129+
let ty = self.tcx().item_type(def_id);
130+
let ty = self.cx.normalize(&ty);
131+
if let Err(terr) = self.cx.eq_types(self.last_span, ty, sty) {
132+
span_mirbug!(
133+
self, lvalue, "bad static type ({:?}: {:?}): {:?}",
134+
ty, sty, terr);
135+
}
136+
LvalueTy::Ty { ty: sty }
137+
138+
},
130139
Lvalue::Projection(ref proj) => {
131140
let base_ty = self.sanitize_lvalue(&proj.base, location);
132141
if let LvalueTy::Ty { ty } = base_ty {

‎src/librustc_trans/base.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -596,10 +596,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
596596
// release builds.
597597
info!("trans_instance({})", instance);
598598

599-
let fn_ty = ccx.tcx().item_type(instance.def);
600-
let fn_ty = ccx.tcx().erase_regions(&fn_ty);
601-
let fn_ty = monomorphize::apply_param_substs(ccx.shared(), instance.substs, &fn_ty);
602-
599+
let fn_ty = common::def_ty(ccx.shared(), instance.def, instance.substs);
603600
let sig = common::ty_fn_sig(ccx, fn_ty);
604601
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig);
605602

@@ -626,9 +623,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
626623
attributes::inline(llfn, attributes::InlineAttr::Hint);
627624
attributes::set_frame_pointer_elimination(ccx, llfn);
628625

629-
let ctor_ty = ccx.tcx().item_type(def_id);
630-
let ctor_ty = monomorphize::apply_param_substs(ccx.shared(), substs, &ctor_ty);
631-
626+
let ctor_ty = common::def_ty(ccx.shared(), def_id, substs);
632627
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&ctor_ty.fn_sig());
633628
let fn_ty = FnType::new(ccx, sig, &[]);
634629

‎src/librustc_trans/callee.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ use abi::{Abi, FnType};
2424
use attributes;
2525
use base;
2626
use builder::Builder;
27-
use common::{self, CrateContext, SharedCrateContext};
27+
use common::{self, CrateContext};
2828
use cleanup::CleanupScope;
2929
use mir::lvalue::LvalueRef;
3030
use consts;
31+
use common::def_ty;
3132
use declare;
3233
use value::Value;
3334
use meth;
34-
use monomorphize::{self, Instance};
35+
use monomorphize::Instance;
3536
use trans_item::TransItem;
3637
use type_of;
3738
use Disr;
@@ -207,16 +208,6 @@ impl<'tcx> Callee<'tcx> {
207208
}
208209
}
209210

210-
/// Given a DefId and some Substs, produces the monomorphic item type.
211-
fn def_ty<'a, 'tcx>(shared: &SharedCrateContext<'a, 'tcx>,
212-
def_id: DefId,
213-
substs: &'tcx Substs<'tcx>)
214-
-> Ty<'tcx> {
215-
let ty = shared.tcx().item_type(def_id);
216-
monomorphize::apply_param_substs(shared, substs, &ty)
217-
}
218-
219-
220211
fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
221212
def_id: DefId,
222213
substs: ty::ClosureSubsts<'tcx>,
@@ -544,8 +535,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
544535

545536
let substs = tcx.normalize_associated_type(&substs);
546537
let instance = Instance::new(def_id, substs);
547-
let item_ty = ccx.tcx().item_type(def_id);
548-
let fn_ty = monomorphize::apply_param_substs(ccx.shared(), substs, &item_ty);
538+
let fn_ty = common::def_ty(ccx.shared(), def_id, substs);
549539

550540
if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
551541
return (llfn, fn_ty);

‎src/librustc_trans/collector.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ use syntax_pos::DUMMY_SP;
207207
use base::custom_coerce_unsize_info;
208208
use callee::needs_fn_once_adapter_shim;
209209
use context::SharedCrateContext;
210-
use common::fulfill_obligation;
210+
use common::{def_ty, fulfill_obligation};
211211
use glue::{self, DropGlueKind};
212212
use monomorphize::{self, Instance};
213213
use util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
@@ -341,7 +341,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
341341
// Sanity check whether this ended up being collected accidentally
342342
debug_assert!(should_trans_locally(scx.tcx(), def_id));
343343

344-
let ty = scx.tcx().item_type(def_id);
344+
let ty = def_ty(scx, def_id, Substs::empty());
345345
let ty = glue::get_drop_glue_type(scx, ty);
346346
neighbors.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
347347

@@ -815,10 +815,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
815815
}
816816
ty::TyAdt(def, substs) => {
817817
for field in def.all_fields() {
818-
let field_type = scx.tcx().item_type(field.did);
819-
let field_type = monomorphize::apply_param_substs(scx,
820-
substs,
821-
&field_type);
818+
let field_type = def_ty(scx, field.did, substs);
822819
let field_type = glue::get_drop_glue_type(scx, field_type);
823820

824821
if scx.type_needs_drop(field_type) {
@@ -1184,7 +1181,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
11841181
debug!("RootCollector: ADT drop-glue for {}",
11851182
def_id_to_string(self.scx.tcx(), def_id));
11861183

1187-
let ty = self.scx.tcx().item_type(def_id);
1184+
let ty = def_ty(self.scx, def_id, Substs::empty());
11881185
let ty = glue::get_drop_glue_type(self.scx, ty);
11891186
self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
11901187
}

‎src/librustc_trans/common.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use type_::Type;
2929
use value::Value;
3030
use rustc::ty::{self, Ty, TyCtxt};
3131
use rustc::ty::layout::Layout;
32-
use rustc::ty::subst::Subst;
32+
use rustc::ty::subst::{Subst, Substs};
3333
use rustc::traits::{self, SelectionContext, Reveal};
3434
use rustc::hir;
3535

@@ -604,3 +604,13 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
604604
pub fn is_closure(tcx: TyCtxt, def_id: DefId) -> bool {
605605
tcx.def_key(def_id).disambiguated_data.data == DefPathData::ClosureExpr
606606
}
607+
608+
/// Given a DefId and some Substs, produces the monomorphic item type.
609+
pub fn def_ty<'a, 'tcx>(shared: &SharedCrateContext<'a, 'tcx>,
610+
def_id: DefId,
611+
substs: &'tcx Substs<'tcx>)
612+
-> Ty<'tcx>
613+
{
614+
let ty = shared.tcx().item_type(def_id);
615+
monomorphize::apply_param_substs(shared, substs, &ty)
616+
}

‎src/librustc_trans/consts.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ use rustc::hir::map as hir_map;
1818
use {debuginfo, machine};
1919
use base;
2020
use trans_item::TransItem;
21-
use common::{CrateContext, val_ty};
21+
use common::{self, CrateContext, val_ty};
2222
use declare;
23-
use monomorphize::{Instance};
23+
use monomorphize::Instance;
2424
use type_::Type;
2525
use type_of;
2626
use rustc::ty;
27+
use rustc::ty::subst::Substs;
2728

2829
use rustc::hir;
2930

@@ -84,7 +85,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
8485
return g;
8586
}
8687

87-
let ty = ccx.tcx().item_type(def_id);
88+
let ty = common::def_ty(ccx.shared(), def_id, Substs::empty());
8889
let g = if let Some(id) = ccx.tcx().hir.as_local_node_id(def_id) {
8990

9091
let llty = type_of::type_of(ccx, ty);
@@ -234,7 +235,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
234235
v
235236
};
236237

237-
let ty = ccx.tcx().item_type(def_id);
238+
let ty = common::def_ty(ccx.shared(), def_id, Substs::empty());
238239
let llty = type_of::type_of(ccx, ty);
239240
let g = if val_llty == llty {
240241
g

‎src/librustc_trans/debuginfo/metadata.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc::ty::util::TypeIdHasher;
3333
use rustc::hir;
3434
use rustc_data_structures::ToHex;
3535
use {type_of, machine, monomorphize};
36-
use common::CrateContext;
36+
use common::{self, CrateContext};
3737
use type_::Type;
3838
use rustc::ty::{self, AdtKind, Ty, layout};
3939
use session::config;
@@ -377,7 +377,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
377377
span: Span)
378378
-> MetadataCreationResult
379379
{
380-
let signature = cx.tcx().erase_late_bound_regions(&signature);
380+
let signature = cx.tcx().erase_late_bound_regions_and_normalize(&signature);
381381

382382
let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs().len() + 1);
383383

@@ -1764,16 +1764,15 @@ pub fn create_global_var_metadata(cx: &CrateContext,
17641764
};
17651765

17661766
let is_local_to_unit = is_node_local_to_unit(cx, node_id);
1767-
let variable_type = tcx.erase_regions(&tcx.item_type(node_def_id));
1767+
let variable_type = common::def_ty(cx.shared(), node_def_id, Substs::empty());
17681768
let type_metadata = type_metadata(cx, variable_type, span);
17691769
let var_name = tcx.item_name(node_def_id).to_string();
17701770
let linkage_name = mangled_name_of_item(cx, node_def_id, "");
17711771

17721772
let var_name = CString::new(var_name).unwrap();
17731773
let linkage_name = CString::new(linkage_name).unwrap();
17741774

1775-
let ty = cx.tcx().item_type(node_def_id);
1776-
let global_align = type_of::align_of(cx, ty);
1775+
let global_align = type_of::align_of(cx, variable_type);
17771776

17781777
unsafe {
17791778
llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),

‎src/librustc_trans/debuginfo/mod.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ use rustc::hir::def_id::DefId;
2727
use rustc::ty::subst::Substs;
2828

2929
use abi::Abi;
30-
use common::CrateContext;
30+
use common::{self, CrateContext};
3131
use builder::Builder;
32-
use monomorphize::{self, Instance};
32+
use monomorphize::Instance;
3333
use rustc::ty::{self, Ty};
3434
use rustc::mir;
3535
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
@@ -397,11 +397,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
397397
let self_type = cx.tcx().impl_of_method(instance.def).and_then(|impl_def_id| {
398398
// If the method does *not* belong to a trait, proceed
399399
if cx.tcx().trait_id_of_impl(impl_def_id).is_none() {
400-
let impl_self_ty = cx.tcx().item_type(impl_def_id);
401-
let impl_self_ty = cx.tcx().erase_regions(&impl_self_ty);
402-
let impl_self_ty = monomorphize::apply_param_substs(cx.shared(),
403-
instance.substs,
404-
&impl_self_ty);
400+
let impl_self_ty =
401+
common::def_ty(cx.shared(), impl_def_id, instance.substs);
405402

406403
// Only "class" methods are generally understood by LLVM,
407404
// so avoid methods on other types (e.g. `<*mut T>::null`).

‎src/librustc_trans/mir/constant.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,11 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
382382

383383
let lvalue = match *lvalue {
384384
mir::Lvalue::Local(_) => bug!(), // handled above
385-
mir::Lvalue::Static(def_id) => {
385+
mir::Lvalue::Static(box mir::Static { def_id, ty }) => {
386386
ConstLvalue {
387387
base: Base::Static(consts::get_static(self.ccx, def_id)),
388388
llextra: ptr::null_mut(),
389-
ty: lvalue.ty(self.mir, tcx).to_ty(tcx)
389+
ty: self.monomorphize(&ty),
390390
}
391391
}
392392
mir::Lvalue::Projection(ref projection) => {

‎src/librustc_trans/mir/lvalue.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,9 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
304304

305305
let result = match *lvalue {
306306
mir::Lvalue::Local(_) => bug!(), // handled above
307-
mir::Lvalue::Static(def_id) => {
308-
let const_ty = self.monomorphized_lvalue_ty(lvalue);
307+
mir::Lvalue::Static(box mir::Static { def_id, ty }) => {
309308
LvalueRef::new_sized(consts::get_static(ccx, def_id),
310-
LvalueTy::from_ty(const_ty),
309+
LvalueTy::from_ty(self.monomorphize(&ty)),
311310
Alignment::AbiAligned)
312311
},
313312
mir::Lvalue::Projection(box mir::Projection {

‎src/librustc_trans/partitioning.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@
103103
//! inlining, even when they are not marked #[inline].
104104
105105
use collector::InliningMap;
106+
use common;
106107
use context::SharedCrateContext;
107108
use llvm;
108-
use monomorphize;
109109
use rustc::dep_graph::{DepNode, WorkProductId};
110110
use rustc::hir::def_id::DefId;
111111
use rustc::hir::map::DefPathData;
@@ -468,12 +468,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 't
468468
if let Some(impl_def_id) = tcx.impl_of_method(instance.def) {
469469
// This is a method within an inherent impl, find out what the
470470
// self-type is:
471-
let impl_self_ty = tcx.item_type(impl_def_id);
472-
let impl_self_ty = tcx.erase_regions(&impl_self_ty);
473-
let impl_self_ty = monomorphize::apply_param_substs(scx,
474-
instance.substs,
475-
&impl_self_ty);
476-
471+
let impl_self_ty = common::def_ty(scx, impl_def_id, instance.substs);
477472
if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) {
478473
return Some(def_id);
479474
}

‎src/librustc_trans/trans_item.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use common;
2222
use declare;
2323
use glue::DropGlueKind;
2424
use llvm;
25-
use monomorphize::{self, Instance};
25+
use monomorphize::Instance;
2626
use rustc::dep_graph::DepNode;
2727
use rustc::hir;
2828
use rustc::hir::def_id::DefId;
@@ -146,7 +146,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
146146
linkage: llvm::Linkage,
147147
symbol_name: &str) {
148148
let def_id = ccx.tcx().hir.local_def_id(node_id);
149-
let ty = ccx.tcx().item_type(def_id);
149+
let ty = common::def_ty(ccx.shared(), def_id, Substs::empty());
150150
let llty = type_of::type_of(ccx, ty);
151151

152152
let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| {
@@ -168,10 +168,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
168168
assert!(!instance.substs.needs_infer() &&
169169
!instance.substs.has_param_types());
170170

171-
let item_ty = ccx.tcx().item_type(instance.def);
172-
let item_ty = ccx.tcx().erase_regions(&item_ty);
173-
let mono_ty = monomorphize::apply_param_substs(ccx.shared(), instance.substs, &item_ty);
174-
171+
let mono_ty = common::def_ty(ccx.shared(), instance.def, instance.substs);
175172
let attrs = ccx.tcx().get_attrs(instance.def);
176173
let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
177174
unsafe { llvm::LLVMRustSetLinkage(lldecl, linkage) };

‎src/librustc_typeck/astconv.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,8 @@ pub trait AstConv<'gcx, 'tcx> {
7979
item_name: ast::Name)
8080
-> Ty<'tcx>;
8181

82-
/// Project an associated type from a non-higher-ranked trait reference.
83-
/// This is fairly straightforward and can be accommodated in any context.
84-
fn projected_ty(&self,
85-
span: Span,
86-
_trait_ref: ty::TraitRef<'tcx>,
87-
_item_name: ast::Name)
88-
-> Ty<'tcx>;
82+
/// Normalize an associated type coming from the user.
83+
fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
8984

9085
/// Invoked when we encounter an error from some prior pass
9186
/// (e.g. resolve) that is translated into a ty-error. This is
@@ -310,8 +305,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
310305
tcx.types.err
311306
} else {
312307
// This is a default type parameter.
313-
ty::queries::ty::get(tcx, span, def.def_id)
314-
.subst_spanned(tcx, substs, Some(span))
308+
self.normalize_ty(
309+
span,
310+
ty::queries::ty::get(tcx, span, def.def_id)
311+
.subst_spanned(tcx, substs, Some(span))
312+
)
315313
}
316314
} else {
317315
// We've already errored above about the mismatch.
@@ -600,7 +598,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
600598
-> Ty<'tcx>
601599
{
602600
let substs = self.ast_path_substs_for_ty(span, did, item_segment);
603-
ty::queries::ty::get(self.tcx(), span, did).subst(self.tcx(), substs)
601+
self.normalize_ty(
602+
span,
603+
ty::queries::ty::get(self.tcx(), span, did).subst(self.tcx(), substs)
604+
)
604605
}
605606

606607
/// Transform a PolyTraitRef into a PolyExistentialTraitRef by
@@ -900,6 +901,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
900901

901902
let trait_did = bound.0.def_id;
902903
let ty = self.projected_ty_from_poly_trait_ref(span, bound, assoc_name);
904+
let ty = self.normalize_ty(span, ty);
903905

904906
let item = tcx.associated_items(trait_did).find(|i| i.name == assoc_name);
905907
let def_id = item.expect("missing associated type").def_id;
@@ -939,7 +941,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
939941

940942
debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
941943

942-
self.projected_ty(span, trait_ref, item_segment.name)
944+
self.normalize_ty(span, tcx.mk_projection(trait_ref, item_segment.name))
943945
}
944946

945947
pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {

‎src/librustc_typeck/check/mod.rs

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,9 @@ fn typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
665665

666666
check_fn(&inh, fn_sig, decl, id, body)
667667
} else {
668-
let expected_type = tcx.item_type(def_id);
669668
let fcx = FnCtxt::new(&inh, None, body.value.id);
669+
let expected_type = tcx.item_type(def_id);
670+
let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
670671
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
671672

672673
// Gather locals in statics (because of block expressions).
@@ -1374,16 +1375,15 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
13741375
infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
13751376
&poly_trait_ref);
13761377

1377-
self.normalize_associated_type(span, trait_ref, item_name)
1378+
self.tcx().mk_projection(trait_ref, item_name)
13781379
}
13791380

1380-
fn projected_ty(&self,
1381-
span: Span,
1382-
trait_ref: ty::TraitRef<'tcx>,
1383-
item_name: ast::Name)
1384-
-> Ty<'tcx>
1385-
{
1386-
self.normalize_associated_type(span, trait_ref, item_name)
1381+
fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1382+
if ty.has_escaping_regions() {
1383+
ty // FIXME: normalization and escaping regions
1384+
} else {
1385+
self.normalize_associated_types_in(span, &ty)
1386+
}
13871387
}
13881388

13891389
fn set_tainted_by_errors(&self) {
@@ -1660,25 +1660,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
16601660
self.inh.normalize_associated_types_in(span, self.body_id, value)
16611661
}
16621662

1663-
fn normalize_associated_type(&self,
1664-
span: Span,
1665-
trait_ref: ty::TraitRef<'tcx>,
1666-
item_name: ast::Name)
1667-
-> Ty<'tcx>
1668-
{
1669-
let cause = traits::ObligationCause::new(span,
1670-
self.body_id,
1671-
traits::ObligationCauseCode::MiscObligation);
1672-
self.fulfillment_cx
1673-
.borrow_mut()
1674-
.normalize_projection_type(self,
1675-
ty::ProjectionTy {
1676-
trait_ref: trait_ref,
1677-
item_name: item_name,
1678-
},
1679-
cause)
1680-
}
1681-
16821663
pub fn write_nil(&self, node_id: ast::NodeId) {
16831664
self.write_ty(node_id, self.tcx.mk_nil());
16841665
}
@@ -1709,9 +1690,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
17091690
}
17101691

17111692
pub fn register_bound(&self,
1712-
ty: Ty<'tcx>,
1713-
def_id: DefId,
1714-
cause: traits::ObligationCause<'tcx>)
1693+
ty: Ty<'tcx>,
1694+
def_id: DefId,
1695+
cause: traits::ObligationCause<'tcx>)
17151696
{
17161697
self.fulfillment_cx.borrow_mut()
17171698
.register_bound(self, ty, def_id, cause);
@@ -1720,8 +1701,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
17201701
pub fn register_predicate(&self,
17211702
obligation: traits::PredicateObligation<'tcx>)
17221703
{
1723-
debug!("register_predicate({:?})",
1724-
obligation);
1704+
debug!("register_predicate({:?})", obligation);
1705+
if obligation.has_escaping_regions() {
1706+
span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
1707+
obligation);
1708+
}
17251709
self.fulfillment_cx
17261710
.borrow_mut()
17271711
.register_predicate_obligation(self, obligation);
@@ -2040,10 +2024,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
20402024
Neither => {
20412025
if let Some(default) = default_map.get(ty) {
20422026
let default = default.clone();
2027+
let default_ty = self.normalize_associated_types_in(
2028+
default.origin_span, &default.ty);
20432029
match self.eq_types(false,
20442030
&self.misc(default.origin_span),
20452031
ty,
2046-
default.ty) {
2032+
default_ty) {
20472033
Ok(ok) => self.register_infer_ok_obligations(ok),
20482034
Err(_) => conflicts.push((*ty, default)),
20492035
}
@@ -4344,7 +4330,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
43444330
} else if !infer_types && def.has_default {
43454331
// No type parameter provided, but a default exists.
43464332
let default = self.tcx.item_type(def.def_id);
4347-
default.subst_spanned(self.tcx, substs, Some(span))
4333+
self.normalize_ty(
4334+
span,
4335+
default.subst_spanned(self.tcx, substs, Some(span))
4336+
)
43484337
} else {
43494338
// No type parameters were provided, we can infer all.
43504339
// This can also be reached in some error cases:

‎src/librustc_typeck/collect.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
291291
-> Ty<'tcx>
292292
{
293293
if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) {
294-
self.projected_ty(span, trait_ref, item_name)
294+
self.tcx().mk_projection(trait_ref, item_name)
295295
} else {
296296
// no late-bound regions, we can just ignore the binder
297297
span_err!(self.tcx().sess, span, E0212,
@@ -301,13 +301,10 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
301301
}
302302
}
303303

304-
fn projected_ty(&self,
305-
_span: Span,
306-
trait_ref: ty::TraitRef<'tcx>,
307-
item_name: ast::Name)
308-
-> Ty<'tcx>
309-
{
310-
self.tcx().mk_projection(trait_ref, item_name)
304+
fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
305+
// types in item signatures are not normalized, to avoid undue
306+
// dependencies.
307+
ty
311308
}
312309

313310
fn set_tainted_by_errors(&self) {

‎src/test/run-pass/issue-27901.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait Stream { type Item; }
12+
impl<'a> Stream for &'a str { type Item = u8; }
13+
fn f<'s>(s: &'s str) -> (&'s str, <&'s str as Stream>::Item) {
14+
(s, 42)
15+
}
16+
17+
fn main() {
18+
let fx = f as for<'t> fn(&'t str) -> (&'t str, <&'t str as Stream>::Item);
19+
assert_eq!(fx("hi"), ("hi", 42));
20+
}

‎src/test/run-pass/issue-28828.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub trait Foo {
12+
type Out;
13+
}
14+
15+
impl Foo for () {
16+
type Out = bool;
17+
}
18+
19+
fn main() {
20+
type Bool = <() as Foo>::Out;
21+
22+
let x: Bool = true;
23+
assert!(x);
24+
25+
let y: Option<Bool> = None;
26+
assert_eq!(y, None);
27+
}

‎src/test/run-pass/issue-39367.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::ops::Deref;
12+
13+
struct ArenaSet<U: Deref, V=<U as Deref>::Target>(U, &'static V)
14+
where V: 'static + ?Sized;
15+
16+
static Z: [u8; 4] = [1,2,3,4];
17+
18+
fn arena() -> &'static ArenaSet<Vec<u8>> {
19+
fn __static_ref_initialize() -> ArenaSet<Vec<u8>> {
20+
ArenaSet(vec![], &Z)
21+
}
22+
unsafe {
23+
use std::sync::{Once, ONCE_INIT};
24+
fn require_sync<T: Sync>(_: &T) { }
25+
unsafe fn __stability() -> &'static ArenaSet<Vec<u8>> {
26+
use std::mem::transmute;
27+
use std::boxed::Box;
28+
static mut DATA: *const ArenaSet<Vec<u8>> = 0 as *const ArenaSet<Vec<u8>>;
29+
30+
static mut ONCE: Once = ONCE_INIT;
31+
ONCE.call_once(|| {
32+
DATA = transmute
33+
::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>>
34+
(Box::new(__static_ref_initialize()));
35+
});
36+
37+
&*DATA
38+
}
39+
let static_ref = __stability();
40+
require_sync(static_ref);
41+
static_ref
42+
}
43+
}
44+
45+
fn main() {
46+
let &ArenaSet(ref u, v) = arena();
47+
assert!(u.is_empty());
48+
assert_eq!(v, Z);
49+
}

0 commit comments

Comments
 (0)
Please sign in to comment.