Skip to content

Commit ba70db9

Browse files
authored
Merge pull request #37239 from brson/beta-next
[beta] backports
2 parents 6d9b0bf + b477047 commit ba70db9

File tree

16 files changed

+172
-53
lines changed

16 files changed

+172
-53
lines changed

src/librustc/infer/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,8 @@ impl_trans_normalize!('gcx,
583583
ty::FnSig<'gcx>,
584584
&'gcx ty::BareFnTy<'gcx>,
585585
ty::ClosureSubsts<'gcx>,
586-
ty::PolyTraitRef<'gcx>
586+
ty::PolyTraitRef<'gcx>,
587+
ty::ExistentialTraitRef<'gcx>
587588
);
588589

589590
impl<'gcx> TransNormalize<'gcx> for LvalueTy<'gcx> {
@@ -603,6 +604,18 @@ impl<'gcx> TransNormalize<'gcx> for LvalueTy<'gcx> {
603604

604605
// NOTE: Callable from trans only!
605606
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
607+
/// Currently, higher-ranked type bounds inhibit normalization. Therefore,
608+
/// each time we erase them in translation, we need to normalize
609+
/// the contents.
610+
pub fn erase_late_bound_regions_and_normalize<T>(self, value: &ty::Binder<T>)
611+
-> T
612+
where T: TransNormalize<'tcx>
613+
{
614+
assert!(!value.needs_subst());
615+
let value = self.erase_late_bound_regions(value);
616+
self.normalize_associated_type(&value)
617+
}
618+
606619
pub fn normalize_associated_type<T>(self, value: &T) -> T
607620
where T: TransNormalize<'tcx>
608621
{

src/librustc_trans/base.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,8 +1133,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
11331133
let fn_ty = ccx.tcx().erase_regions(&fn_ty);
11341134
let fn_ty = monomorphize::apply_param_substs(ccx.shared(), instance.substs, &fn_ty);
11351135

1136-
let sig = ccx.tcx().erase_late_bound_regions(fn_ty.fn_sig());
1137-
let sig = ccx.tcx().normalize_associated_type(&sig);
1136+
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(fn_ty.fn_sig());
11381137
let abi = fn_ty.fn_abi();
11391138

11401139
let lldecl = match ccx.instances().borrow().get(&instance) {
@@ -1156,8 +1155,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
11561155
let ctor_ty = ccx.tcx().lookup_item_type(def_id).ty;
11571156
let ctor_ty = monomorphize::apply_param_substs(ccx.shared(), substs, &ctor_ty);
11581157

1159-
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
1160-
let sig = ccx.tcx().normalize_associated_type(&sig);
1158+
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&ctor_ty.fn_sig());
11611159
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
11621160

11631161
let (arena, fcx): (TypedArena<_>, FunctionContext);

src/librustc_trans/builder.rs

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use value::Value;
2222
use util::nodemap::FnvHashMap;
2323
use libc::{c_uint, c_char};
2424

25+
use std::borrow::Cow;
2526
use std::ffi::CString;
2627
use std::ptr;
2728
use syntax_pos::Span;
@@ -175,8 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
175176
.collect::<Vec<String>>()
176177
.join(", "));
177178

178-
check_call("invoke", llfn, args);
179-
179+
let args = self.check_call("invoke", llfn, args);
180180
let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut());
181181

182182
unsafe {
@@ -543,6 +543,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
543543
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
544544
assert!(!self.llbuilder.is_null());
545545
self.count_insn("store");
546+
let ptr = self.check_store(val, ptr);
546547
unsafe {
547548
llvm::LLVMBuildStore(self.llbuilder, val, ptr)
548549
}
@@ -552,6 +553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
552553
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
553554
assert!(!self.llbuilder.is_null());
554555
self.count_insn("store.volatile");
556+
let ptr = self.check_store(val, ptr);
555557
unsafe {
556558
let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
557559
llvm::LLVMSetVolatile(insn, llvm::True);
@@ -562,6 +564,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
562564
pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) {
563565
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
564566
self.count_insn("store.atomic");
567+
let ptr = self.check_store(val, ptr);
565568
unsafe {
566569
let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
567570
let align = llalign_of_pref(self.ccx, ty.element_type());
@@ -857,8 +860,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
857860
.collect::<Vec<String>>()
858861
.join(", "));
859862

860-
check_call("call", llfn, args);
861-
863+
let args = self.check_call("call", llfn, args);
862864
let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut());
863865

864866
unsafe {
@@ -1100,10 +1102,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11001102
llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope);
11011103
}
11021104
}
1103-
}
11041105

1105-
fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) {
1106-
if cfg!(debug_assertions) {
1106+
/// Returns the ptr value that should be used for storing `val`.
1107+
fn check_store<'b>(&self,
1108+
val: ValueRef,
1109+
ptr: ValueRef) -> ValueRef {
1110+
let dest_ptr_ty = val_ty(ptr);
1111+
let stored_ty = val_ty(val);
1112+
let stored_ptr_ty = stored_ty.ptr_to();
1113+
1114+
assert_eq!(dest_ptr_ty.kind(), llvm::TypeKind::Pointer);
1115+
1116+
if dest_ptr_ty == stored_ptr_ty {
1117+
ptr
1118+
} else {
1119+
debug!("Type mismatch in store. \
1120+
Expected {:?}, got {:?}; inserting bitcast",
1121+
dest_ptr_ty, stored_ptr_ty);
1122+
self.bitcast(ptr, stored_ptr_ty)
1123+
}
1124+
}
1125+
1126+
/// Returns the args that should be used for a call to `llfn`.
1127+
fn check_call<'b>(&self,
1128+
typ: &str,
1129+
llfn: ValueRef,
1130+
args: &'b [ValueRef]) -> Cow<'b, [ValueRef]> {
11071131
let mut fn_ty = val_ty(llfn);
11081132
// Strip off pointers
11091133
while fn_ty.kind() == llvm::TypeKind::Pointer {
@@ -1115,16 +1139,31 @@ fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) {
11151139

11161140
let param_tys = fn_ty.func_params();
11171141

1118-
let iter = param_tys.into_iter()
1119-
.zip(args.iter().map(|&v| val_ty(v)));
1120-
for (i, (expected_ty, actual_ty)) in iter.enumerate() {
1121-
if expected_ty != actual_ty {
1122-
bug!("Type mismatch in function call of {:?}. \
1123-
Expected {:?} for param {}, got {:?}",
1124-
Value(llfn),
1125-
expected_ty, i, actual_ty);
1142+
let all_args_match = param_tys.iter()
1143+
.zip(args.iter().map(|&v| val_ty(v)))
1144+
.all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
1145+
1146+
if all_args_match {
1147+
return Cow::Borrowed(args);
1148+
}
1149+
1150+
let casted_args: Vec<_> = param_tys.into_iter()
1151+
.zip(args.iter())
1152+
.enumerate()
1153+
.map(|(i, (expected_ty, &actual_val))| {
1154+
let actual_ty = val_ty(actual_val);
1155+
if expected_ty != actual_ty {
1156+
debug!("Type mismatch in function call of {:?}. \
1157+
Expected {:?} for param {}, got {:?}; injecting bitcast",
1158+
Value(llfn),
1159+
expected_ty, i, actual_ty);
1160+
self.bitcast(actual_val, expected_ty)
1161+
} else {
1162+
actual_val
1163+
}
1164+
})
1165+
.collect();
11261166

1127-
}
1128-
}
1167+
return Cow::Owned(casted_args);
11291168
}
11301169
}

src/librustc_trans/callee.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,7 @@ impl<'tcx> Callee<'tcx> {
184184
pub fn direct_fn_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>,
185185
extra_args: &[Ty<'tcx>]) -> FnType {
186186
let abi = self.ty.fn_abi();
187-
let sig = ccx.tcx().erase_late_bound_regions(self.ty.fn_sig());
188-
let sig = ccx.tcx().normalize_associated_type(&sig);
187+
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(self.ty.fn_sig());
189188
let mut fn_ty = FnType::unadjusted(ccx, abi, &sig, extra_args);
190189
if let Virtual(_) = self.data {
191190
// Don't pass the vtable, it's not an argument of the virtual fn.
@@ -327,8 +326,7 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
327326
bare_fn_ty);
328327
}
329328
};
330-
let sig = tcx.erase_late_bound_regions(sig);
331-
let sig = ccx.tcx().normalize_associated_type(&sig);
329+
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
332330
let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec());
333331
let sig = ty::FnSig {
334332
inputs: vec![bare_fn_ty_maybe_ref,

src/librustc_trans/closure.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
6161

6262
// Compute the rust-call form of the closure call method.
6363
let sig = &tcx.closure_type(closure_id, substs).sig;
64-
let sig = tcx.erase_late_bound_regions(sig);
65-
let sig = tcx.normalize_associated_type(&sig);
64+
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
6665
let closure_type = tcx.mk_closure_from_closure_substs(closure_id, substs);
6766
let function_type = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
6867
unsafety: hir::Unsafety::Normal,
@@ -126,8 +125,7 @@ pub fn trans_closure_body_via_mir<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
126125
// of the closure expression.
127126

128127
let sig = &tcx.closure_type(closure_def_id, closure_substs).sig;
129-
let sig = tcx.erase_late_bound_regions(sig);
130-
let sig = tcx.normalize_associated_type(&sig);
128+
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
131129

132130
let closure_type = tcx.mk_closure_from_closure_substs(closure_def_id,
133131
closure_substs);
@@ -249,8 +247,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
249247
assert_eq!(abi, Abi::RustCall);
250248
sig.0.inputs[0] = closure_ty;
251249

252-
let sig = tcx.erase_late_bound_regions(&sig);
253-
let sig = tcx.normalize_associated_type(&sig);
250+
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
254251
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
255252

256253
let llonce_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ impl<'tcx> TypeMap<'tcx> {
235235
ty::TyTrait(ref trait_data) => {
236236
unique_type_id.push_str("trait ");
237237

238-
let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal);
238+
let principal = cx.tcx().erase_late_bound_regions_and_normalize(
239+
&trait_data.principal);
239240

240241
from_def_id_and_substs(self,
241242
cx,
@@ -253,8 +254,7 @@ impl<'tcx> TypeMap<'tcx> {
253254

254255
unique_type_id.push_str(" fn(");
255256

256-
let sig = cx.tcx().erase_late_bound_regions(sig);
257-
let sig = cx.tcx().normalize_associated_type(&sig);
257+
let sig = cx.tcx().erase_late_bound_regions_and_normalize(sig);
258258

259259
for &parameter_type in &sig.inputs {
260260
let parameter_type_id =

src/librustc_trans/debuginfo/type_names.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
9494
output.push(']');
9595
},
9696
ty::TyTrait(ref trait_data) => {
97-
let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal);
97+
let principal = cx.tcx().erase_late_bound_regions_and_normalize(
98+
&trait_data.principal);
9899
push_item_name(cx, principal.def_id, false, output);
99100
push_type_params(cx, principal.substs, output);
100101
},
@@ -112,8 +113,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
112113

113114
output.push_str("fn(");
114115

115-
let sig = cx.tcx().erase_late_bound_regions(sig);
116-
let sig = cx.tcx().normalize_associated_type(&sig);
116+
let sig = cx.tcx().erase_late_bound_regions_and_normalize(sig);
117117
if !sig.inputs.is_empty() {
118118
for &parameter_type in &sig.inputs {
119119
push_debuginfo_type_name(cx, parameter_type, true, output);

src/librustc_trans/declare.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
104104
fn_type: ty::Ty<'tcx>) -> ValueRef {
105105
debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type);
106106
let abi = fn_type.fn_abi();
107-
let sig = ccx.tcx().erase_late_bound_regions(fn_type.fn_sig());
108-
let sig = ccx.tcx().normalize_associated_type(&sig);
107+
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(fn_type.fn_sig());
109108
debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
110109

111110
let fty = FnType::new(ccx, abi, &sig, &[]);

src/librustc_trans/intrinsic.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
9999

100100
let _icx = push_ctxt("trans_intrinsic_call");
101101

102-
let (def_id, substs, sig) = match callee_ty.sty {
103-
ty::TyFnDef(def_id, substs, fty) => {
104-
let sig = tcx.erase_late_bound_regions(&fty.sig);
105-
(def_id, substs, tcx.normalize_associated_type(&sig))
106-
}
102+
let (def_id, substs, fty) = match callee_ty.sty {
103+
ty::TyFnDef(def_id, substs, ref fty) => (def_id, substs, fty),
107104
_ => bug!("expected fn item type, found {}", callee_ty)
108105
};
106+
107+
let sig = tcx.erase_late_bound_regions_and_normalize(&fty.sig);
109108
let arg_tys = sig.inputs;
110109
let ret_ty = sig.output;
111110
let name = tcx.item_name(def_id).as_str();
@@ -1108,8 +1107,7 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
11081107

11091108

11101109
let tcx = bcx.tcx();
1111-
let sig = tcx.erase_late_bound_regions(callee_ty.fn_sig());
1112-
let sig = tcx.normalize_associated_type(&sig);
1110+
let sig = tcx.erase_late_bound_regions_and_normalize(callee_ty.fn_sig());
11131111
let arg_tys = sig.inputs;
11141112

11151113
// every intrinsic takes a SIMD vector as its first argument

src/librustc_trans/meth.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
8080
_ => bug!()
8181
};
8282

83-
let sig = tcx.erase_late_bound_regions(sig);
84-
let sig = tcx.normalize_associated_type(&sig);
83+
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
8584
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
8685

8786
let llfn = declare::define_internal_fn(ccx, &function_name, callee.ty);

0 commit comments

Comments
 (0)