@@ -104,6 +104,32 @@ pub fn get_base_type(inference_context: @mut InferCtxt,
104
104
}
105
105
}
106
106
107
+ pub fn type_is_defined_in_local_crate( original_type : t ) -> bool {
108
+ /*!
109
+ *
110
+ * For coherence, when we have `impl Trait for Type`, we need to
111
+ * guarantee that `Type` is "local" to the
112
+ * crate. For our purposes, this means that it must contain
113
+ * some nominal type defined in this crate.
114
+ */
115
+
116
+ let mut found_nominal = false ;
117
+ do ty:: walk_ty ( original_type) |t| {
118
+ match get ( t) . sty {
119
+ ty_enum( def_id, _) |
120
+ ty_trait( def_id, _, _) |
121
+ ty_struct( def_id, _) => {
122
+ if def_id. crate == ast:: local_crate {
123
+ found_nominal = true ;
124
+ }
125
+ }
126
+
127
+ _ => { }
128
+ }
129
+ }
130
+ return found_nominal;
131
+ }
132
+
107
133
// Returns the def ID of the base type, if there is one.
108
134
pub fn get_base_type_def_id( inference_context : @mut InferCtxt ,
109
135
span : span ,
@@ -161,8 +187,7 @@ pub fn CoherenceChecker(crate_context: @mut CrateCtxt) -> CoherenceChecker {
161
187
crate_context: crate_context,
162
188
inference_context: new_infer_ctxt(crate_context.tcx),
163
189
164
- base_type_def_ids: HashMap(),
165
- privileged_implementations: HashMap()
190
+ base_type_def_ids: HashMap()
166
191
}
167
192
}
168
193
@@ -174,11 +199,6 @@ pub struct CoherenceChecker {
174
199
// definition ID.
175
200
176
201
base_type_def_ids: HashMap<def_id,def_id>,
177
-
178
- // A set of implementations in privileged scopes; i.e. those
179
- // implementations that are defined in the same scope as their base types.
180
-
181
- privileged_implementations: HashMap<node_id,()>,
182
202
}
183
203
184
204
pub impl CoherenceChecker {
@@ -615,27 +635,11 @@ pub impl CoherenceChecker {
615
635
visit_mod( module_, item. span, item. id, ( ) , visitor) ;
616
636
}
617
637
item_impl( _, opt_trait, _, _) => {
618
- let mut ok = false;
619
- match self . base_type_def_ids. find(
620
- & local_def( item. id) ) {
621
-
622
- None => {
623
- // Nothing to do.
624
- }
625
- Some ( base_type_def_id) => {
626
- // Check to see whether the implementation is
627
- // in the same crate as its base type.
628
-
629
- if base_type_def_id. crate == local_crate {
630
- // Record that this implementation is OK.
631
- self. privileged_implementations. insert
632
- ( item. id, ( ) ) ;
633
- ok = true;
634
- }
635
- }
636
- }
637
-
638
- if !ok {
638
+ // `for_ty` is `Type` in `impl Trait for Type`
639
+ let for_ty =
640
+ ty:: node_id_to_type( self . crate_context. tcx,
641
+ item. id) ;
642
+ if !type_is_defined_in_local_crate( for_ty) {
639
643
// This implementation is not in scope of its base
640
644
// type. This still might be OK if the trait is
641
645
// defined in the same crate.
@@ -655,25 +659,24 @@ pub impl CoherenceChecker {
655
659
implement a trait or \
656
660
new type instead") ;
657
661
}
658
- _ => ( )
659
- }
660
662
661
- for opt_trait. each |trait_ref| {
662
- // This is OK if and only if the trait was
663
- // defined in this crate.
664
-
665
- let trait_def_id =
666
- self . trait_ref_to_trait_def_id(
667
- * trait_ref) ;
668
-
669
- if trait_def_id. crate != local_crate {
670
- let session = self . crate_context. tcx. sess;
671
- session. span_err( item. span,
672
- ~"cannot provide an \
673
- extension \
674
- implementation for a \
675
- trait not defined in \
676
- this crate") ;
663
+ Some ( trait_ref) => {
664
+ // This is OK if and only if the trait was
665
+ // defined in this crate.
666
+
667
+ let trait_def_id =
668
+ self . trait_ref_to_trait_def_id(
669
+ trait_ref) ;
670
+
671
+ if trait_def_id. crate != local_crate {
672
+ let session = self . crate_context. tcx. sess;
673
+ session. span_err( item. span,
674
+ ~"cannot provide an \
675
+ extension \
676
+ implementation for a \
677
+ trait not defined in \
678
+ this crate") ;
679
+ }
677
680
}
678
681
}
679
682
}
0 commit comments