diff options
| author | bors <bors@rust-lang.org> | 2013-03-23 12:36:53 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-03-23 12:36:53 -0700 |
| commit | a56ec8c1342453a88be79e192a11501844375d40 (patch) | |
| tree | 438faffceaa44ab4ddeb23c6fbfa6eb920082a8c | |
| parent | 8aee0a6a2972f0c62777cb757184c01042513973 (diff) | |
| parent | a1b4afe0670fb1603b056f317a301ed527064ef5 (diff) | |
| download | rust-a56ec8c1342453a88be79e192a11501844375d40.tar.gz rust-a56ec8c1342453a88be79e192a11501844375d40.zip | |
auto merge of #5515 : nikomatsakis/rust/issue-5514-flexible-coherence-rules, r=pcwalton
See issue #5514 r? @pcwalton
| -rw-r--r-- | src/librustc/middle/typeck/coherence.rs | 95 |
1 files changed, 49 insertions, 46 deletions
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 824ac594e74..0b3eca7c07d 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -104,6 +104,32 @@ pub fn get_base_type(inference_context: @mut InferCtxt, } } +pub fn type_is_defined_in_local_crate(original_type: t) -> bool { + /*! + * + * For coherence, when we have `impl Trait for Type`, we need to + * guarantee that `Type` is "local" to the + * crate. For our purposes, this means that it must contain + * some nominal type defined in this crate. + */ + + let mut found_nominal = false; + do ty::walk_ty(original_type) |t| { + match get(t).sty { + ty_enum(def_id, _) | + ty_trait(def_id, _, _) | + ty_struct(def_id, _) => { + if def_id.crate == ast::local_crate { + found_nominal = true; + } + } + + _ => { } + } + } + return found_nominal; +} + // Returns the def ID of the base type, if there is one. pub fn get_base_type_def_id(inference_context: @mut InferCtxt, span: span, @@ -161,8 +187,7 @@ pub fn CoherenceChecker(crate_context: @mut CrateCtxt) -> CoherenceChecker { crate_context: crate_context, inference_context: new_infer_ctxt(crate_context.tcx), - base_type_def_ids: HashMap(), - privileged_implementations: HashMap() + base_type_def_ids: HashMap() } } @@ -174,11 +199,6 @@ pub struct CoherenceChecker { // definition ID. base_type_def_ids: HashMap<def_id,def_id>, - - // A set of implementations in privileged scopes; i.e. those - // implementations that are defined in the same scope as their base types. - - privileged_implementations: HashMap<node_id,()>, } pub impl CoherenceChecker { @@ -615,27 +635,11 @@ pub impl CoherenceChecker { visit_mod(module_, item.span, item.id, (), visitor); } item_impl(_, opt_trait, _, _) => { - let mut ok = false; - match self.base_type_def_ids.find( - &local_def(item.id)) { - - None => { - // Nothing to do. - } - Some(base_type_def_id) => { - // Check to see whether the implementation is - // in the same crate as its base type. - - if base_type_def_id.crate == local_crate { - // Record that this implementation is OK. - self.privileged_implementations.insert - (item.id, ()); - ok = true; - } - } - } - - if !ok { + // `for_ty` is `Type` in `impl Trait for Type` + let for_ty = + ty::node_id_to_type(self.crate_context.tcx, + item.id); + if !type_is_defined_in_local_crate(for_ty) { // This implementation is not in scope of its base // type. This still might be OK if the trait is // defined in the same crate. @@ -655,25 +659,24 @@ pub impl CoherenceChecker { implement a trait or \ new type instead"); } - _ => () - } - for opt_trait.each |trait_ref| { - // This is OK if and only if the trait was - // defined in this crate. - - let trait_def_id = - self.trait_ref_to_trait_def_id( - *trait_ref); - - if trait_def_id.crate != local_crate { - let session = self.crate_context.tcx.sess; - session.span_err(item.span, - ~"cannot provide an \ - extension \ - implementation for a \ - trait not defined in \ - this crate"); + Some(trait_ref) => { + // This is OK if and only if the trait was + // defined in this crate. + + let trait_def_id = + self.trait_ref_to_trait_def_id( + trait_ref); + + if trait_def_id.crate != local_crate { + let session = self.crate_context.tcx.sess; + session.span_err(item.span, + ~"cannot provide an \ + extension \ + implementation for a \ + trait not defined in \ + this crate"); + } } } } |
