Skip to content

Commit 3770221

Browse files
committed
Start of data structure cleanup for trait system. Get rid of CoherenceInfo, make trait_impls less bogus.
1 parent 874eb19 commit 3770221

File tree

7 files changed

+50
-105
lines changed

7 files changed

+50
-105
lines changed

src/librustc/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
396396
ebml_w: &mut writer::Encoder,
397397
exp: &middle::resolve::Export2)
398398
-> bool {
399-
match ecx.tcx.base_impls.find(&exp.def_id) {
399+
match ecx.tcx.inherent_impls.find(&exp.def_id) {
400400
Some(implementations) => {
401401
for implementations.iter().advance |&base_impl| {
402402
for base_impl.methods.iter().advance |&m| {

src/librustc/middle/trans/meth.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ pub fn trans_method_callee(bcx: block,
162162
let self_ty = node_id_type(bcx, this.id);
163163
// <impl_id> is the ID of the implementation of
164164
// trait <trait_id> for type <self_ty>
165-
let impl_id = ty::get_impl_id(tcx, trait_id, self_ty);
165+
let impl_id = ty::bogus_get_impl_id_from_ty(tcx, trait_id, self_ty);
166166
// Get the supertrait's methods
167167
let supertrait_method_def_ids = ty::trait_method_def_ids(tcx, trait_id);
168168
// Make sure to fail with a readable error message if

src/librustc/middle/ty.rs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,13 @@ struct ctxt_ {
303303
// A method will be in this list if and only if it is a destructor.
304304
destructors: @mut HashSet<ast::def_id>,
305305

306-
// Maps a trait onto a mapping from self-ty to impl
307-
trait_impls: @mut HashMap<ast::def_id, @mut HashMap<t, @Impl>>,
306+
// Maps a trait onto a list of impls of that trait.
307+
trait_impls: @mut HashMap<ast::def_id, @mut ~[@Impl]>,
308308

309-
// Maps a base type to its impl
310-
base_impls: @mut HashMap<ast::def_id, @mut ~[@Impl]>,
309+
// Maps a def_id of a type to a list of its inherent impls.
310+
// Contains implementations of methods that are inherent to a type.
311+
// Methods in these implementations don't need to be exported.
312+
inherent_impls: @mut HashMap<ast::def_id, @mut ~[@Impl]>,
311313

312314
// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
313315
// present in this set can be warned about.
@@ -908,7 +910,7 @@ pub fn mk_ctxt(s: session::Session,
908910
destructor_for_type: @mut HashMap::new(),
909911
destructors: @mut HashSet::new(),
910912
trait_impls: @mut HashMap::new(),
911-
base_impls: @mut HashMap::new(),
913+
inherent_impls: @mut HashMap::new(),
912914
used_unsafe: @mut HashSet::new(),
913915
used_mut_nodes: @mut HashSet::new(),
914916
}
@@ -3596,20 +3598,6 @@ pub fn trait_method(cx: ctxt, trait_did: ast::def_id, idx: uint) -> @Method {
35963598
}
35973599

35983600

3599-
pub fn add_base_impl(cx: ctxt, base_def_id: def_id, implementation: @Impl) {
3600-
let implementations;
3601-
match cx.base_impls.find(&base_def_id) {
3602-
None => {
3603-
implementations = @mut ~[];
3604-
cx.base_impls.insert(base_def_id, implementations);
3605-
}
3606-
Some(&existing) => {
3607-
implementations = existing;
3608-
}
3609-
}
3610-
implementations.push(implementation);
3611-
}
3612-
36133601
pub fn trait_methods(cx: ctxt, trait_did: ast::def_id) -> @~[@Method] {
36143602
match cx.trait_methods_cache.find(&trait_did) {
36153603
Some(&methods) => methods,
@@ -4375,16 +4363,25 @@ pub fn count_traits_and_supertraits(tcx: ctxt,
43754363
return total;
43764364
}
43774365

4378-
// Given a trait and a type, returns the impl of that type
4379-
pub fn get_impl_id(tcx: ctxt, trait_id: def_id, self_ty: t) -> def_id {
4366+
// Given a trait and a type, returns the impl of that type.
4367+
// This is broken, of course, by parametric impls. This used to use
4368+
// a table specifically for this mapping, but I removed that table.
4369+
// This is only used when calling a supertrait method from a default method,
4370+
// and should go away once I fix how that works. -sully
4371+
pub fn bogus_get_impl_id_from_ty(tcx: ctxt,
4372+
trait_id: def_id, self_ty: t) -> def_id {
43804373
match tcx.trait_impls.find(&trait_id) {
4381-
Some(ty_to_impl) => match ty_to_impl.find(&self_ty) {
4382-
Some(the_impl) => the_impl.did,
4383-
None => // try autoderef!
4384-
match deref(tcx, self_ty, false) {
4385-
Some(some_ty) => get_impl_id(tcx, trait_id, some_ty.ty),
4386-
None => tcx.sess.bug("get_impl_id: no impl of trait for \
4387-
this type")
4374+
Some(ty_to_impl) => {
4375+
for ty_to_impl.iter().advance |imp| {
4376+
let impl_ty = tcx.tcache.get_copy(&imp.did);
4377+
if impl_ty.ty == self_ty { return imp.did; }
4378+
}
4379+
// try autoderef!
4380+
match deref(tcx, self_ty, false) {
4381+
Some(some_ty) =>
4382+
bogus_get_impl_id_from_ty(tcx, trait_id, some_ty.ty),
4383+
None => tcx.sess.bug("get_impl_id: no impl of trait for \
4384+
this type")
43884385
}
43894386
},
43904387
None => tcx.sess.bug("get_impl_id: trait isn't in trait_impls")

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,7 @@ impl<'self> LookupContext<'self> {
330330
for opt_applicable_traits.iter().advance |applicable_traits| {
331331
for applicable_traits.iter().advance |trait_did| {
332332
// Look for explicit implementations.
333-
let opt_impl_infos =
334-
self.fcx.ccx.coherence_info.extension_methods.find(trait_did);
333+
let opt_impl_infos = self.tcx().trait_impls.find(trait_did);
335334
for opt_impl_infos.iter().advance |impl_infos| {
336335
for impl_infos.iter().advance |impl_info| {
337336
self.push_candidates_from_impl(
@@ -517,8 +516,7 @@ impl<'self> LookupContext<'self> {
517516
}
518517

519518
pub fn push_inherent_impl_candidates_for_type(&self, did: def_id) {
520-
let opt_impl_infos =
521-
self.fcx.ccx.coherence_info.inherent_methods.find(&did);
519+
let opt_impl_infos = self.tcx().inherent_impls.find(&did);
522520
for opt_impl_infos.iter().advance |impl_infos| {
523521
for impl_infos.iter().advance |impl_info| {
524522
self.push_candidates_from_impl(

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ fn lookup_vtable(vcx: &VtableContext,
260260

261261
let mut impls_seen = HashSet::new();
262262

263-
match vcx.ccx.coherence_info.extension_methods.find(&trait_ref.def_id) {
263+
match tcx.trait_impls.find(&trait_ref.def_id) {
264264
None => {
265265
// Nothing found. Continue.
266266
}

src/librustc/middle/typeck/coherence.rs

Lines changed: 20 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -159,23 +159,6 @@ pub fn method_to_MethodInfo(ast_method: @method) -> @MethodInfo {
159159
}
160160
}
161161

162-
pub struct CoherenceInfo {
163-
// Contains implementations of methods that are inherent to a type.
164-
// Methods in these implementations don't need to be exported.
165-
inherent_methods: @mut HashMap<def_id, @mut ~[@Impl]>,
166-
167-
// Contains implementations of methods associated with a trait. For these,
168-
// the associated trait must be imported at the call site.
169-
extension_methods: @mut HashMap<def_id, @mut ~[@Impl]>,
170-
}
171-
172-
pub fn CoherenceInfo() -> CoherenceInfo {
173-
CoherenceInfo {
174-
inherent_methods: @mut HashMap::new(),
175-
extension_methods: @mut HashMap::new(),
176-
}
177-
}
178-
179162
pub fn CoherenceChecker(crate_context: @mut CrateCtxt) -> CoherenceChecker {
180163
CoherenceChecker {
181164
crate_context: crate_context,
@@ -287,7 +270,7 @@ impl CoherenceChecker {
287270
implementation_opt = Some(implementation);
288271
}
289272

290-
self.add_trait_method(trait_ref.def_id, implementation_opt.get());
273+
self.add_trait_impl(trait_ref.def_id, implementation_opt.get());
291274
}
292275

293276
// Add the implementation to the mapping from implementation to base
@@ -313,8 +296,7 @@ impl CoherenceChecker {
313296
}
314297
}
315298

316-
self.add_inherent_method(base_type_def_id,
317-
implementation);
299+
self.add_inherent_impl(base_type_def_id, implementation);
318300
}
319301

320302
self.base_type_def_ids.insert(local_def(item.id),
@@ -418,35 +400,33 @@ impl CoherenceChecker {
418400
}
419401
}
420402

421-
pub fn add_inherent_method(&self,
422-
base_def_id: def_id,
423-
implementation: @Impl) {
403+
pub fn add_inherent_impl(&self,
404+
base_def_id: def_id,
405+
implementation: @Impl) {
406+
let tcx = self.crate_context.tcx;
424407
let implementation_list;
425-
match self.crate_context.coherence_info.inherent_methods
426-
.find(&base_def_id) {
408+
match tcx.inherent_impls.find(&base_def_id) {
427409
None => {
428410
implementation_list = @mut ~[];
429-
self.crate_context.coherence_info.inherent_methods
430-
.insert(base_def_id, implementation_list);
411+
tcx.inherent_impls.insert(base_def_id, implementation_list);
431412
}
432413
Some(&existing_implementation_list) => {
433414
implementation_list = existing_implementation_list;
434415
}
435416
}
436417

437418
implementation_list.push(implementation);
438-
439-
ty::add_base_impl(self.crate_context.tcx, base_def_id, implementation);
440419
}
441420

442-
pub fn add_trait_method(&self, trait_id: def_id, implementation: @Impl) {
421+
pub fn add_trait_impl(&self,
422+
base_def_id: def_id,
423+
implementation: @Impl) {
424+
let tcx = self.crate_context.tcx;
443425
let implementation_list;
444-
match self.crate_context.coherence_info.extension_methods
445-
.find(&trait_id) {
426+
match tcx.trait_impls.find(&base_def_id) {
446427
None => {
447428
implementation_list = @mut ~[];
448-
self.crate_context.coherence_info.extension_methods
449-
.insert(trait_id, implementation_list);
429+
tcx.trait_impls.insert(base_def_id, implementation_list);
450430
}
451431
Some(&existing_implementation_list) => {
452432
implementation_list = existing_implementation_list;
@@ -457,8 +437,7 @@ impl CoherenceChecker {
457437
}
458438

459439
pub fn check_implementation_coherence(&self) {
460-
let coherence_info = &self.crate_context.coherence_info;
461-
for coherence_info.extension_methods.each_key |&trait_id| {
440+
for self.crate_context.tcx.trait_impls.each_key |&trait_id| {
462441
self.check_implementation_coherence_of(trait_id);
463442
}
464443
}
@@ -472,8 +451,6 @@ impl CoherenceChecker {
472451

473452
// "We have an impl of trait <trait_def_id> for type <polytype_a>,
474453
// and that impl is <implementation_a>"
475-
self.add_impl_for_trait(trait_def_id, polytype_a.ty,
476-
implementation_a);
477454
do self.iter_impls_of_trait(trait_def_id) |b| {
478455
let implementation_b = b;
479456

@@ -494,32 +471,8 @@ impl CoherenceChecker {
494471
}
495472
}
496473

497-
// Adds an impl of trait trait_t for self type self_t; that impl
498-
// is the_impl
499-
pub fn add_impl_for_trait(&self,
500-
trait_t: def_id,
501-
self_t: t,
502-
the_impl: @Impl) {
503-
debug!("Adding impl %? of %? for %s",
504-
the_impl.did, trait_t,
505-
ty_to_str(self.crate_context.tcx, self_t));
506-
match self.crate_context.tcx.trait_impls.find(&trait_t) {
507-
None => {
508-
let m = @mut HashMap::new();
509-
m.insert(self_t, the_impl);
510-
self.crate_context.tcx.trait_impls.insert(trait_t, m);
511-
}
512-
Some(&m) => {
513-
m.insert(self_t, the_impl);
514-
}
515-
}
516-
}
517-
518474
pub fn iter_impls_of_trait(&self, trait_def_id: def_id, f: &fn(@Impl)) {
519-
let coherence_info = &self.crate_context.coherence_info;
520-
let extension_methods = &*coherence_info.extension_methods;
521-
522-
match extension_methods.find(&trait_def_id) {
475+
match self.crate_context.tcx.trait_impls.find(&trait_def_id) {
523476
Some(impls) => {
524477
for impls.iter().advance |&im| {
525478
f(im);
@@ -874,7 +827,7 @@ impl CoherenceChecker {
874827
..*implementation
875828
};
876829

877-
self.add_trait_method(trait_ref.def_id, implementation);
830+
self.add_trait_impl(trait_ref.def_id, implementation);
878831
}
879832

880833
// Add the implementation to the mapping from implementation to base
@@ -887,8 +840,8 @@ impl CoherenceChecker {
887840
// inherent methods apply to `impl Type` but not
888841
// `impl Trait for Type`:
889842
if associated_traits.is_none() {
890-
self.add_inherent_method(base_type_def_id,
891-
implementation);
843+
self.add_inherent_impl(base_type_def_id,
844+
implementation);
892845
}
893846

894847
self.base_type_def_ids.insert(implementation.did,
@@ -922,12 +875,11 @@ impl CoherenceChecker {
922875
//
923876

924877
pub fn populate_destructor_table(&self) {
925-
let coherence_info = &self.crate_context.coherence_info;
926878
let tcx = self.crate_context.tcx;
927879
let drop_trait = match tcx.lang_items.drop_trait() {
928880
Some(id) => id, None => { return }
929881
};
930-
let impls_opt = coherence_info.extension_methods.find(&drop_trait);
882+
let impls_opt = tcx.trait_impls.find(&drop_trait);
931883

932884
let impls;
933885
match impls_opt {

src/librustc/middle/typeck/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ pub struct CrateCtxt {
192192
trait_map: resolve::TraitMap,
193193
method_map: method_map,
194194
vtable_map: vtable_map,
195-
coherence_info: coherence::CoherenceInfo,
196195
tcx: ty::ctxt
197196
}
198197

@@ -415,7 +414,6 @@ pub fn check_crate(tcx: ty::ctxt,
415414
trait_map: trait_map,
416415
method_map: @mut HashMap::new(),
417416
vtable_map: @mut HashMap::new(),
418-
coherence_info: coherence::CoherenceInfo(),
419417
tcx: tcx
420418
};
421419

0 commit comments

Comments
 (0)