mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-03 18:43:38 +00:00
try to detect affected code and direct people to #56105
This commit is contained in:
parent
2c17af0bf7
commit
4c8fd2e80a
@ -4,6 +4,7 @@
|
|||||||
//! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
|
//! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
|
||||||
//! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
|
//! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
|
||||||
|
|
||||||
|
use infer::CombinedSnapshot;
|
||||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use syntax_pos::DUMMY_SP;
|
use syntax_pos::DUMMY_SP;
|
||||||
use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
|
use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
|
||||||
@ -33,6 +34,17 @@ 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: Vec<IntercrateAmbiguityCause>,
|
||||||
|
|
||||||
|
/// True if the overlap might've been permitted before the shift
|
||||||
|
/// to universes.
|
||||||
|
pub involves_placeholder: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_placeholder_note(err: &mut ::errors::DiagnosticBuilder<'_>) {
|
||||||
|
err.note(&format!(
|
||||||
|
"this behavior recently changed as a result of a bug fix; \
|
||||||
|
see rust-lang/rust#56105 for details"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If there are types that satisfy both impls, invokes `on_overlap`
|
/// If there are types that satisfy both impls, invokes `on_overlap`
|
||||||
@ -104,13 +116,22 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, '
|
|||||||
|
|
||||||
/// Can both impl `a` and impl `b` be satisfied by a common type (including
|
/// Can both impl `a` and impl `b` be satisfied by a common type (including
|
||||||
/// `where` clauses)? If so, returns an `ImplHeader` that unifies the two impls.
|
/// `where` clauses)? If so, returns an `ImplHeader` that unifies the two impls.
|
||||||
fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
fn overlap<'cx, 'gcx, 'tcx>(
|
||||||
a_def_id: DefId,
|
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
||||||
b_def_id: DefId)
|
a_def_id: DefId,
|
||||||
-> Option<OverlapResult<'tcx>>
|
b_def_id: DefId,
|
||||||
{
|
) -> Option<OverlapResult<'tcx>> {
|
||||||
debug!("overlap(a_def_id={:?}, b_def_id={:?})", a_def_id, b_def_id);
|
debug!("overlap(a_def_id={:?}, b_def_id={:?})", a_def_id, b_def_id);
|
||||||
|
|
||||||
|
selcx.infcx().probe(|snapshot| overlap_within_probe(selcx, a_def_id, b_def_id, snapshot))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlap_within_probe(
|
||||||
|
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
||||||
|
a_def_id: DefId,
|
||||||
|
b_def_id: DefId,
|
||||||
|
snapshot: &CombinedSnapshot<'_, 'tcx>,
|
||||||
|
) -> Option<OverlapResult<'tcx>> {
|
||||||
// For the purposes of this check, we don't bring any placeholder
|
// For the purposes of this check, we don't bring any placeholder
|
||||||
// types into scope; instead, we replace the generic types with
|
// types into scope; instead, we replace the generic types with
|
||||||
// fresh type variables, and hence we do our evaluations in an
|
// fresh type variables, and hence we do our evaluations in an
|
||||||
@ -158,7 +179,13 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
|||||||
let impl_header = selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
|
let impl_header = selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
|
||||||
let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
|
let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
|
||||||
debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
|
debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
|
||||||
Some(OverlapResult { impl_header, intercrate_ambiguity_causes })
|
|
||||||
|
let involves_placeholder = match selcx.infcx().region_constraints_added_in_snapshot(snapshot) {
|
||||||
|
Some(true) => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
@ -43,7 +43,8 @@ pub use self::FulfillmentErrorCode::*;
|
|||||||
pub use self::Vtable::*;
|
pub use self::Vtable::*;
|
||||||
pub use self::ObligationCauseCode::*;
|
pub use self::ObligationCauseCode::*;
|
||||||
|
|
||||||
pub use self::coherence::{orphan_check, overlapping_impls, OrphanCheckErr, OverlapResult};
|
pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls};
|
||||||
|
pub use self::coherence::{OrphanCheckErr, OverlapResult};
|
||||||
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
|
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
|
||||||
pub use self::project::MismatchedProjectionTypes;
|
pub use self::project::MismatchedProjectionTypes;
|
||||||
pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type};
|
pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type};
|
||||||
|
@ -15,6 +15,7 @@ use hir::def_id::DefId;
|
|||||||
use infer::{InferCtxt, InferOk};
|
use infer::{InferCtxt, InferOk};
|
||||||
use lint;
|
use lint;
|
||||||
use traits::{self, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
|
use traits::{self, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
|
||||||
|
use traits::coherence;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use syntax_pos::DUMMY_SP;
|
use syntax_pos::DUMMY_SP;
|
||||||
@ -32,6 +33,7 @@ pub struct OverlapError {
|
|||||||
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: Vec<IntercrateAmbiguityCause>,
|
||||||
|
pub involves_placeholder: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a subst for the requested impl, translate it to a subst
|
/// Given a subst for the requested impl, translate it to a subst
|
||||||
@ -370,6 +372,10 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
|
|||||||
cause.add_intercrate_ambiguity_hint(&mut err);
|
cause.add_intercrate_ambiguity_hint(&mut err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if overlap.involves_placeholder {
|
||||||
|
coherence::add_placeholder_note(&mut err);
|
||||||
|
}
|
||||||
|
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -164,6 +164,7 @@ impl<'a, 'gcx, 'tcx> Children {
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
|
intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
|
||||||
|
involves_placeholder: overlap.involves_placeholder,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,6 +73,10 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
|||||||
cause.add_intercrate_ambiguity_hint(&mut err);
|
cause.add_intercrate_ambiguity_hint(&mut err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if overlap.involves_placeholder {
|
||||||
|
traits::add_placeholder_note(&mut err);
|
||||||
|
}
|
||||||
|
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ LL | impl TheTrait for for<'a,'b> fn(&'a u8, &'b u8) -> &'a u8 {
|
|||||||
...
|
...
|
||||||
LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 {
|
LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
|
||||||
|
|
|
||||||
|
= note: this behavior recently changed as a result of a bug fix; see #XXX for details
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user