Skip to content

Commit

Permalink
Auto merge of #40163 - arielb1:normalization-1702, r=nikomatsakis
Browse files Browse the repository at this point in the history
More through normalization, Feb/Mar 2017 edition

Fix a few normalization bugs.

Fixes #27901.
Fixes #28828.
Fixes #38135.
Fixes #39363.
Fixes #39367.
  • Loading branch information
bors committed Mar 4, 2017
2 parents 5208090 + 4aede75 commit 8c6c0f8
Show file tree
Hide file tree
Showing 22 changed files with 235 additions and 136 deletions.
14 changes: 11 additions & 3 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,12 +816,20 @@ pub enum Lvalue<'tcx> {
Local(Local),

/// static or static mut variable
Static(DefId),
Static(Box<Static<'tcx>>),

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

/// The def-id of a static, along with its normalized type (which is
/// stored to avoid requiring normalization when reading MIR).
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub struct Static<'tcx> {
pub def_id: DefId,
pub ty: Ty<'tcx>,
}

/// The `Projection` data structure defines things of the form `B.x`
/// or `*B` or `B[index]`. Note that it is parameterized because it is
/// shared between `Constant` and `Lvalue`. See the aliases
Expand Down Expand Up @@ -911,8 +919,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {

match *self {
Local(id) => write!(fmt, "{:?}", id),
Static(def_id) =>
write!(fmt, "{}", ty::tls::with(|tcx| tcx.item_path_str(def_id))),
Static(box self::Static { def_id, ty }) =>
write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.item_path_str(def_id)), ty),
Projection(ref data) =>
match data.elem {
ProjectionElem::Downcast(ref adt_def, index) =>
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ impl<'tcx> Lvalue<'tcx> {
match *self {
Lvalue::Local(index) =>
LvalueTy::Ty { ty: mir.local_decls[index].ty },
Lvalue::Static(def_id) =>
LvalueTy::Ty { ty: tcx.item_type(def_id) },
Lvalue::Static(ref data) =>
LvalueTy::Ty { ty: data.ty },
Lvalue::Projection(ref proj) =>
proj.base.ty(mir, tcx).projection_ty(tcx, &proj.elem),
}
Expand Down
24 changes: 21 additions & 3 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ macro_rules! make_mir_visitor {
self.super_lvalue(lvalue, context, location);
}

fn visit_static(&mut self,
static_: & $($mutability)* Static<'tcx>,
context: LvalueContext<'tcx>,
location: Location) {
self.super_static(static_, context, location);
}

fn visit_projection(&mut self,
lvalue: & $($mutability)* LvalueProjection<'tcx>,
context: LvalueContext<'tcx>,
Expand Down Expand Up @@ -554,15 +561,27 @@ macro_rules! make_mir_visitor {
match *lvalue {
Lvalue::Local(_) => {
}
Lvalue::Static(ref $($mutability)* def_id) => {
self.visit_def_id(def_id, location);
Lvalue::Static(ref $($mutability)* static_) => {
self.visit_static(static_, context, location);
}
Lvalue::Projection(ref $($mutability)* proj) => {
self.visit_projection(proj, context, location);
}
}
}

fn super_static(&mut self,
static_: & $($mutability)* Static<'tcx>,
_context: LvalueContext<'tcx>,
location: Location) {
let Static {
ref $($mutability)* def_id,
ref $($mutability)* ty,
} = *static_;
self.visit_def_id(def_id, location);
self.visit_ty(ty);
}

fn super_projection(&mut self,
proj: & $($mutability)* LvalueProjection<'tcx>,
context: LvalueContext<'tcx>,
Expand Down Expand Up @@ -818,4 +837,3 @@ impl<'tcx> LvalueContext<'tcx> {
self.is_mutating_use() || self.is_nonmutating_use()
}
}

2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/as_lvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
block.and(Lvalue::Local(index))
}
ExprKind::StaticRef { id } => {
block.and(Lvalue::Static(id))
block.and(Lvalue::Static(Box::new(Static { def_id: id, ty: expr.ty })))
}

ExprKind::Array { .. } |
Expand Down
29 changes: 19 additions & 10 deletions src/librustc_mir/transform/type_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,21 @@ use syntax_pos::{Span, DUMMY_SP};

use rustc_data_structures::indexed_vec::Idx;

fn mirbug(tcx: TyCtxt, span: Span, msg: &str) {
tcx.sess.diagnostic().span_bug(span, msg);
}

macro_rules! span_mirbug {
($context:expr, $elem:expr, $($message:tt)*) => ({
$context.tcx().sess.span_warn(
$context.last_span,
&format!("broken MIR ({:?}): {}", $elem, format!($($message)*))
)
mirbug($context.tcx(), $context.last_span,
&format!("broken MIR ({:?}): {}", $elem, format!($($message)*)))
})
}

macro_rules! span_mirbug_and_err {
($context:expr, $elem:expr, $($message:tt)*) => ({
{
$context.tcx().sess.span_warn(
$context.last_span,
&format!("broken MIR ({:?}): {:?}", $elem, format!($($message)*))
);
span_mirbug!($context, $elem, $($message)*);
$context.error()
}
})
Expand Down Expand Up @@ -125,8 +124,18 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
debug!("sanitize_lvalue: {:?}", lvalue);
match *lvalue {
Lvalue::Local(index) => LvalueTy::Ty { ty: self.mir.local_decls[index].ty },
Lvalue::Static(def_id) =>
LvalueTy::Ty { ty: self.tcx().item_type(def_id) },
Lvalue::Static(box Static { def_id, ty: sty }) => {
let sty = self.sanitize_type(lvalue, sty);
let ty = self.tcx().item_type(def_id);
let ty = self.cx.normalize(&ty);
if let Err(terr) = self.cx.eq_types(self.last_span, ty, sty) {
span_mirbug!(
self, lvalue, "bad static type ({:?}: {:?}): {:?}",
ty, sty, terr);
}
LvalueTy::Ty { ty: sty }

},
Lvalue::Projection(ref proj) => {
let base_ty = self.sanitize_lvalue(&proj.base, location);
if let LvalueTy::Ty { ty } = base_ty {
Expand Down
9 changes: 2 additions & 7 deletions src/librustc_trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,10 +596,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
// release builds.
info!("trans_instance({})", instance);

let fn_ty = ccx.tcx().item_type(instance.def);
let fn_ty = ccx.tcx().erase_regions(&fn_ty);
let fn_ty = monomorphize::apply_param_substs(ccx.shared(), instance.substs, &fn_ty);

let fn_ty = common::def_ty(ccx.shared(), instance.def, instance.substs);
let sig = common::ty_fn_sig(ccx, fn_ty);
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig);

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

let ctor_ty = ccx.tcx().item_type(def_id);
let ctor_ty = monomorphize::apply_param_substs(ccx.shared(), substs, &ctor_ty);

let ctor_ty = common::def_ty(ccx.shared(), def_id, substs);
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&ctor_ty.fn_sig());
let fn_ty = FnType::new(ccx, sig, &[]);

Expand Down
18 changes: 4 additions & 14 deletions src/librustc_trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ use abi::{Abi, FnType};
use attributes;
use base;
use builder::Builder;
use common::{self, CrateContext, SharedCrateContext};
use common::{self, CrateContext};
use cleanup::CleanupScope;
use mir::lvalue::LvalueRef;
use consts;
use common::def_ty;
use declare;
use value::Value;
use meth;
use monomorphize::{self, Instance};
use monomorphize::Instance;
use trans_item::TransItem;
use type_of;
use Disr;
Expand Down Expand Up @@ -207,16 +208,6 @@ impl<'tcx> Callee<'tcx> {
}
}

/// Given a DefId and some Substs, produces the monomorphic item type.
fn def_ty<'a, 'tcx>(shared: &SharedCrateContext<'a, 'tcx>,
def_id: DefId,
substs: &'tcx Substs<'tcx>)
-> Ty<'tcx> {
let ty = shared.tcx().item_type(def_id);
monomorphize::apply_param_substs(shared, substs, &ty)
}


fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
def_id: DefId,
substs: ty::ClosureSubsts<'tcx>,
Expand Down Expand Up @@ -544,8 +535,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,

let substs = tcx.normalize_associated_type(&substs);
let instance = Instance::new(def_id, substs);
let item_ty = ccx.tcx().item_type(def_id);
let fn_ty = monomorphize::apply_param_substs(ccx.shared(), substs, &item_ty);
let fn_ty = common::def_ty(ccx.shared(), def_id, substs);

if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
return (llfn, fn_ty);
Expand Down
11 changes: 4 additions & 7 deletions src/librustc_trans/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ use syntax_pos::DUMMY_SP;
use base::custom_coerce_unsize_info;
use callee::needs_fn_once_adapter_shim;
use context::SharedCrateContext;
use common::fulfill_obligation;
use common::{def_ty, fulfill_obligation};
use glue::{self, DropGlueKind};
use monomorphize::{self, Instance};
use util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
Expand Down Expand Up @@ -341,7 +341,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
// Sanity check whether this ended up being collected accidentally
debug_assert!(should_trans_locally(scx.tcx(), def_id));

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

Expand Down Expand Up @@ -815,10 +815,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
}
ty::TyAdt(def, substs) => {
for field in def.all_fields() {
let field_type = scx.tcx().item_type(field.did);
let field_type = monomorphize::apply_param_substs(scx,
substs,
&field_type);
let field_type = def_ty(scx, field.did, substs);
let field_type = glue::get_drop_glue_type(scx, field_type);

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

let ty = self.scx.tcx().item_type(def_id);
let ty = def_ty(self.scx, def_id, Substs::empty());
let ty = glue::get_drop_glue_type(self.scx, ty);
self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
}
Expand Down
12 changes: 11 additions & 1 deletion src/librustc_trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use type_::Type;
use value::Value;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::Layout;
use rustc::ty::subst::Subst;
use rustc::ty::subst::{Subst, Substs};
use rustc::traits::{self, SelectionContext, Reveal};
use rustc::hir;

Expand Down Expand Up @@ -604,3 +604,13 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
pub fn is_closure(tcx: TyCtxt, def_id: DefId) -> bool {
tcx.def_key(def_id).disambiguated_data.data == DefPathData::ClosureExpr
}

/// Given a DefId and some Substs, produces the monomorphic item type.
pub fn def_ty<'a, 'tcx>(shared: &SharedCrateContext<'a, 'tcx>,
def_id: DefId,
substs: &'tcx Substs<'tcx>)
-> Ty<'tcx>
{
let ty = shared.tcx().item_type(def_id);
monomorphize::apply_param_substs(shared, substs, &ty)
}
9 changes: 5 additions & 4 deletions src/librustc_trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ use rustc::hir::map as hir_map;
use {debuginfo, machine};
use base;
use trans_item::TransItem;
use common::{CrateContext, val_ty};
use common::{self, CrateContext, val_ty};
use declare;
use monomorphize::{Instance};
use monomorphize::Instance;
use type_::Type;
use type_of;
use rustc::ty;
use rustc::ty::subst::Substs;

use rustc::hir;

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

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

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

let ty = ccx.tcx().item_type(def_id);
let ty = common::def_ty(ccx.shared(), def_id, Substs::empty());
let llty = type_of::type_of(ccx, ty);
let g = if val_llty == llty {
g
Expand Down
9 changes: 4 additions & 5 deletions src/librustc_trans/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use rustc::ty::util::TypeIdHasher;
use rustc::hir;
use rustc_data_structures::ToHex;
use {type_of, machine, monomorphize};
use common::CrateContext;
use common::{self, CrateContext};
use type_::Type;
use rustc::ty::{self, AdtKind, Ty, layout};
use session::config;
Expand Down Expand Up @@ -377,7 +377,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
span: Span)
-> MetadataCreationResult
{
let signature = cx.tcx().erase_late_bound_regions(&signature);
let signature = cx.tcx().erase_late_bound_regions_and_normalize(&signature);

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

Expand Down Expand Up @@ -1764,16 +1764,15 @@ pub fn create_global_var_metadata(cx: &CrateContext,
};

let is_local_to_unit = is_node_local_to_unit(cx, node_id);
let variable_type = tcx.erase_regions(&tcx.item_type(node_def_id));
let variable_type = common::def_ty(cx.shared(), node_def_id, Substs::empty());
let type_metadata = type_metadata(cx, variable_type, span);
let var_name = tcx.item_name(node_def_id).to_string();
let linkage_name = mangled_name_of_item(cx, node_def_id, "");

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

let ty = cx.tcx().item_type(node_def_id);
let global_align = type_of::align_of(cx, ty);
let global_align = type_of::align_of(cx, variable_type);

unsafe {
llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
Expand Down
11 changes: 4 additions & 7 deletions src/librustc_trans/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ use rustc::hir::def_id::DefId;
use rustc::ty::subst::Substs;

use abi::Abi;
use common::CrateContext;
use common::{self, CrateContext};
use builder::Builder;
use monomorphize::{self, Instance};
use monomorphize::Instance;
use rustc::ty::{self, Ty};
use rustc::mir;
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
Expand Down Expand Up @@ -397,11 +397,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let self_type = cx.tcx().impl_of_method(instance.def).and_then(|impl_def_id| {
// If the method does *not* belong to a trait, proceed
if cx.tcx().trait_id_of_impl(impl_def_id).is_none() {
let impl_self_ty = cx.tcx().item_type(impl_def_id);
let impl_self_ty = cx.tcx().erase_regions(&impl_self_ty);
let impl_self_ty = monomorphize::apply_param_substs(cx.shared(),
instance.substs,
&impl_self_ty);
let impl_self_ty =
common::def_ty(cx.shared(), impl_def_id, instance.substs);

// Only "class" methods are generally understood by LLVM,
// so avoid methods on other types (e.g. `<*mut T>::null`).
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,11 +382,11 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {

let lvalue = match *lvalue {
mir::Lvalue::Local(_) => bug!(), // handled above
mir::Lvalue::Static(def_id) => {
mir::Lvalue::Static(box mir::Static { def_id, ty }) => {
ConstLvalue {
base: Base::Static(consts::get_static(self.ccx, def_id)),
llextra: ptr::null_mut(),
ty: lvalue.ty(self.mir, tcx).to_ty(tcx)
ty: self.monomorphize(&ty),
}
}
mir::Lvalue::Projection(ref projection) => {
Expand Down
Loading

0 comments on commit 8c6c0f8

Please sign in to comment.