Skip to content

Commit 06e1281

Browse files
committed
auto merge of #12403 : eddyb/rust/generic-dtors-with-bounds, r=nikomatsakis
Fix generic Drop impls with trait bounds. Fixes #4252.
2 parents 5f324aa + efaa1ea commit 06e1281

File tree

16 files changed

+122
-161
lines changed

16 files changed

+122
-161
lines changed

src/librustc/middle/astencode.rs

+6-34
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use metadata::tydecode;
2020
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
2121
RegionParameter};
2222
use metadata::tyencode;
23-
use middle::typeck::{method_origin, method_map_entry};
23+
use middle::typeck::method_origin;
2424
use middle::{ty, typeck, moves};
2525
use middle;
2626
use util::ppaux::ty_to_str;
@@ -573,35 +573,7 @@ impl tr for moves::CaptureVar {
573573
}
574574

575575
// ______________________________________________________________________
576-
// Encoding and decoding of method_map_entry
577-
578-
trait read_method_map_entry_helper {
579-
fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
580-
-> method_map_entry;
581-
}
582-
583-
fn encode_method_map_entry(ebml_w: &mut writer::Encoder, mme: method_map_entry) {
584-
ebml_w.emit_struct("method_map_entry", 3, |ebml_w| {
585-
ebml_w.emit_struct_field("origin", 1u, |ebml_w| {
586-
mme.origin.encode(ebml_w);
587-
});
588-
})
589-
}
590-
591-
impl<'a> read_method_map_entry_helper for reader::Decoder<'a> {
592-
fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
593-
-> method_map_entry {
594-
self.read_struct("method_map_entry", 3, |this| {
595-
method_map_entry {
596-
origin: this.read_struct_field("origin", 1, |this| {
597-
let method_origin: method_origin =
598-
Decodable::decode(this);
599-
method_origin.tr(xcx)
600-
})
601-
}
602-
})
603-
}
604-
}
576+
// Encoding and decoding of method_origin
605577

606578
impl tr for method_origin {
607579
fn tr(&self, xcx: @ExtendedDecodeContext) -> method_origin {
@@ -1023,11 +995,11 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
1023995
{
1024996
let method_map = maps.method_map.borrow();
1025997
let r = method_map.get().find(&id);
1026-
for &mme in r.iter() {
998+
for &origin in r.iter() {
1027999
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
10281000
ebml_w.id(id);
10291001
ebml_w.tag(c::tag_table_val, |ebml_w| {
1030-
encode_method_map_entry(ebml_w, *mme)
1002+
origin.encode(ebml_w);
10311003
})
10321004
})
10331005
}
@@ -1364,9 +1336,9 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
13641336
ty_param_defs.get().insert(id, bounds);
13651337
}
13661338
c::tag_table_method_map => {
1367-
let entry = val_dsr.read_method_map_entry(xcx);
1339+
let origin: method_origin = Decodable::decode(val_dsr);
13681340
let mut method_map = dcx.maps.method_map.borrow_mut();
1369-
method_map.get().insert(id, entry);
1341+
method_map.get().insert(id, origin.tr(xcx));
13701342
}
13711343
c::tag_table_vtable_map => {
13721344
let vtable_res =

src/librustc/middle/dead.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl MarkSymbolVisitor {
9494
span: codemap::Span) {
9595
let method_map = self.method_map.borrow();
9696
match method_map.get().find(id) {
97-
Some(&typeck::method_map_entry { origin, .. }) => {
97+
Some(&origin) => {
9898
match origin {
9999
typeck::method_static(def_id) => {
100100
match ty::provided_source(self.tcx, def_id) {

src/librustc/middle/kind.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,15 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
285285

286286
// Even though the callee_id may have been the id with
287287
// node_type_substs, e.id is correct here.
288-
ty::method_call_type_param_defs(cx.tcx, cx.method_map, e.id).expect(
289-
"non path/method call expr has type substs??")
288+
match cx.method_map.borrow().get().find(&e.id) {
289+
Some(origin) => {
290+
ty::method_call_type_param_defs(cx.tcx, *origin)
291+
}
292+
None => {
293+
cx.tcx.sess.span_bug(e.span,
294+
"non path/method call expr has type substs??");
295+
}
296+
}
290297
}
291298
};
292299
let type_param_defs = type_param_defs.borrow();

src/librustc/middle/lint.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ fn check_stability(cx: &Context, e: &ast::Expr) {
14001400
ast::ExprMethodCall(..) => {
14011401
let method_map = cx.method_map.borrow();
14021402
match method_map.get().find(&e.id) {
1403-
Some(&typeck::method_map_entry { origin, .. }) => {
1403+
Some(&origin) => {
14041404
match origin {
14051405
typeck::method_static(def_id) => {
14061406
// If this implements a trait method, get def_id

src/librustc/middle/privacy.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -790,17 +790,17 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
790790
let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
791791
match ty::get(t).sty {
792792
ty::ty_enum(_, _) | ty::ty_struct(_, _) => {
793-
let method_map = self.method_map.borrow();
794-
let entry = match method_map.get().find(&expr.id) {
793+
match self.method_map.borrow().get().find(&expr.id) {
795794
None => {
796795
self.tcx.sess.span_bug(expr.span,
797796
"method call not in \
798797
method map");
799798
}
800-
Some(entry) => entry
801-
};
802-
debug!("(privacy checking) checking impl method");
803-
self.check_method(expr.span, &entry.origin, ident);
799+
Some(origin) => {
800+
debug!("(privacy checking) checking impl method");
801+
self.check_method(expr.span, origin, ident);
802+
}
803+
}
804804
}
805805
_ => {}
806806
}

src/librustc/middle/reachable.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,7 @@ impl Visitor<()> for MarkSymbolVisitor {
149149
ast::ExprMethodCall(..) => {
150150
let method_map = self.method_map.borrow();
151151
match method_map.get().find(&expr.id) {
152-
Some(&typeck::method_map_entry {
153-
origin: typeck::method_static(def_id),
154-
..
155-
}) => {
152+
Some(&typeck::method_static(def_id)) => {
156153
if is_local(def_id) {
157154
if ReachableContext::
158155
def_id_represents_local_inlined_item(
@@ -174,8 +171,7 @@ impl Visitor<()> for MarkSymbolVisitor {
174171
Some(_) => {}
175172
None => {
176173
self.tcx.sess.span_bug(expr.span,
177-
"method call expression \
178-
not in method map?!")
174+
"method call expression not in method map?!")
179175
}
180176
}
181177
}

src/librustc/middle/trans/base.rs

+9-16
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ use middle::trans::type_of;
6565
use middle::trans::type_of::*;
6666
use middle::trans::value::Value;
6767
use middle::ty;
68+
use middle::typeck;
6869
use util::common::indenter;
6970
use util::ppaux::{Repr, ty_to_str};
7071
use util::sha2::Sha256;
@@ -535,22 +536,14 @@ pub fn get_res_dtor(ccx: @CrateContext,
535536
};
536537
if !substs.is_empty() {
537538
assert_eq!(did.krate, ast::LOCAL_CRATE);
538-
let tsubsts = ty::substs {regions: ty::ErasedRegions,
539-
self_ty: None,
540-
tps: /*bad*/ substs.to_owned() };
541-
542-
// FIXME: #4252: Generic destructors with type bounds are broken.
543-
//
544-
// Since the vtables aren't passed to `monomorphic_fn` here, generic destructors with type
545-
// bounds are broken. Sadly, the `typeck` pass isn't outputting the necessary metadata
546-
// because it does so based on method calls present in the AST. Destructor calls are not yet
547-
// known about at that stage of compilation, since `trans` handles cleanups.
548-
let (val, _) = monomorphize::monomorphic_fn(ccx,
549-
did,
550-
&tsubsts,
551-
None,
552-
None,
553-
None);
539+
let tsubsts = ty::substs {
540+
regions: ty::ErasedRegions,
541+
self_ty: None,
542+
tps: substs.to_owned()
543+
};
544+
545+
let vtables = typeck::check::vtable::trans_resolve_method(ccx.tcx, did.node, &tsubsts);
546+
let (val, _) = monomorphize::monomorphic_fn(ccx, did, &tsubsts, vtables, None, None);
554547

555548
val
556549
} else if did.krate == ast::LOCAL_CRATE {

src/librustc/middle/trans/meth.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,15 @@ pub fn trans_method_callee<'a>(
9595
bcx: &'a Block<'a>,
9696
callee_id: ast::NodeId,
9797
this: &ast::Expr,
98-
mentry: typeck::method_map_entry,
98+
origin: typeck::method_origin,
9999
arg_cleanup_scope: cleanup::ScopeId)
100100
-> Callee<'a> {
101101
let _icx = push_ctxt("meth::trans_method_callee");
102102

103-
debug!("trans_method_callee(callee_id={:?}, mentry={})",
104-
callee_id,
105-
mentry.repr(bcx.tcx()));
103+
debug!("trans_method_callee(callee_id={:?}, origin={})",
104+
callee_id, origin.repr(bcx.tcx()));
106105

107-
match mentry.origin {
106+
match origin {
108107
typeck::method_static(did) => {
109108
Callee {
110109
bcx: bcx,

src/librustc/middle/ty.rs

+12-17
Original file line numberDiff line numberDiff line change
@@ -3242,25 +3242,21 @@ pub fn expr_has_ty_params(cx: ctxt, expr: &ast::Expr) -> bool {
32423242
return node_id_has_type_params(cx, expr.id);
32433243
}
32443244

3245-
pub fn method_call_type_param_defs(tcx: ctxt,
3246-
method_map: typeck::method_map,
3247-
id: ast::NodeId)
3248-
-> Option<Rc<~[TypeParameterDef]>> {
3249-
let method_map = method_map.borrow();
3250-
method_map.get().find(&id).map(|method| {
3251-
match method.origin {
3252-
typeck::method_static(did) => {
3245+
pub fn method_call_type_param_defs(tcx: ctxt, origin: typeck::method_origin)
3246+
-> Rc<~[TypeParameterDef]> {
3247+
match origin {
3248+
typeck::method_static(did) => {
32533249
// n.b.: When we encode impl methods, the bounds
32543250
// that we encode include both the impl bounds
32553251
// and then the method bounds themselves...
32563252
ty::lookup_item_type(tcx, did).generics.type_param_defs
3257-
}
3258-
typeck::method_param(typeck::method_param {
3259-
trait_id: trt_id,
3260-
method_num: n_mth, ..}) |
3261-
typeck::method_object(typeck::method_object {
3262-
trait_id: trt_id,
3263-
method_num: n_mth, ..}) => {
3253+
}
3254+
typeck::method_param(typeck::method_param {
3255+
trait_id: trt_id,
3256+
method_num: n_mth, ..}) |
3257+
typeck::method_object(typeck::method_object {
3258+
trait_id: trt_id,
3259+
method_num: n_mth, ..}) => {
32643260
// ...trait methods bounds, in contrast, include only the
32653261
// method bounds, so we must preprend the tps from the
32663262
// trait itself. This ought to be harmonized.
@@ -3271,9 +3267,8 @@ pub fn method_call_type_param_defs(tcx: ctxt,
32713267
ty::trait_method(tcx,
32723268
trt_id,
32733269
n_mth).generics.type_param_defs()))
3274-
}
32753270
}
3276-
})
3271+
}
32773272
}
32783273

32793274
pub fn resolve_expr(tcx: ctxt, expr: &ast::Expr) -> ast::Def {

src/librustc/middle/typeck/check/demand.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ use syntax::codemap::Span;
2020

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

28-
pub fn subtype(fcx: @FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
28+
pub fn subtype(fcx: &FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
2929
suptype_with_fn(fcx, sp, true, actual, expected,
3030
|sp, a, e, s| { fcx.report_mismatched_types(sp, e, a, s) })
3131
}
3232

33-
pub fn suptype_with_fn(fcx: @FnCtxt,
33+
pub fn suptype_with_fn(fcx: &FnCtxt,
3434
sp: Span,
3535
b_is_expected: bool,
3636
ty_a: ty::t,

src/librustc/middle/typeck/check/method.rs

+13-15
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ use middle::typeck::check::{structurally_resolved_type};
9090
use middle::typeck::check::vtable;
9191
use middle::typeck::check;
9292
use middle::typeck::infer;
93-
use middle::typeck::{method_map_entry, method_origin, method_param};
93+
use middle::typeck::{method_origin, method_param};
9494
use middle::typeck::{method_static, method_object};
9595
use middle::typeck::{param_numbered, param_self, param_index};
9696
use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
@@ -133,7 +133,7 @@ pub fn lookup(
133133
deref_args: check::DerefArgs, // Whether we autopointer first.
134134
check_traits: CheckTraitsFlag, // Whether we check traits only.
135135
autoderef_receiver: AutoderefReceiverFlag)
136-
-> Option<method_map_entry> {
136+
-> Option<method_origin> {
137137
let impl_dups = @RefCell::new(HashSet::new());
138138
let lcx = LookupContext {
139139
fcx: fcx,
@@ -211,7 +211,7 @@ enum RcvrMatchCondition {
211211
}
212212

213213
impl<'a> LookupContext<'a> {
214-
fn search(&self, self_ty: ty::t) -> Option<method_map_entry> {
214+
fn search(&self, self_ty: ty::t) -> Option<method_origin> {
215215
let mut self_ty = self_ty;
216216
let mut autoderefs = 0;
217217
loop {
@@ -592,7 +592,7 @@ impl<'a> LookupContext<'a> {
592592
fn search_for_autoderefd_method(&self,
593593
self_ty: ty::t,
594594
autoderefs: uint)
595-
-> Option<method_map_entry> {
595+
-> Option<method_origin> {
596596
let (self_ty, autoadjust) =
597597
self.consider_reborrow(self_ty, autoderefs);
598598
match self.search_for_method(self_ty) {
@@ -686,9 +686,9 @@ impl<'a> LookupContext<'a> {
686686
}
687687

688688
fn search_for_autosliced_method(&self,
689-
self_ty: ty::t,
690-
autoderefs: uint)
691-
-> Option<method_map_entry> {
689+
self_ty: ty::t,
690+
autoderefs: uint)
691+
-> Option<method_origin> {
692692
/*!
693693
*
694694
* Searches for a candidate by converting things like
@@ -763,7 +763,7 @@ impl<'a> LookupContext<'a> {
763763
}
764764

765765
fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
766-
-> Option<method_map_entry> {
766+
-> Option<method_origin> {
767767
/*!
768768
*
769769
* Converts any type `T` to `&M T` where `M` is an
@@ -799,7 +799,7 @@ impl<'a> LookupContext<'a> {
799799
autoderefs: uint,
800800
mutbls: &[ast::Mutability],
801801
mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t)
802-
-> Option<method_map_entry> {
802+
-> Option<method_origin> {
803803
// This is hokey. We should have mutability inference as a
804804
// variable. But for now, try &const, then &, then &mut:
805805
let region =
@@ -823,7 +823,7 @@ impl<'a> LookupContext<'a> {
823823
}
824824

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

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

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

10381038
self.fcx.write_ty(self.callee_id, fty);
10391039
self.fcx.write_substs(self.callee_id, all_substs);
1040-
method_map_entry {
1041-
origin: candidate.origin
1042-
}
1040+
candidate.origin
10431041
}
10441042

10451043
fn construct_transformed_self_ty_for_object(

0 commit comments

Comments
 (0)