Skip to content

Commit 3d16176

Browse files
committed
---
yaml --- r: 144109 b: refs/heads/try2 c: e524781 h: refs/heads/master i: 144107: 0f23165 v: v3
1 parent c4a7755 commit 3d16176

File tree

2 files changed

+74
-64
lines changed

2 files changed

+74
-64
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: e8d2141f03bc7fa0f66b76ff8870f35117ea2d21
8+
refs/heads/try2: e524781e5821c82e0c2031c2ad072d0345e102a5
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/typeck/coherence.rs

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,7 @@ use syntax::ast_map;
4545
use syntax::ast_util::{def_id_of_def, local_def};
4646
use syntax::codemap::{span, dummy_sp};
4747
use syntax::opt_vec;
48-
use syntax::oldvisit::{default_simple_visitor, default_visitor};
49-
use syntax::oldvisit::{mk_simple_visitor, mk_vt, visit_crate, visit_item};
50-
use syntax::oldvisit::{Visitor, SimpleVisitor};
51-
use syntax::oldvisit::{visit_mod};
48+
use syntax::visit;
5249
use syntax::parse;
5350
use util::ppaux::ty_to_str;
5451

@@ -168,31 +165,89 @@ pub struct CoherenceChecker {
168165
base_type_def_ids: @mut HashMap<def_id,def_id>,
169166
}
170167

171-
impl CoherenceChecker {
172-
pub fn check_coherence(self, crate: &Crate) {
173-
// Check implementations and traits. This populates the tables
174-
// containing the inherent methods and extension methods. It also
175-
// builds up the trait inheritance table.
176-
visit_crate(crate, ((), mk_simple_visitor(@SimpleVisitor {
177-
visit_item: |item| {
168+
struct CoherenceCheckVisitor { cc: CoherenceChecker }
169+
170+
impl visit::Visitor<()> for CoherenceCheckVisitor {
171+
fn visit_item(&mut self, item:@item, _:()) {
172+
178173
// debug!("(checking coherence) item '%s'",
179-
// self.crate_context.tcx.sess.str_of(item.ident));
174+
// self.cc.crate_context.tcx.sess.str_of(item.ident));
180175

181176
match item.node {
182177
item_impl(_, ref opt_trait, _, _) => {
183178
let opt_trait : ~[trait_ref] =
184179
opt_trait.iter()
185180
.map(|x| (*x).clone())
186181
.collect();
187-
self.check_implementation(item, opt_trait);
182+
self.cc.check_implementation(item, opt_trait);
188183
}
189184
_ => {
190185
// Nothing to do.
191186
}
192187
};
193-
},
194-
.. *default_simple_visitor()
195-
})));
188+
189+
visit::walk_item(self, item, ());
190+
}
191+
}
192+
193+
struct PrivilegedScopeVisitor { cc: CoherenceChecker }
194+
195+
impl visit::Visitor<()> for PrivilegedScopeVisitor {
196+
fn visit_item(&mut self, item:@item, _:()) {
197+
198+
match item.node {
199+
item_mod(ref module_) => {
200+
// Then visit the module items.
201+
visit::walk_mod(self, module_, ());
202+
}
203+
item_impl(_, None, ref ast_ty, _) => {
204+
if !self.cc.ast_type_is_defined_in_local_crate(ast_ty) {
205+
// This is an error.
206+
let session = self.cc.crate_context.tcx.sess;
207+
session.span_err(item.span,
208+
"cannot associate methods with a type outside the \
209+
crate the type is defined in; define and implement \
210+
a trait or new type instead");
211+
}
212+
}
213+
item_impl(_, Some(ref trait_ref), _, _) => {
214+
// `for_ty` is `Type` in `impl Trait for Type`
215+
let for_ty =
216+
ty::node_id_to_type(self.cc.crate_context.tcx,
217+
item.id);
218+
if !type_is_defined_in_local_crate(for_ty) {
219+
// This implementation is not in scope of its base
220+
// type. This still might be OK if the trait is
221+
// defined in the same crate.
222+
223+
let trait_def_id =
224+
self.cc.trait_ref_to_trait_def_id(trait_ref);
225+
226+
if trait_def_id.crate != LOCAL_CRATE {
227+
let session = self.cc.crate_context.tcx.sess;
228+
session.span_err(item.span,
229+
"cannot provide an extension implementation \
230+
for a trait not defined in this crate");
231+
}
232+
}
233+
234+
visit::walk_item(self, item, ());
235+
}
236+
_ => {
237+
visit::walk_item(self, item, ());
238+
}
239+
}
240+
}
241+
}
242+
243+
impl CoherenceChecker {
244+
pub fn check_coherence(self, crate: &Crate) {
245+
// Check implementations and traits. This populates the tables
246+
// containing the inherent methods and extension methods. It also
247+
// builds up the trait inheritance table.
248+
249+
let mut visitor = CoherenceCheckVisitor { cc: self };
250+
visit::walk_crate(&mut visitor, crate, ());
196251

197252
// Check that there are no overlapping trait instances
198253
self.check_implementation_coherence();
@@ -486,53 +541,8 @@ impl CoherenceChecker {
486541

487542
// Privileged scope checking
488543
pub fn check_privileged_scopes(self, crate: &Crate) {
489-
visit_crate(crate, ((), mk_vt(@Visitor {
490-
visit_item: |item, (_context, visitor)| {
491-
match item.node {
492-
item_mod(ref module_) => {
493-
// Then visit the module items.
494-
visit_mod(module_, item.span, item.id, ((), visitor));
495-
}
496-
item_impl(_, None, ref ast_ty, _) => {
497-
if !self.ast_type_is_defined_in_local_crate(ast_ty) {
498-
// This is an error.
499-
let session = self.crate_context.tcx.sess;
500-
session.span_err(item.span,
501-
"cannot associate methods with a type outside the \
502-
crate the type is defined in; define and implement \
503-
a trait or new type instead");
504-
}
505-
}
506-
item_impl(_, Some(ref trait_ref), _, _) => {
507-
// `for_ty` is `Type` in `impl Trait for Type`
508-
let for_ty =
509-
ty::node_id_to_type(self.crate_context.tcx,
510-
item.id);
511-
if !type_is_defined_in_local_crate(for_ty) {
512-
// This implementation is not in scope of its base
513-
// type. This still might be OK if the trait is
514-
// defined in the same crate.
515-
516-
let trait_def_id =
517-
self.trait_ref_to_trait_def_id(trait_ref);
518-
519-
if trait_def_id.crate != LOCAL_CRATE {
520-
let session = self.crate_context.tcx.sess;
521-
session.span_err(item.span,
522-
"cannot provide an extension implementation \
523-
for a trait not defined in this crate");
524-
}
525-
}
526-
527-
visit_item(item, ((), visitor));
528-
}
529-
_ => {
530-
visit_item(item, ((), visitor));
531-
}
532-
}
533-
},
534-
.. *default_visitor()
535-
})));
544+
let mut visitor = PrivilegedScopeVisitor{ cc: self };
545+
visit::walk_crate(&mut visitor, crate, ());
536546
}
537547

538548
pub fn trait_ref_to_trait_def_id(&self, trait_ref: &trait_ref) -> def_id {

0 commit comments

Comments
 (0)