Skip to content

Commit

Permalink
auto merge of #12403 : eddyb/rust/generic-dtors-with-bounds, r=nikoma…
Browse files Browse the repository at this point in the history
…tsakis

Fix generic Drop impls with trait bounds.
Fixes #4252.
  • Loading branch information
bors committed Feb 20, 2014
2 parents 5f324aa + efaa1ea commit 06e1281
Show file tree
Hide file tree
Showing 16 changed files with 122 additions and 161 deletions.
40 changes: 6 additions & 34 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
RegionParameter};
use metadata::tyencode;
use middle::typeck::{method_origin, method_map_entry};
use middle::typeck::method_origin;
use middle::{ty, typeck, moves};
use middle;
use util::ppaux::ty_to_str;
Expand Down Expand Up @@ -573,35 +573,7 @@ impl tr for moves::CaptureVar {
}

// ______________________________________________________________________
// Encoding and decoding of method_map_entry

trait read_method_map_entry_helper {
fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
-> method_map_entry;
}

fn encode_method_map_entry(ebml_w: &mut writer::Encoder, mme: method_map_entry) {
ebml_w.emit_struct("method_map_entry", 3, |ebml_w| {
ebml_w.emit_struct_field("origin", 1u, |ebml_w| {
mme.origin.encode(ebml_w);
});
})
}

impl<'a> read_method_map_entry_helper for reader::Decoder<'a> {
fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
-> method_map_entry {
self.read_struct("method_map_entry", 3, |this| {
method_map_entry {
origin: this.read_struct_field("origin", 1, |this| {
let method_origin: method_origin =
Decodable::decode(this);
method_origin.tr(xcx)
})
}
})
}
}
// Encoding and decoding of method_origin

impl tr for method_origin {
fn tr(&self, xcx: @ExtendedDecodeContext) -> method_origin {
Expand Down Expand Up @@ -1023,11 +995,11 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
{
let method_map = maps.method_map.borrow();
let r = method_map.get().find(&id);
for &mme in r.iter() {
for &origin in r.iter() {
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
ebml_w.id(id);
ebml_w.tag(c::tag_table_val, |ebml_w| {
encode_method_map_entry(ebml_w, *mme)
origin.encode(ebml_w);
})
})
}
Expand Down Expand Up @@ -1364,9 +1336,9 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
ty_param_defs.get().insert(id, bounds);
}
c::tag_table_method_map => {
let entry = val_dsr.read_method_map_entry(xcx);
let origin: method_origin = Decodable::decode(val_dsr);
let mut method_map = dcx.maps.method_map.borrow_mut();
method_map.get().insert(id, entry);
method_map.get().insert(id, origin.tr(xcx));
}
c::tag_table_vtable_map => {
let vtable_res =
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl MarkSymbolVisitor {
span: codemap::Span) {
let method_map = self.method_map.borrow();
match method_map.get().find(id) {
Some(&typeck::method_map_entry { origin, .. }) => {
Some(&origin) => {
match origin {
typeck::method_static(def_id) => {
match ty::provided_source(self.tcx, def_id) {
Expand Down
11 changes: 9 additions & 2 deletions src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,15 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {

// Even though the callee_id may have been the id with
// node_type_substs, e.id is correct here.
ty::method_call_type_param_defs(cx.tcx, cx.method_map, e.id).expect(
"non path/method call expr has type substs??")
match cx.method_map.borrow().get().find(&e.id) {
Some(origin) => {
ty::method_call_type_param_defs(cx.tcx, *origin)
}
None => {
cx.tcx.sess.span_bug(e.span,
"non path/method call expr has type substs??");
}
}
}
};
let type_param_defs = type_param_defs.borrow();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,7 @@ fn check_stability(cx: &Context, e: &ast::Expr) {
ast::ExprMethodCall(..) => {
let method_map = cx.method_map.borrow();
match method_map.get().find(&e.id) {
Some(&typeck::method_map_entry { origin, .. }) => {
Some(&origin) => {
match origin {
typeck::method_static(def_id) => {
// If this implements a trait method, get def_id
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,17 +790,17 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
match ty::get(t).sty {
ty::ty_enum(_, _) | ty::ty_struct(_, _) => {
let method_map = self.method_map.borrow();
let entry = match method_map.get().find(&expr.id) {
match self.method_map.borrow().get().find(&expr.id) {
None => {
self.tcx.sess.span_bug(expr.span,
"method call not in \
method map");
}
Some(entry) => entry
};
debug!("(privacy checking) checking impl method");
self.check_method(expr.span, &entry.origin, ident);
Some(origin) => {
debug!("(privacy checking) checking impl method");
self.check_method(expr.span, origin, ident);
}
}
}
_ => {}
}
Expand Down
8 changes: 2 additions & 6 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,7 @@ impl Visitor<()> for MarkSymbolVisitor {
ast::ExprMethodCall(..) => {
let method_map = self.method_map.borrow();
match method_map.get().find(&expr.id) {
Some(&typeck::method_map_entry {
origin: typeck::method_static(def_id),
..
}) => {
Some(&typeck::method_static(def_id)) => {
if is_local(def_id) {
if ReachableContext::
def_id_represents_local_inlined_item(
Expand All @@ -174,8 +171,7 @@ impl Visitor<()> for MarkSymbolVisitor {
Some(_) => {}
None => {
self.tcx.sess.span_bug(expr.span,
"method call expression \
not in method map?!")
"method call expression not in method map?!")
}
}
}
Expand Down
25 changes: 9 additions & 16 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ use middle::trans::type_of;
use middle::trans::type_of::*;
use middle::trans::value::Value;
use middle::ty;
use middle::typeck;
use util::common::indenter;
use util::ppaux::{Repr, ty_to_str};
use util::sha2::Sha256;
Expand Down Expand Up @@ -535,22 +536,14 @@ pub fn get_res_dtor(ccx: @CrateContext,
};
if !substs.is_empty() {
assert_eq!(did.krate, ast::LOCAL_CRATE);
let tsubsts = ty::substs {regions: ty::ErasedRegions,
self_ty: None,
tps: /*bad*/ substs.to_owned() };

// FIXME: #4252: Generic destructors with type bounds are broken.
//
// Since the vtables aren't passed to `monomorphic_fn` here, generic destructors with type
// bounds are broken. Sadly, the `typeck` pass isn't outputting the necessary metadata
// because it does so based on method calls present in the AST. Destructor calls are not yet
// known about at that stage of compilation, since `trans` handles cleanups.
let (val, _) = monomorphize::monomorphic_fn(ccx,
did,
&tsubsts,
None,
None,
None);
let tsubsts = ty::substs {
regions: ty::ErasedRegions,
self_ty: None,
tps: substs.to_owned()
};

let vtables = typeck::check::vtable::trans_resolve_method(ccx.tcx, did.node, &tsubsts);
let (val, _) = monomorphize::monomorphic_fn(ccx, did, &tsubsts, vtables, None, None);

val
} else if did.krate == ast::LOCAL_CRATE {
Expand Down
9 changes: 4 additions & 5 deletions src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,15 @@ pub fn trans_method_callee<'a>(
bcx: &'a Block<'a>,
callee_id: ast::NodeId,
this: &ast::Expr,
mentry: typeck::method_map_entry,
origin: typeck::method_origin,
arg_cleanup_scope: cleanup::ScopeId)
-> Callee<'a> {
let _icx = push_ctxt("meth::trans_method_callee");

debug!("trans_method_callee(callee_id={:?}, mentry={})",
callee_id,
mentry.repr(bcx.tcx()));
debug!("trans_method_callee(callee_id={:?}, origin={})",
callee_id, origin.repr(bcx.tcx()));

match mentry.origin {
match origin {
typeck::method_static(did) => {
Callee {
bcx: bcx,
Expand Down
29 changes: 12 additions & 17 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3242,25 +3242,21 @@ pub fn expr_has_ty_params(cx: ctxt, expr: &ast::Expr) -> bool {
return node_id_has_type_params(cx, expr.id);
}

pub fn method_call_type_param_defs(tcx: ctxt,
method_map: typeck::method_map,
id: ast::NodeId)
-> Option<Rc<~[TypeParameterDef]>> {
let method_map = method_map.borrow();
method_map.get().find(&id).map(|method| {
match method.origin {
typeck::method_static(did) => {
pub fn method_call_type_param_defs(tcx: ctxt, origin: typeck::method_origin)
-> Rc<~[TypeParameterDef]> {
match origin {
typeck::method_static(did) => {
// n.b.: When we encode impl methods, the bounds
// that we encode include both the impl bounds
// and then the method bounds themselves...
ty::lookup_item_type(tcx, did).generics.type_param_defs
}
typeck::method_param(typeck::method_param {
trait_id: trt_id,
method_num: n_mth, ..}) |
typeck::method_object(typeck::method_object {
trait_id: trt_id,
method_num: n_mth, ..}) => {
}
typeck::method_param(typeck::method_param {
trait_id: trt_id,
method_num: n_mth, ..}) |
typeck::method_object(typeck::method_object {
trait_id: trt_id,
method_num: n_mth, ..}) => {
// ...trait methods bounds, in contrast, include only the
// method bounds, so we must preprend the tps from the
// trait itself. This ought to be harmonized.
Expand All @@ -3271,9 +3267,8 @@ pub fn method_call_type_param_defs(tcx: ctxt,
ty::trait_method(tcx,
trt_id,
n_mth).generics.type_param_defs()))
}
}
})
}
}

pub fn resolve_expr(tcx: ctxt, expr: &ast::Expr) -> ast::Def {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/typeck/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ use syntax::codemap::Span;

// Requires that the two types unify, and prints an error message if they
// don't.
pub fn suptype(fcx: @FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
pub fn suptype(fcx: &FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
suptype_with_fn(fcx, sp, false, expected, actual,
|sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) })
}

pub fn subtype(fcx: @FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
pub fn subtype(fcx: &FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
suptype_with_fn(fcx, sp, true, actual, expected,
|sp, a, e, s| { fcx.report_mismatched_types(sp, e, a, s) })
}

pub fn suptype_with_fn(fcx: @FnCtxt,
pub fn suptype_with_fn(fcx: &FnCtxt,
sp: Span,
b_is_expected: bool,
ty_a: ty::t,
Expand Down
28 changes: 13 additions & 15 deletions src/librustc/middle/typeck/check/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ use middle::typeck::check::{structurally_resolved_type};
use middle::typeck::check::vtable;
use middle::typeck::check;
use middle::typeck::infer;
use middle::typeck::{method_map_entry, method_origin, method_param};
use middle::typeck::{method_origin, method_param};
use middle::typeck::{method_static, method_object};
use middle::typeck::{param_numbered, param_self, param_index};
use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
Expand Down Expand Up @@ -133,7 +133,7 @@ pub fn lookup(
deref_args: check::DerefArgs, // Whether we autopointer first.
check_traits: CheckTraitsFlag, // Whether we check traits only.
autoderef_receiver: AutoderefReceiverFlag)
-> Option<method_map_entry> {
-> Option<method_origin> {
let impl_dups = @RefCell::new(HashSet::new());
let lcx = LookupContext {
fcx: fcx,
Expand Down Expand Up @@ -211,7 +211,7 @@ enum RcvrMatchCondition {
}

impl<'a> LookupContext<'a> {
fn search(&self, self_ty: ty::t) -> Option<method_map_entry> {
fn search(&self, self_ty: ty::t) -> Option<method_origin> {
let mut self_ty = self_ty;
let mut autoderefs = 0;
loop {
Expand Down Expand Up @@ -592,7 +592,7 @@ impl<'a> LookupContext<'a> {
fn search_for_autoderefd_method(&self,
self_ty: ty::t,
autoderefs: uint)
-> Option<method_map_entry> {
-> Option<method_origin> {
let (self_ty, autoadjust) =
self.consider_reborrow(self_ty, autoderefs);
match self.search_for_method(self_ty) {
Expand Down Expand Up @@ -686,9 +686,9 @@ impl<'a> LookupContext<'a> {
}

fn search_for_autosliced_method(&self,
self_ty: ty::t,
autoderefs: uint)
-> Option<method_map_entry> {
self_ty: ty::t,
autoderefs: uint)
-> Option<method_origin> {
/*!
*
* Searches for a candidate by converting things like
Expand Down Expand Up @@ -763,7 +763,7 @@ impl<'a> LookupContext<'a> {
}

fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
-> Option<method_map_entry> {
-> Option<method_origin> {
/*!
*
* Converts any type `T` to `&M T` where `M` is an
Expand Down Expand Up @@ -799,7 +799,7 @@ impl<'a> LookupContext<'a> {
autoderefs: uint,
mutbls: &[ast::Mutability],
mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t)
-> Option<method_map_entry> {
-> Option<method_origin> {
// This is hokey. We should have mutability inference as a
// variable. But for now, try &const, then &, then &mut:
let region =
Expand All @@ -823,7 +823,7 @@ impl<'a> LookupContext<'a> {
}

fn search_for_method(&self, rcvr_ty: ty::t)
-> Option<method_map_entry> {
-> Option<method_origin> {
debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty));
let _indenter = indenter();

Expand Down Expand Up @@ -855,7 +855,7 @@ impl<'a> LookupContext<'a> {
fn consider_candidates(&self,
rcvr_ty: ty::t,
candidates: &mut ~[Candidate])
-> Option<method_map_entry> {
-> Option<method_origin> {
// FIXME(pcwalton): Do we need to clone here?
let relevant_candidates: ~[Candidate] =
candidates.iter().map(|c| (*c).clone()).
Expand Down Expand Up @@ -926,7 +926,7 @@ impl<'a> LookupContext<'a> {
}

fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
-> method_map_entry {
-> method_origin {
// This method performs two sets of substitutions, one after the other:
// 1. Substitute values for any type/lifetime parameters from the impl and
// method declaration into the method type. This is the function type
Expand Down Expand Up @@ -1037,9 +1037,7 @@ impl<'a> LookupContext<'a> {

self.fcx.write_ty(self.callee_id, fty);
self.fcx.write_substs(self.callee_id, all_substs);
method_map_entry {
origin: candidate.origin
}
candidate.origin
}

fn construct_transformed_self_ty_for_object(
Expand Down
Loading

0 comments on commit 06e1281

Please sign in to comment.