Skip to content

Commit 0f663a0

Browse files
committed
---
yaml --- r: 22335 b: refs/heads/snap-stage3 c: 1b73214 h: refs/heads/master i: 22333: 130bf1a 22331: 318e7ca 22327: b13adb6 22319: e0aee4c 22303: f5641a6 22271: 04090e8 v: v3
1 parent 6ea7443 commit 0f663a0

File tree

5 files changed

+137
-36
lines changed

5 files changed

+137
-36
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: e430a699f2c60890d9b86069fd0c68a70ece7120
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: c56a7e5c25c2a411ba119f3a17bfa6db0b1722ed
4+
refs/heads/snap-stage3: 1b732145ec569cd67e2a5d0cc4dd37d5cd60c961
55
refs/heads/try: ffbe0e0e00374358b789b0037bcb3a577cd218be
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/rustc/middle/resolve.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4181,9 +4181,9 @@ impl Resolver {
41814181
}
41824182
41834183
return self.resolve_identifier(path.idents.last(),
4184-
namespace,
4185-
check_ribs,
4186-
path.span);
4184+
namespace,
4185+
check_ribs,
4186+
path.span);
41874187
}
41884188
41894189
fn resolve_identifier(identifier: ident,

branches/snap-stage3/src/rustc/middle/typeck/check/vtable.rs

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ fn lookup_vtables(fcx: @fn_ctxt,
5151
match *bound {
5252
ty::bound_trait(i_ty) => {
5353
let i_ty = ty::subst(tcx, substs, i_ty);
54-
match lookup_vtable(fcx, expr, *ty, i_ty, allow_unsafe,
55-
is_early) {
54+
match lookup_vtable_covariant(fcx, expr, *ty, i_ty,
55+
allow_unsafe, is_early) {
5656
Some(vtable) => result.push(vtable),
5757
None => {
5858
fcx.tcx().sess.span_fatal(
@@ -91,28 +91,75 @@ fn relate_trait_tys(fcx: @fn_ctxt, expr: @ast::expr,
9191
demand::suptype(fcx, expr.span, exp_trait_ty, act_trait_ty)
9292
}
9393

94-
/*
95-
Look up the vtable to use when treating an item of type <t>
96-
as if it has type <trait_ty>
97-
*/
98-
fn lookup_vtable(fcx: @fn_ctxt,
99-
expr: @ast::expr,
100-
ty: ty::t,
101-
trait_ty: ty::t,
102-
allow_unsafe: bool,
103-
is_early: bool)
104-
-> Option<vtable_origin>
105-
{
94+
// Look up the vtable to use when treating an item of type `t` as if it has
95+
// type `trait_ty`. This does allow subtraits.
96+
fn lookup_vtable_covariant(fcx: @fn_ctxt,
97+
expr: @ast::expr,
98+
ty: ty::t,
99+
trait_ty: ty::t,
100+
allow_unsafe: bool,
101+
is_early: bool)
102+
-> Option<vtable_origin> {
103+
let worklist = dvec::DVec();
104+
worklist.push(trait_ty);
105+
while worklist.len() > 0 {
106+
let trait_ty = worklist.pop();
107+
let result = lookup_vtable_invariant(fcx, expr, ty, trait_ty,
108+
allow_unsafe, is_early);
109+
if result.is_some() {
110+
return result;
111+
}
112+
113+
// Add subtraits to the worklist, if applicable.
114+
match ty::get(trait_ty).sty {
115+
ty::ty_trait(trait_id, _, _) => {
116+
let table = fcx.ccx.coherence_info.supertrait_to_subtraits;
117+
match table.find(trait_id) {
118+
None => {}
119+
Some(subtraits) => {
120+
for subtraits.each |subtrait_id| {
121+
// XXX: This is wrong; subtraits should themselves
122+
// have substs.
123+
let substs =
124+
{ self_r: None, self_ty: None, tps: ~[] };
125+
let trait_ty = ty::mk_trait(fcx.ccx.tcx,
126+
*subtrait_id,
127+
substs,
128+
ty::vstore_box);
129+
worklist.push(trait_ty);
130+
}
131+
}
132+
}
133+
}
134+
_ => {
135+
fcx.ccx.tcx.sess.impossible_case(expr.span,
136+
"lookup_vtable_covariant: \
137+
non-trait in worklist");
138+
}
139+
}
140+
}
106141

107-
debug!("lookup_vtable(ty=%s, trait_ty=%s)",
142+
return None;
143+
}
144+
145+
// Look up the vtable to use when treating an item of type `t` as if it has
146+
// type `trait_ty`. This does not allow subtraits.
147+
fn lookup_vtable_invariant(fcx: @fn_ctxt,
148+
expr: @ast::expr,
149+
ty: ty::t,
150+
trait_ty: ty::t,
151+
allow_unsafe: bool,
152+
is_early: bool)
153+
-> Option<vtable_origin> {
154+
debug!("lookup_vtable_invariant(ty=%s, trait_ty=%s)",
108155
fcx.infcx().ty_to_str(ty), fcx.inh.infcx.ty_to_str(trait_ty));
109156
let _i = indenter();
110157

111158
let tcx = fcx.ccx.tcx;
112159
let (trait_id, trait_substs) = match ty::get(trait_ty).sty {
113160
ty::ty_trait(did, substs, _) => (did, substs),
114161
_ => tcx.sess.impossible_case(expr.span,
115-
"lookup_vtable: \
162+
"lookup_vtable_invariant: \
116163
don't know how to handle a non-trait")
117164
};
118165
let ty = match fixup_ty(fcx, expr, ty, is_early) {
@@ -150,7 +197,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
150197
}
151198
_ => tcx.sess.impossible_case(
152199
expr.span,
153-
"lookup_vtable: in loop, \
200+
"lookup_vtable_invariant: in loop, \
154201
don't know how to handle a non-trait ity")
155202
}
156203
n_bound += 1u;
@@ -462,24 +509,25 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
462509
let target_ty = fcx.expr_ty(ex);
463510
match ty::get(target_ty).sty {
464511
ty::ty_trait(*) => {
465-
/*
466-
Look up vtables for the type we're casting to,
467-
passing in the source and target type
468-
*/
512+
// Look up vtables for the type we're casting to, passing in the
513+
// source and target type.
514+
//
515+
// XXX: This is invariant and shouldn't be. --pcw
516+
469517
let ty = fcx.expr_ty(src);
470-
let vtable_opt = lookup_vtable(fcx, ex, ty, target_ty, true,
471-
is_early);
518+
let vtable_opt = lookup_vtable_invariant(fcx, ex, ty, target_ty,
519+
true, is_early);
472520
match vtable_opt {
473521
None => {
474522
// Try the new-style boxed trait; "@int as @Trait".
475523
let mut err = false;
476524
let ty = structurally_resolved_type(fcx, ex.span, ty);
477525
match ty::get(ty).sty {
478526
ty::ty_box(boxed_ty) => {
479-
let vtable_opt = lookup_vtable(fcx, ex,
480-
boxed_ty.ty,
481-
target_ty, true,
482-
is_early);
527+
let vtable_opt =
528+
lookup_vtable_invariant(fcx, ex, boxed_ty.ty,
529+
target_ty, true,
530+
is_early);
483531
match vtable_opt {
484532
Some(vtable) => {
485533
/*

branches/snap-stage3/src/rustc/middle/typeck/coherence.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,16 @@ struct CoherenceInfo {
126126
// Contains implementations of methods associated with a trait. For these,
127127
// the associated trait must be imported at the call site.
128128
extension_methods: HashMap<def_id,@DVec<@Impl>>,
129+
130+
// A mapping from a supertrait to its subtraits.
131+
supertrait_to_subtraits: HashMap<def_id,@DVec<def_id>>
129132
}
130133

131134
fn CoherenceInfo() -> CoherenceInfo {
132135
CoherenceInfo {
133136
inherent_methods: HashMap(),
134-
extension_methods: HashMap()
137+
extension_methods: HashMap(),
138+
supertrait_to_subtraits: HashMap()
135139
}
136140
}
137141

@@ -161,7 +165,6 @@ struct CoherenceChecker {
161165
}
162166

163167
impl CoherenceChecker {
164-
165168
// Create a mapping containing a MethodInfo for every provided
166169
// method in every trait.
167170
fn build_provided_methods_map(crate: @crate) {
@@ -225,9 +228,9 @@ impl CoherenceChecker {
225228
}
226229

227230
fn check_coherence(crate: @crate) {
228-
229-
// Check implementations. This populates the tables containing the
230-
// inherent methods and extension methods.
231+
// Check implementations and traits. This populates the tables
232+
// containing the inherent methods and extension methods. It also
233+
// builds up the trait inheritance table.
231234
visit_crate(*crate, (), mk_simple_visitor(@{
232235
visit_item: |item| {
233236
debug!("(checking coherence) item '%s'",
@@ -240,6 +243,9 @@ impl CoherenceChecker {
240243
item_class(struct_def, _) => {
241244
self.check_implementation(item, struct_def.traits);
242245
}
246+
item_trait(_, supertraits, _) => {
247+
self.register_inherited_trait(item, supertraits);
248+
}
243249
_ => {
244250
// Nothing to do.
245251
}
@@ -324,6 +330,27 @@ impl CoherenceChecker {
324330
}
325331
}
326332

333+
fn register_inherited_trait(item: @item, supertraits: ~[@trait_ref]) {
334+
// XXX: This is wrong. We need to support substitutions; e.g.
335+
// trait Foo : Bar<int>.
336+
let supertrait_to_subtraits =
337+
self.crate_context.coherence_info.supertrait_to_subtraits;
338+
let subtrait_id = local_def(item.id);
339+
for supertraits.each |supertrait| {
340+
let supertrait_id = self.trait_ref_to_trait_def_id(*supertrait);
341+
match supertrait_to_subtraits.find(supertrait_id) {
342+
None => {
343+
let new_vec = @dvec::DVec();
344+
new_vec.push(subtrait_id);
345+
supertrait_to_subtraits.insert(supertrait_id, new_vec);
346+
}
347+
Some(existing_vec) => {
348+
existing_vec.push(subtrait_id);
349+
}
350+
}
351+
}
352+
}
353+
327354
fn add_inherent_method(base_def_id: def_id, implementation: @Impl) {
328355
let implementation_list;
329356
match self.crate_context.coherence_info.inherent_methods
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
trait Foo {
2+
fn f();
3+
}
4+
5+
trait Bar : Foo {
6+
fn g();
7+
}
8+
9+
struct A {
10+
x: int
11+
}
12+
13+
impl A : Bar {
14+
fn g() { io::println("in g"); }
15+
fn f() { io::println("in f"); }
16+
}
17+
18+
fn h<T:Foo>(a: &T) {
19+
a.f();
20+
}
21+
22+
fn main() {
23+
let a = A { x: 3 };
24+
h(&a);
25+
}
26+

0 commit comments

Comments
 (0)