Skip to content

Commit 3826485

Browse files
committed
---
yaml --- r: 51610 b: refs/heads/incoming c: a56ec8c h: refs/heads/master v: v3
1 parent 1a7c4b1 commit 3826485

File tree

2 files changed

+50
-47
lines changed

2 files changed

+50
-47
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: 8eb2bab100b42f0ba751552d8eff00eb2134c55a
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/incoming: 8aee0a6a2972f0c62777cb757184c01042513973
9+
refs/heads/incoming: a56ec8c1342453a88be79e192a11501844375d40
1010
refs/heads/dist-snap: 8b98e5a296d95c5e832db0756828e5bec31c6f50
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/incoming/src/librustc/middle/typeck/coherence.rs

Lines changed: 49 additions & 46 deletions
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)