Remove duplicate notes from error on inter-crate ambiguous impl of traits (fix #99092)

This commit is contained in:
rhysd 2022-07-10 02:48:53 +09:00
parent 6c20ab744b
commit d5aed20f47
7 changed files with 45 additions and 13 deletions

View File

@ -13,7 +13,7 @@ use crate::traits::{
self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation, self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation,
PredicateObligations, SelectionContext, PredicateObligations, SelectionContext,
}; };
//use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic; use rustc_errors::Diagnostic;
use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@ -44,7 +44,7 @@ pub enum Conflict {
pub struct OverlapResult<'tcx> { pub struct OverlapResult<'tcx> {
pub impl_header: ty::ImplHeader<'tcx>, pub impl_header: ty::ImplHeader<'tcx>,
pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>, pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>,
/// `true` if the overlap might've been permitted before the shift /// `true` if the overlap might've been permitted before the shift
/// to universes. /// to universes.

View File

@ -110,7 +110,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
}; };
debug!(?cause, "evaluate_stack: pushing cause"); debug!(?cause, "evaluate_stack: pushing cause");
self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause); self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
} }
} }
} }

View File

@ -24,7 +24,7 @@ use crate::traits::error_reporting::InferCtxtExt;
use crate::traits::project::ProjectAndUnifyResult; use crate::traits::project::ProjectAndUnifyResult;
use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::project::ProjectionCacheKeyExt;
use crate::traits::ProjectionCacheKey; use crate::traits::ProjectionCacheKey;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_errors::{Diagnostic, ErrorGuaranteed};
use rustc_hir as hir; use rustc_hir as hir;
@ -52,7 +52,7 @@ pub use rustc_middle::traits::select::*;
mod candidate_assembly; mod candidate_assembly;
mod confirmation; mod confirmation;
#[derive(Clone, Debug)] #[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum IntercrateAmbiguityCause { pub enum IntercrateAmbiguityCause {
DownstreamCrate { trait_desc: String, self_desc: Option<String> }, DownstreamCrate { trait_desc: String, self_desc: Option<String> },
UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> }, UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> },
@ -128,7 +128,7 @@ pub struct SelectionContext<'cx, 'tcx> {
/// We don't do his until we detect a coherence error because it can /// We don't do his until we detect a coherence error because it can
/// lead to false overflow results (#47139) and because always /// lead to false overflow results (#47139) and because always
/// computing it may negatively impact performance. /// computing it may negatively impact performance.
intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>, intercrate_ambiguity_causes: Option<FxIndexSet<IntercrateAmbiguityCause>>,
/// The mode that trait queries run in, which informs our error handling /// The mode that trait queries run in, which informs our error handling
/// policy. In essence, canonicalized queries need their errors propagated /// policy. In essence, canonicalized queries need their errors propagated
@ -254,14 +254,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) { pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
assert!(self.intercrate); assert!(self.intercrate);
assert!(self.intercrate_ambiguity_causes.is_none()); assert!(self.intercrate_ambiguity_causes.is_none());
self.intercrate_ambiguity_causes = Some(vec![]); self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
debug!("selcx: enable_tracking_intercrate_ambiguity_causes"); debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
} }
/// Gets the intercrate ambiguity causes collected since tracking /// Gets the intercrate ambiguity causes collected since tracking
/// was enabled and disables tracking at the same time. If /// was enabled and disables tracking at the same time. If
/// tracking is not enabled, just returns an empty vector. /// tracking is not enabled, just returns an empty vector.
pub fn take_intercrate_ambiguity_causes(&mut self) -> Vec<IntercrateAmbiguityCause> { pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet<IntercrateAmbiguityCause> {
assert!(self.intercrate); assert!(self.intercrate);
self.intercrate_ambiguity_causes.take().unwrap_or_default() self.intercrate_ambiguity_causes.take().unwrap_or_default()
} }
@ -960,7 +960,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}); });
debug!(?cause, "evaluate_stack: pushing cause"); debug!(?cause, "evaluate_stack: pushing cause");
self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause); self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
} }
} }
} }
@ -1252,7 +1252,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
reservation impl ambiguity on {:?}", reservation impl ambiguity on {:?}",
def_id def_id
); );
intercrate_ambiguity_clauses.push( intercrate_ambiguity_clauses.insert(
IntercrateAmbiguityCause::ReservationImpl { IntercrateAmbiguityCause::ReservationImpl {
message: value.to_string(), message: value.to_string(),
}, },

View File

@ -15,7 +15,7 @@ use specialization_graph::GraphExt;
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder}; use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
@ -33,7 +33,7 @@ pub struct OverlapError {
pub with_impl: DefId, pub with_impl: DefId,
pub trait_desc: String, pub trait_desc: String,
pub self_desc: Option<String>, pub self_desc: Option<String>,
pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>, pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>,
pub involves_placeholder: bool, pub involves_placeholder: bool,
} }

View File

@ -8,7 +8,6 @@ LL | impl<A:Iterator> Foo<A::Item> for A { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
| |
= note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions
= note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions
error: aborting due to previous error error: aborting due to previous error

View File

@ -0,0 +1,19 @@
struct S;
impl From<()> for S {
fn from(x: ()) -> Self {
S
}
}
impl<I> From<I> for S
//~^ ERROR conflicting implementations of trait
where
I: Iterator<Item = ()>,
{
fn from(x: I) -> Self {
S
}
}
fn main() {}

View File

@ -0,0 +1,14 @@
error[E0119]: conflicting implementations of trait `std::convert::From<()>` for type `S`
--> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1
|
LL | impl From<()> for S {
| ------------------- first implementation here
...
LL | impl<I> From<I> for S
| ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S`
|
= note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions
error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.