@@ -104,6 +104,32 @@ pub fn get_base_type(inference_context: @mut InferCtxt,
104104 }
105105}
106106
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+
107133// Returns the def ID of the base type, if there is one.
108134pub fn get_base_type_def_id( inference_context : @mut InferCtxt ,
109135 span : span ,
@@ -161,8 +187,7 @@ pub fn CoherenceChecker(crate_context: @mut CrateCtxt) -> CoherenceChecker {
161187 crate_context: crate_context,
162188 inference_context: new_infer_ctxt(crate_context.tcx),
163189
164- base_type_def_ids: HashMap(),
165- privileged_implementations: HashMap()
190+ base_type_def_ids: HashMap()
166191 }
167192}
168193
@@ -174,11 +199,6 @@ pub struct CoherenceChecker {
174199 // definition ID.
175200
176201 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,()>,
182202}
183203
184204pub impl CoherenceChecker {
@@ -615,27 +635,11 @@ pub impl CoherenceChecker {
615635 visit_mod( module_, item. span, item. id, ( ) , visitor) ;
616636 }
617637 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) {
639643 // This implementation is not in scope of its base
640644 // type. This still might be OK if the trait is
641645 // defined in the same crate.
@@ -655,25 +659,24 @@ pub impl CoherenceChecker {
655659 implement a trait or \
656660 new type instead") ;
657661 }
658- _ => ( )
659- }
660662
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+ }
677680 }
678681 }
679682 }
0 commit comments