-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Add hints when intercrate ambiguity causes overlap. #43426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
d49f278
bebd622
a59cc32
043786d
84bfc33
d153ff3
4d503b0
099bb1b
37c9a60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,7 @@ use hir::def_id::DefId; | |
| use infer::{InferCtxt, InferOk}; | ||
| use ty::subst::{Subst, Substs}; | ||
| use traits::{self, Reveal, ObligationCause}; | ||
| use traits::select::IntercrateAmbiguityCause; | ||
| use ty::{self, TyCtxt, TypeFoldable}; | ||
| use syntax_pos::DUMMY_SP; | ||
| use std::rc::Rc; | ||
|
|
@@ -36,6 +37,7 @@ pub struct OverlapError { | |
| pub with_impl: DefId, | ||
| pub trait_desc: String, | ||
| pub self_desc: Option<String>, | ||
| pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>, | ||
| } | ||
|
|
||
| /// Given a subst for the requested impl, translate it to a subst | ||
|
|
@@ -337,6 +339,20 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx | |
| } | ||
| } | ||
|
|
||
| for cause in &overlap.intercrate_ambiguity_causes { | ||
| match cause { | ||
| &IntercrateAmbiguityCause::DownstreamCrate(def_id) => { | ||
| err.note(&format!("downstream crates may implement {}", | ||
| tcx.item_path_str(def_id))); | ||
| } | ||
| &IntercrateAmbiguityCause::UpstreamCrateUpdate(def_id) => { | ||
| err.note(&format!("upstream crates may add new impl for {} \ | ||
|
||
| in future versions", | ||
| tcx.item_path_str(def_id))); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| err.emit(); | ||
| } | ||
| } else { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; | |
| use rustc::hir; | ||
| use rustc::hir::itemlikevisit::ItemLikeVisitor; | ||
| use rustc::traits; | ||
| use rustc::traits::IntercrateAmbiguityCause; | ||
| use rustc::ty::{self, TyCtxt}; | ||
|
|
||
| pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, | ||
|
|
@@ -26,7 +27,8 @@ struct InherentOverlapChecker<'a, 'tcx: 'a> { | |
| } | ||
|
|
||
| impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { | ||
| fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId) { | ||
| fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId, | ||
| overlap: traits::OverlapResult) { | ||
| #[derive(Copy, Clone, PartialEq)] | ||
| enum Namespace { | ||
| Type, | ||
|
|
@@ -50,16 +52,32 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { | |
|
|
||
| for &item2 in &impl_items2[..] { | ||
| if (name, namespace) == name_and_namespace(item2) { | ||
| struct_span_err!(self.tcx.sess, | ||
| self.tcx.span_of_impl(item1).unwrap(), | ||
| E0592, | ||
| "duplicate definitions with name `{}`", | ||
| name) | ||
| .span_label(self.tcx.span_of_impl(item1).unwrap(), | ||
| format!("duplicate definitions for `{}`", name)) | ||
| .span_label(self.tcx.span_of_impl(item2).unwrap(), | ||
| format!("other definition for `{}`", name)) | ||
| .emit(); | ||
| let mut err = struct_span_err!(self.tcx.sess, | ||
| self.tcx.span_of_impl(item1).unwrap(), | ||
| E0592, | ||
| "duplicate definitions with name `{}`", | ||
| name); | ||
|
|
||
| err.span_label(self.tcx.span_of_impl(item1).unwrap(), | ||
| format!("duplicate definitions for `{}`", name)); | ||
| err.span_label(self.tcx.span_of_impl(item2).unwrap(), | ||
| format!("other definition for `{}`", name)); | ||
|
|
||
| for cause in &overlap.intercrate_ambiguity_causes { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: seems like we should extract this into some sort of helper; I feel like the same code was present elsewherein the PR, no? |
||
| match cause { | ||
| &IntercrateAmbiguityCause::DownstreamCrate(def_id) => { | ||
| err.note(&format!("downstream crates may implement {}", | ||
|
||
| self.tcx.item_path_str(def_id))); | ||
| } | ||
| &IntercrateAmbiguityCause::UpstreamCrateUpdate(def_id) => { | ||
| err.note(&format!("upstream crates may add new impl for {} \ | ||
| in future versions", | ||
| self.tcx.item_path_str(def_id))); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| err.emit(); | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -71,8 +89,9 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { | |
| for (i, &impl1_def_id) in impls.iter().enumerate() { | ||
| for &impl2_def_id in &impls[(i + 1)..] { | ||
| self.tcx.infer_ctxt().enter(|infcx| { | ||
| if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id).is_some() { | ||
| self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id) | ||
| if let Some(overlap) = | ||
| traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) { | ||
| self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap) | ||
| } | ||
| }); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: use backticks, like: