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

Fix type and linkage errors with parallel codegen #26018

Merged
merged 4 commits into from
Jun 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ pub enum DefIdSource {
// Identifies a type alias (`type X = ...`).
TypeWithId,

// Identifies a type parameter (`fn foo<X>() { ... }`).
TypeParameter,

// Identifies a region parameter (`fn foo<'X>() { ... }`).
RegionParameter,

Expand Down Expand Up @@ -193,7 +190,7 @@ pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: us
tcx: &ty::ctxt<'tcx>, conv: F) -> subst::Substs<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
debug!("parse_substs_data {}", data_log_string(data, pos));
debug!("parse_substs_data{}", data_log_string(data, pos));
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_substs(&mut st, conv)
}
Expand Down Expand Up @@ -542,7 +539,14 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
len: len };

match tcx.rcache.borrow().get(&key).cloned() {
Some(tt) => return tt,
Some(tt) => {
// If there is a closure buried in the type some where, then we
// need to re-convert any def ids (see case 'k', below). That means
// we can't reuse the cached version.
if !ty::type_has_ty_closure(tt) {
return tt;
}
}
None => {}
}
let mut ps = PState {
Expand Down
48 changes: 6 additions & 42 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use middle::def;
use metadata::encoder as e;
use middle::region;
use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId};
use metadata::tydecode::{RegionParameter, ClosureSource};
use metadata::tyencode;
use middle::cast;
Expand Down Expand Up @@ -346,13 +346,6 @@ impl<D:serialize::Decoder> def_id_decoder_helpers for D
// ______________________________________________________________________
// Encoding and decoding the AST itself
//
// The hard work is done by an autogenerated module astencode_gen. To
// regenerate astencode_gen, run src/etc/gen-astencode. It will
// replace astencode_gen with a dummy file and regenerate its
// contents. If you get compile errors, the dummy file
// remains---resolve the errors and then rerun astencode_gen.
// Annoying, I know, but hopefully only temporary.
//
// When decoding, we have to renumber the AST so that the node ids that
// appear within are disjoint from the node ids in our existing ASTs.
// We also have to adjust the spans: for now we just insert a dummy span,
Expand Down Expand Up @@ -656,35 +649,6 @@ impl<'a, 'tcx> read_method_callee_helper<'tcx> for reader::Decoder<'a> {
}
}

impl<'tcx> tr for MethodOrigin<'tcx> {
fn tr(&self, dcx: &DecodeContext) -> MethodOrigin<'tcx> {
match *self {
ty::MethodStatic(did) => ty::MethodStatic(did.tr(dcx)),
ty::MethodStaticClosure(did) => {
ty::MethodStaticClosure(did.tr(dcx))
}
ty::MethodTypeParam(ref mp) => {
ty::MethodTypeParam(
ty::MethodParam {
// def-id is already translated when we read it out
trait_ref: mp.trait_ref.clone(),
method_num: mp.method_num,
impl_def_id: mp.impl_def_id.tr(dcx),
}
)
}
ty::MethodTraitObject(ref mo) => {
ty::MethodTraitObject(
ty::MethodObject {
trait_ref: mo.trait_ref.clone(),
.. *mo
}
)
}
}
}
}

pub fn encode_closure_kind(ebml_w: &mut Encoder, kind: ty::ClosureKind) {
kind.encode(ebml_w).unwrap();
}
Expand Down Expand Up @@ -1473,10 +1437,10 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
-> subst::Substs<'tcx> {
self.read_opaque(|this, doc| {
Ok(tydecode::parse_substs_data(doc.data,
dcx.cdata.cnum,
doc.start,
dcx.tcx,
|s, a| this.convert_def_id(dcx, s, a)))
dcx.cdata.cnum,
doc.start,
dcx.tcx,
|s, a| this.convert_def_id(dcx, s, a)))
}).unwrap()
}

Expand Down Expand Up @@ -1617,7 +1581,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
-> ast::DefId {
let r = match source {
NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did),
TypeParameter | ClosureSource => dcx.tr_intern_def_id(did)
ClosureSource => dcx.tr_intern_def_id(did)
};
debug!("convert_def_id(source={:?}, did={:?})={:?}", source, did, r);
return r;
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ bitflags! {
const HAS_REGIONS = 1 << 5,
const HAS_TY_ERR = 1 << 6,
const HAS_PROJECTION = 1 << 7,
const HAS_TY_CLOSURE = 1 << 8,
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
TypeFlags::HAS_SELF.bits |
TypeFlags::HAS_REGIONS.bits,
Expand Down Expand Up @@ -985,6 +986,9 @@ pub fn type_needs_infer(ty: Ty) -> bool {
pub fn type_has_projection(ty: Ty) -> bool {
ty.flags.get().intersects(TypeFlags::HAS_PROJECTION)
}
pub fn type_has_ty_closure(ty: Ty) -> bool {
ty.flags.get().intersects(TypeFlags::HAS_TY_CLOSURE)
}

pub fn type_has_late_bound_regions(ty: Ty) -> bool {
ty.flags.get().intersects(TypeFlags::HAS_RE_LATE_BOUND)
Expand Down Expand Up @@ -2960,6 +2964,7 @@ impl FlagComputation {
}

&ty_closure(_, substs) => {
self.add_flags(TypeFlags::HAS_TY_CLOSURE);
self.add_substs(substs);
}

Expand Down
24 changes: 19 additions & 5 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,11 +304,18 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
s
}

fn closure_to_string<'tcx>(cx: &ctxt<'tcx>, cty: &ty::ClosureTy<'tcx>) -> String {
fn closure_to_string<'tcx>(cx: &ctxt<'tcx>,
cty: &ty::ClosureTy<'tcx>,
did: &ast::DefId)
-> String {
let mut s = String::new();
s.push_str("[closure");
push_sig_to_string(cx, &mut s, '(', ')', &cty.sig);
s.push(']');
if cx.sess.verbose() {
s.push_str(&format!(" id={:?}]", did));
} else {
s.push(']');
}
s
}

Expand Down Expand Up @@ -407,13 +414,20 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
ty_closure(ref did, substs) => {
let closure_tys = cx.closure_tys.borrow();
closure_tys.get(did).map(|closure_type| {
closure_to_string(cx, &closure_type.subst(cx, substs))
closure_to_string(cx, &closure_type.subst(cx, substs), did)
}).unwrap_or_else(|| {
let id_str = if cx.sess.verbose() {
format!(" id={:?}", did)
} else {
"".to_owned()
};


if did.krate == ast::LOCAL_CRATE {
let span = cx.map.span(did.node);
format!("[closure {}]", span.repr(cx))
format!("[closure {}{}]", span.repr(cx), id_str)
} else {
format!("[closure]")
format!("[closure{}]", id_str)
}
})
}
Expand Down
8 changes: 5 additions & 3 deletions src/librustc_trans/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,8 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
_ => {
bcx.tcx().sess.span_bug(
expr.span,
&format!("type of callee is neither bare-fn nor closure: \
{}",
bcx.ty_to_string(datum.ty)));
&format!("type of callee is neither bare-fn nor closure: {}",
bcx.ty_to_string(datum.ty)));
}
}
}
Expand Down Expand Up @@ -506,6 +505,9 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
false
};

debug!("trans_fn_ref_with_substs({}) must_monomorphise: {}",
def_id.repr(tcx), must_monomorphise);

// Create a monomorphic version of generic functions
if must_monomorphise {
// Should be either intra-crate or inlined.
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_trans/trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc

match ccx.closure_vals().borrow().get(&mono_id) {
Some(&llfn) => {
debug!("get_or_create_declaration_if_closure(): found closure");
debug!("get_or_create_declaration_if_closure(): found closure {:?}: {:?}",
mono_id, ccx.tn().val_to_string(llfn));
return Some(Datum::new(llfn, function_type, Rvalue::new(ByValue)))
}
None => {}
Expand All @@ -173,9 +174,10 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
attributes::inline(llfn, attributes::InlineAttr::Hint);

debug!("get_or_create_declaration_if_closure(): inserting new \
closure {:?} (type {})",
closure {:?} (type {}): {:?}",
mono_id,
ccx.tn().type_to_string(val_ty(llfn)));
ccx.tn().type_to_string(val_ty(llfn)),
ccx.tn().val_to_string(llfn));
ccx.closure_vals().borrow_mut().insert(mono_id, llfn);

Some(Datum::new(llfn, function_type, Rvalue::new(ByValue)))
Expand All @@ -198,9 +200,9 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
Dest::Ignore(ccx) => ccx
};
let tcx = ccx.tcx();
let _icx = push_ctxt("closure::trans_closure");
let _icx = push_ctxt("closure::trans_closure_expr");

debug!("trans_closure()");
debug!("trans_closure_expr()");

let closure_id = ast_util::local_def(id);
let llfn = get_or_create_declaration_if_closure(
Expand Down Expand Up @@ -230,15 +232,15 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
&[],
sig.output,
function_type.abi,
ClosureEnv::Closure(&freevars[..]));
ClosureEnv::Closure(&freevars));

// Don't hoist this to the top of the function. It's perfectly legitimate
// to have a zero-size closure (in which case dest will be `Ignore`) and
// we must still generate the closure body.
let (mut bcx, dest_addr) = match dest {
Dest::SaveIn(bcx, p) => (bcx, p),
Dest::Ignore(_) => {
debug!("trans_closure() ignoring result");
debug!("trans_closure_expr() ignoring result");
return None;
}
};
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_trans/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1000,7 +1000,8 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
None => { }
}

debug!("trans fulfill_obligation: trait_ref={}", trait_ref.repr(ccx.tcx()));
debug!("trans fulfill_obligation: trait_ref={} def_id={:?}",
trait_ref.repr(ccx.tcx()), trait_ref.def_id());

ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx);
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_trans/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,16 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
qualif: check_const::ConstQualif,
param_substs: &'tcx Substs<'tcx>)
-> ValueRef {
debug!("get_const_expr_as_global: {:?}", expr.id);
// Special-case constants to cache a common global for all uses.
match expr.node {
ast::ExprPath(..) => {
let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
match def {
def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) {
debug!("get_const_expr_as_global ({:?}): found const {:?}",
expr.id, def_id);
return get_const_val(ccx, def_id, expr);
}
}
Expand Down Expand Up @@ -911,7 +914,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
ast::ExprClosure(_, ref decl, ref body) => {
closure::trans_closure_expr(closure::Dest::Ignore(cx),
&**decl, &**body, e.id,
decl,
body,
e.id,
param_substs);
C_null(type_of::type_of(cx, ety))
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_trans/trans/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ pub struct SharedCrateContext<'tcx> {
check_overflow: bool,
check_drop_flag_for_sanity: bool,

available_monomorphizations: RefCell<FnvHashSet<String>>,
available_drop_glues: RefCell<FnvHashMap<DropGlueKind<'tcx>, String>>,
use_dll_storage_attrs: bool,
}
Expand All @@ -100,6 +99,7 @@ pub struct LocalCrateContext<'tcx> {
/// Cache instances of monomorphized functions
monomorphized: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
monomorphizing: RefCell<DefIdMap<usize>>,
available_monomorphizations: RefCell<FnvHashSet<String>>,
/// Cache generated vtables
vtables: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>>,
/// Cache of constant strings,
Expand Down Expand Up @@ -321,7 +321,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
},
check_overflow: check_overflow,
check_drop_flag_for_sanity: check_drop_flag_for_sanity,
available_monomorphizations: RefCell::new(FnvHashSet()),
available_drop_glues: RefCell::new(FnvHashMap()),
use_dll_storage_attrs: use_dll_storage_attrs,
};
Expand Down Expand Up @@ -452,6 +451,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
external_srcs: RefCell::new(NodeMap()),
monomorphized: RefCell::new(FnvHashMap()),
monomorphizing: RefCell::new(DefIdMap()),
available_monomorphizations: RefCell::new(FnvHashSet()),
vtables: RefCell::new(FnvHashMap()),
const_cstr_cache: RefCell::new(FnvHashMap()),
const_unsized: RefCell::new(FnvHashMap()),
Expand Down Expand Up @@ -709,7 +709,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
}

pub fn available_monomorphizations<'a>(&'a self) -> &'a RefCell<FnvHashSet<String>> {
&self.shared.available_monomorphizations
&self.local.available_monomorphizations
}

pub fn available_drop_glues(&self) -> &RefCell<FnvHashMap<DropGlueKind<'tcx>, String>> {
Expand Down
10 changes: 0 additions & 10 deletions src/librustc_trans/trans/controlflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use syntax::ast;
use syntax::ast_util;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::visit::Visitor;

pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
s: &ast::Stmt)
Expand Down Expand Up @@ -171,16 +170,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// if true { .. } [else { .. }]
bcx = trans_block(bcx, &*thn, dest);
trans::debuginfo::clear_source_location(bcx.fcx);

if let Some(elexpr) = els {
let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
trans.visit_expr(&*elexpr);
}
} else {
// if false { .. } [else { .. }]
let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
trans.visit_block(&*thn);

if let Some(elexpr) = els {
bcx = expr::trans_into(bcx, &*elexpr, dest);
trans::debuginfo::clear_source_location(bcx.fcx);
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_trans/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
SaveIn(lldest) => closure::Dest::SaveIn(bcx, lldest),
Ignore => closure::Dest::Ignore(bcx.ccx())
};
closure::trans_closure_expr(dest, &**decl, &**body, expr.id, bcx.fcx.param_substs)
closure::trans_closure_expr(dest, decl, body, expr.id, bcx.fcx.param_substs)
.unwrap_or(bcx)
}
ast::ExprCall(ref f, ref args) => {
Expand Down Expand Up @@ -1956,6 +1956,7 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
args: &'a [P<ast::Expr>],
dest: Option<Dest>)
-> Block<'blk, 'tcx> {
debug!("trans_overloaded_call {}", expr.id);
let method_call = MethodCall::expr(expr.id);
let method_type = bcx.tcx()
.method_map
Expand Down
Loading