Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable] Backports for 1.12.1 #37173

Merged
merged 10 commits into from
Oct 19, 2016
2 changes: 1 addition & 1 deletion mk/main.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
######################################################################

# The version number
CFG_RELEASE_NUM=1.12.0
CFG_RELEASE_NUM=1.12.1

# An optional number to put after the label, e.g. '.2' -> '-beta.2'
# NB Make sure it starts with a dot to conform to semver pre-release
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ impl FlagComputation {
}

&ty::TyProjection(ref data) => {
// currently we can't normalize projections that
// include bound regions, so track those separately.
if !data.has_escaping_regions() {
self.add_flags(TypeFlags::HAS_NORMALIZABLE_PROJECTION);
}
self.add_flags(TypeFlags::HAS_PROJECTION);
self.add_projection_ty(data);
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
TypeFlags::HAS_FREE_REGIONS |
TypeFlags::HAS_TY_INFER |
TypeFlags::HAS_PARAMS |
TypeFlags::HAS_PROJECTION |
TypeFlags::HAS_NORMALIZABLE_PROJECTION |
TypeFlags::HAS_TY_ERR |
TypeFlags::HAS_SELF)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/item_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Returns the def-id of `def_id`'s parent in the def tree. If
/// this returns `None`, then `def_id` represents a crate root or
/// inlined root.
fn parent_def_id(&self, def_id: DefId) -> Option<DefId> {
pub fn parent_def_id(&self, def_id: DefId) -> Option<DefId> {
let key = self.def_key(def_id);
key.parent.map(|index| DefId { krate: def_id.krate, index: index })
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,10 @@ bitflags! {
// Only set for TyInfer other than Fresh.
const KEEP_IN_LOCAL_TCX = 1 << 11,

// Is there a projection that does not involve a bound region?
// Currently we can't normalize projections w/ bound regions.
const HAS_NORMALIZABLE_PROJECTION = 1 << 12,

const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
TypeFlags::HAS_SELF.bits |
TypeFlags::HAS_RE_EARLY_BOUND.bits,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/build/expr/as_lvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ExprKind::LogicalOp { .. } |
ExprKind::Box { .. } |
ExprKind::Cast { .. } |
ExprKind::Use { .. } |
ExprKind::NeverToAny { .. } |
ExprKind::ReifyFnPointer { .. } |
ExprKind::UnsafeFnPointer { .. } |
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_mir/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source = unpack!(block = this.as_operand(block, source));
block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty))
}
ExprKind::Use { source } => {
let source = unpack!(block = this.as_operand(block, source));
block.and(Rvalue::Use(source))
}
ExprKind::ReifyFnPointer { source } => {
let source = unpack!(block = this.as_operand(block, source));
block.and(Rvalue::Cast(CastKind::ReifyFnPointer, source, expr.ty))
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/build/expr/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ impl Category {
ExprKind::Binary { .. } |
ExprKind::Box { .. } |
ExprKind::Cast { .. } |
ExprKind::Use { .. } |
ExprKind::ReifyFnPointer { .. } |
ExprKind::UnsafeFnPointer { .. } |
ExprKind::Unsize { .. } |
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ExprKind::Binary { .. } |
ExprKind::Box { .. } |
ExprKind::Cast { .. } |
ExprKind::Use { .. } |
ExprKind::ReifyFnPointer { .. } |
ExprKind::UnsafeFnPointer { .. } |
ExprKind::Unsize { .. } |
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/hair/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// Check to see if this cast is a "coercion cast", where the cast is actually done
// using a coercion (or is a no-op).
if let Some(&TyCastKind::CoercionCast) = cx.tcx.cast_kinds.borrow().get(&source.id) {
// Skip the actual cast itexpr, as it's now a no-op.
return source.make_mirror(cx);
// Convert the lexpr to a vexpr.
ExprKind::Use { source: source.to_ref() }
} else {
ExprKind::Cast { source: source.to_ref() }
}
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_mir/hair/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ pub enum ExprKind<'tcx> {
Cast {
source: ExprRef<'tcx>,
},
Use {
source: ExprRef<'tcx>,
}, // Use a lexpr to get a vexpr.
NeverToAny {
source: ExprRef<'tcx>,
},
Expand Down
11 changes: 10 additions & 1 deletion src/librustc_trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,16 @@ pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
_ => bug!("compare_scalar_types: must be a comparison operator"),
}
}
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyBool | ty::TyUint(_) | ty::TyChar => {
ty::TyBool => {
// FIXME(#36856) -- using `from_immediate` forces these booleans into `i8`,
// which works around some LLVM bugs
ICmp(bcx,
bin_op_to_icmp_predicate(op, false),
from_immediate(bcx, lhs),
from_immediate(bcx, rhs),
debug_loc)
}
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyUint(_) | ty::TyChar => {
ICmp(bcx,
bin_op_to_icmp_predicate(op, false),
lhs,
Expand Down
73 changes: 56 additions & 17 deletions src/librustc_trans/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use value::Value;
use util::nodemap::FnvHashMap;
use libc::{c_uint, c_char};

use std::borrow::Cow;
use std::ffi::CString;
use std::ptr;
use syntax_pos::Span;
Expand Down Expand Up @@ -175,8 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.collect::<Vec<String>>()
.join(", "));

check_call("invoke", llfn, args);

let args = self.check_call("invoke", llfn, args);
let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut());

unsafe {
Expand Down Expand Up @@ -543,6 +543,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
assert!(!self.llbuilder.is_null());
self.count_insn("store");
let ptr = self.check_store(val, ptr);
unsafe {
llvm::LLVMBuildStore(self.llbuilder, val, ptr)
}
Expand All @@ -552,6 +553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
assert!(!self.llbuilder.is_null());
self.count_insn("store.volatile");
let ptr = self.check_store(val, ptr);
unsafe {
let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
llvm::LLVMSetVolatile(insn, llvm::True);
Expand All @@ -562,6 +564,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) {
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
self.count_insn("store.atomic");
let ptr = self.check_store(val, ptr);
unsafe {
let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
let align = llalign_of_pref(self.ccx, ty.element_type());
Expand Down Expand Up @@ -857,8 +860,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.collect::<Vec<String>>()
.join(", "));

check_call("call", llfn, args);

let args = self.check_call("call", llfn, args);
let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut());

unsafe {
Expand Down Expand Up @@ -1100,10 +1102,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope);
}
}
}

fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) {
if cfg!(debug_assertions) {
/// Returns the ptr value that should be used for storing `val`.
fn check_store<'b>(&self,
val: ValueRef,
ptr: ValueRef) -> ValueRef {
let dest_ptr_ty = val_ty(ptr);
let stored_ty = val_ty(val);
let stored_ptr_ty = stored_ty.ptr_to();

assert_eq!(dest_ptr_ty.kind(), llvm::TypeKind::Pointer);

if dest_ptr_ty == stored_ptr_ty {
ptr
} else {
debug!("Type mismatch in store. \
Expected {:?}, got {:?}; inserting bitcast",
dest_ptr_ty, stored_ptr_ty);
self.bitcast(ptr, stored_ptr_ty)
}
}

/// Returns the args that should be used for a call to `llfn`.
fn check_call<'b>(&self,
typ: &str,
llfn: ValueRef,
args: &'b [ValueRef]) -> Cow<'b, [ValueRef]> {
let mut fn_ty = val_ty(llfn);
// Strip off pointers
while fn_ty.kind() == llvm::TypeKind::Pointer {
Expand All @@ -1115,16 +1139,31 @@ fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) {

let param_tys = fn_ty.func_params();

let iter = param_tys.into_iter()
.zip(args.iter().map(|&v| val_ty(v)));
for (i, (expected_ty, actual_ty)) in iter.enumerate() {
if expected_ty != actual_ty {
bug!("Type mismatch in function call of {:?}. \
Expected {:?} for param {}, got {:?}",
Value(llfn),
expected_ty, i, actual_ty);
let all_args_match = param_tys.iter()
.zip(args.iter().map(|&v| val_ty(v)))
.all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);

if all_args_match {
return Cow::Borrowed(args);
}

let casted_args: Vec<_> = param_tys.into_iter()
.zip(args.iter())
.enumerate()
.map(|(i, (expected_ty, &actual_val))| {
let actual_ty = val_ty(actual_val);
if expected_ty != actual_ty {
debug!("Type mismatch in function call of {:?}. \
Expected {:?} for param {}, got {:?}; injecting bitcast",
Value(llfn),
expected_ty, i, actual_ty);
self.bitcast(actual_val, expected_ty)
} else {
actual_val
}
})
.collect();

}
}
return Cow::Owned(casted_args);
}
}
4 changes: 3 additions & 1 deletion src/librustc_trans/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,9 @@ fn create_fn_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let concrete_substs = monomorphize::apply_param_substs(tcx,
param_substs,
&fn_substs);
assert!(concrete_substs.is_normalized_for_trans());
assert!(concrete_substs.is_normalized_for_trans(),
"concrete_substs not normalized for trans: {:?}",
concrete_substs);
TransItem::Fn(Instance::new(def_id, concrete_substs))
}

Expand Down
35 changes: 13 additions & 22 deletions src/librustc_trans/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use machine;
use type_of;

use syntax_pos::DUMMY_SP;
use syntax::parse::token::keywords;

use std::ops::Deref;
use std::rc::Rc;
Expand Down Expand Up @@ -301,7 +300,6 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
_ => bug!("spread argument isn't a tuple?!")
};

let lltuplety = type_of::type_of(bcx.ccx(), arg_ty);
let lltemp = bcx.with_block(|bcx| {
base::alloc_ty(bcx, arg_ty, &format!("arg{}", arg_index))
});
Expand All @@ -319,27 +317,20 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
} else {
arg.store_fn_arg(bcx, &mut llarg_idx, dst);
}

bcx.with_block(|bcx| arg_scope.map(|scope| {
let byte_offset_of_var_in_tuple =
machine::llelement_offset(bcx.ccx(), lltuplety, i);

let ops = unsafe {
[llvm::LLVMRustDIBuilderCreateOpDeref(),
llvm::LLVMRustDIBuilderCreateOpPlus(),
byte_offset_of_var_in_tuple as i64]
};

let variable_access = VariableAccess::IndirectVariable {
alloca: lltemp,
address_operations: &ops
};
declare_local(bcx, keywords::Invalid.name(),
tupled_arg_ty, scope, variable_access,
VariableKind::ArgumentVariable(arg_index + i + 1),
bcx.fcx().span.unwrap_or(DUMMY_SP));
}));
}

// Now that we have one alloca that contains the aggregate value,
// we can create one debuginfo entry for the argument.
bcx.with_block(|bcx| arg_scope.map(|scope| {
let variable_access = VariableAccess::DirectVariable {
alloca: lltemp
};
declare_local(bcx, arg_decl.debug_name,
arg_ty, scope, variable_access,
VariableKind::ArgumentVariable(arg_index + 1),
bcx.fcx().span.unwrap_or(DUMMY_SP));
}));

return LocalRef::Lvalue(LvalueRef::new_sized(lltemp, LvalueTy::from_ty(arg_ty)));
}

Expand Down
16 changes: 14 additions & 2 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,13 +535,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
report_unexpected_def();
return;
}
Def::Variant(..) | Def::Struct(..) => {
Def::Variant(..) => {
let variant = tcx.expect_variant_def(def);
if variant.kind != VariantKind::Unit {
report_unexpected_def();
return;
}
}
Def::Struct(ctor_did) => {
let did = tcx.parent_def_id(ctor_did).expect("struct ctor has no parent");
let variant = tcx.lookup_adt_def(did).struct_variant();
if variant.kind != VariantKind::Unit {
report_unexpected_def();
return;
}
}
Def::Const(..) | Def::AssociatedConst(..) => {} // OK
_ => bug!("unexpected pattern definition {:?}", def)
}
Expand Down Expand Up @@ -592,9 +600,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
report_unexpected_def(false);
return;
}
Def::Variant(..) | Def::Struct(..) => {
Def::Variant(..) => {
tcx.expect_variant_def(def)
}
Def::Struct(ctor_did) => {
let did = tcx.parent_def_id(ctor_did).expect("struct ctor has no parent");
tcx.lookup_adt_def(did).struct_variant()
}
_ => bug!("unexpected pattern definition {:?}", def)
};
if variant.kind == VariantKind::Unit && subpats.is_empty() && ddpos.is_some() {
Expand Down
2 changes: 1 addition & 1 deletion src/rustllvm/llvm-auto-clean-trigger
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime.
2016-09-17
2016-10-10
Loading