about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMasaki Hara <ackie.h.gmai@gmail.com>2017-08-01 12:37:11 +0430
committerNiko Matsakis <niko@alum.mit.edu>2017-09-05 12:19:35 -0400
commit099bb1ba8a60dff6e51b1325bf746ec6c5eee2a3 (patch)
tree66444af42ba1b45fb5a20365dfbe0d3f91bde820
parent4d503b0c742b46748012180ae016dc0c6530ea80 (diff)
downloadrust-099bb1ba8a60dff6e51b1325bf746ec6c5eee2a3.tar.gz
rust-099bb1ba8a60dff6e51b1325bf746ec6c5eee2a3.zip
Fix misdetection of upstream intercrate ambiguity.
-rw-r--r--src/librustc/traits/select.rs21
-rw-r--r--src/test/compile-fail/coherence-overlap-issue-23516-inherent.rs2
-rw-r--r--src/test/compile-fail/coherence-overlap-issue-23516.rs2
3 files changed, 15 insertions, 10 deletions
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 693b9c147c2..07b64e3c221 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -31,7 +31,7 @@ use super::{VtableImplData, VtableObjectData, VtableBuiltinData, VtableGenerator
 use super::util;
 
 use dep_graph::{DepNodeIndex, DepKind};
-use hir::def_id::DefId;
+use hir::def_id::{DefId, LOCAL_CRATE};
 use infer;
 use infer::{InferCtxt, InferOk, TypeFreshener};
 use ty::subst::{Kind, Subst, Substs};
@@ -1069,13 +1069,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
                 let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
                 let self_ty = trait_ref.self_ty();
-                let cause = IntercrateAmbiguityCause::UpstreamCrateUpdate {
-                    trait_desc: trait_ref.to_string(),
-                    self_desc: if self_ty.has_concrete_skeleton() {
-                        Some(self_ty.to_string())
-                    } else {
-                        None
-                    },
+                let trait_desc = trait_ref.to_string();
+                let self_desc = if self_ty.has_concrete_skeleton() {
+                    Some(self_ty.to_string())
+                } else {
+                    None
+                };
+                let cause = if
+                    trait_ref.def_id.krate != LOCAL_CRATE &&
+                    !self.tcx().has_attr(trait_ref.def_id, "fundamental") {
+                    IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc }
+                } else {
+                    IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
                 };
                 self.intercrate_ambiguity_causes.push(cause);
             }
diff --git a/src/test/compile-fail/coherence-overlap-issue-23516-inherent.rs b/src/test/compile-fail/coherence-overlap-issue-23516-inherent.rs
index 9b8ad51c5ff..355af60710a 100644
--- a/src/test/compile-fail/coherence-overlap-issue-23516-inherent.rs
+++ b/src/test/compile-fail/coherence-overlap-issue-23516-inherent.rs
@@ -19,7 +19,7 @@ struct Cake<X>(X);
 impl<T:Sugar> Cake<T> { fn dummy(&self) { } }
 //~^ ERROR E0592
 //~| NOTE duplicate definitions for `dummy`
-//~| NOTE upstream crates may add new impl of trait `Sugar` for type `std::boxed::Box<_>`
+//~| NOTE downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`
 impl<U:Sugar> Cake<Box<U>> { fn dummy(&self) { } }
 //~^ NOTE other definition for `dummy`
 
diff --git a/src/test/compile-fail/coherence-overlap-issue-23516.rs b/src/test/compile-fail/coherence-overlap-issue-23516.rs
index 950d1fe29bb..ffef5bf1087 100644
--- a/src/test/compile-fail/coherence-overlap-issue-23516.rs
+++ b/src/test/compile-fail/coherence-overlap-issue-23516.rs
@@ -19,6 +19,6 @@ impl<T:Sugar> Sweet for T { }
 impl<U:Sugar> Sweet for Box<U> { }
 //~^ ERROR E0119
 //~| NOTE conflicting implementation for `std::boxed::Box<_>`
-//~| NOTE upstream crates may add new impl of trait `Sugar` for type `std::boxed::Box<_>`
+//~| NOTE downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`
 
 fn main() { }