Skip to content

Commit c190ed7

Browse files
committed
---
yaml --- r: 149402 b: refs/heads/try2 c: efaa1ea h: refs/heads/master v: v3
1 parent cb0d13f commit c190ed7

File tree

4 files changed

+44
-25
lines changed

4 files changed

+44
-25
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: efef078cfa378378201ab097579992b40751cfb4
8+
refs/heads/try2: efaa1ea979c60dcb6884be12dcb12ceb09dbc5bd
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/librustc/middle/trans/base.rs

Lines changed: 9 additions & 16 deletions
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 {

branches/try2/src/librustc/middle/typeck/check/vtable.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,28 @@ pub fn resolve_impl(tcx: ty::ctxt,
812812
impl_vtables.get().insert(impl_def_id, res);
813813
}
814814

815+
/// Resolve vtables for a method call after typeck has finished.
816+
/// Used by trans to monomorphize artificial method callees (e.g. drop).
817+
pub fn trans_resolve_method(tcx: ty::ctxt, id: ast::NodeId,
818+
substs: &ty::substs) -> Option<vtable_res> {
819+
let generics = ty::lookup_item_type(tcx, ast_util::local_def(id)).generics;
820+
let type_param_defs = generics.type_param_defs.borrow();
821+
if has_trait_bounds(*type_param_defs) {
822+
let vcx = VtableContext {
823+
infcx: &infer::new_infer_ctxt(tcx),
824+
param_env: &ty::construct_parameter_environment(tcx, None, [], [], [], id)
825+
};
826+
let loc_info = LocationInfo {
827+
id: id,
828+
span: tcx.map.span(id)
829+
};
830+
831+
Some(lookup_vtables(&vcx, &loc_info, *type_param_defs, substs, false))
832+
} else {
833+
None
834+
}
835+
}
836+
815837
impl<'a> visit::Visitor<()> for &'a FnCtxt {
816838
fn visit_expr(&mut self, ex: &ast::Expr, _: ()) {
817839
early_resolve_expr(ex, *self, false);

branches/try2/src/test/run-pass/issue-4252.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,34 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// ignore-test
12-
1311
trait X {
14-
fn call(&self);
12+
fn call<T>(&self, x: &T);
13+
fn default_method<T>(&self, x: &T) {
14+
println!("X::default_method {:?} {:?}", self, x);
15+
}
1516
}
1617

17-
struct Y;
18+
struct Y(int);
1819

1920
struct Z<T> {
2021
x: T
2122
}
2223

2324
impl X for Y {
24-
fn call(&self) {
25+
fn call<T>(&self, x: &T) {
26+
println!("X::call {:?} {:?}", self, x);
2527
}
2628
}
2729

30+
#[unsafe_destructor]
2831
impl<T: X> Drop for Z<T> {
2932
fn drop(&mut self) {
30-
self.x.call(); // Adding this statement causes an ICE.
33+
// These statements used to cause an ICE.
34+
self.x.call(self);
35+
self.x.default_method(self);
3136
}
3237
}
3338

3439
pub fn main() {
35-
let y = Y;
36-
let _z = Z{x: y};
40+
let _z = Z {x: Y(42)};
3741
}

0 commit comments

Comments
 (0)