From 099bb1ba8a60dff6e51b1325bf746ec6c5eee2a3 Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Tue, 1 Aug 2017 12:37:11 +0430 Subject: [PATCH] Fix misdetection of upstream intercrate ambiguity. --- src/librustc/traits/select.rs | 21 ++++++++++++------- .../coherence-overlap-issue-23516-inherent.rs | 2 +- .../coherence-overlap-issue-23516.rs | 2 +- 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); impl Cake { 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 Cake> { 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 Sweet for T { } impl Sweet for Box { } //~^ 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() { }