Skip to content

Commit a56ec8c

Browse files
committed
auto merge of #5515 : nikomatsakis/rust/issue-5514-flexible-coherence-rules, r=pcwalton
See issue #5514 r? @pcwalton
2 parents 8aee0a6 + a1b4afe commit a56ec8c

File tree

1 file changed

+49
-46
lines changed

1 file changed

+49
-46
lines changed

src/librustc/middle/typeck/coherence.rs

+49-46
Original file line numberDiff line numberDiff line change
@@ -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.
108134
pub 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
184204
pub 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

Comments
 (0)