Revert "add coherence future-compat warnings for marker-only trait objects"
This reverts commit 760639635facb6c9a0926ac9278bcba71880b0b3.
This commit is contained in:
parent
e030aa8015
commit
7eb444e4f1
src
librustc
infer
traits
ty
librustc_traits/chalk_context
librustc_typeck/coherence
@ -337,10 +337,6 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
self.infcx.trait_object_mode()
|
||||
}
|
||||
|
||||
fn tag(&self) -> &'static str {
|
||||
"Generalizer"
|
||||
}
|
||||
|
@ -29,10 +29,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
|
||||
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
self.fields.infcx.trait_object_mode()
|
||||
}
|
||||
|
||||
fn a_is_expected(&self) -> bool { self.a_is_expected }
|
||||
|
||||
fn relate_item_substs(&mut self,
|
||||
|
@ -5,7 +5,7 @@ use super::Subtype;
|
||||
|
||||
use traits::ObligationCause;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
use ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
|
||||
/// "Greatest lower bound" (common subtype)
|
||||
pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
|
||||
@ -26,10 +26,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
{
|
||||
fn tag(&self) -> &'static str { "Glb" }
|
||||
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
self.fields.infcx.trait_object_mode()
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
|
||||
|
||||
fn a_is_expected(&self) -> bool { self.a_is_expected }
|
||||
|
@ -5,7 +5,7 @@ use super::Subtype;
|
||||
|
||||
use traits::ObligationCause;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
use ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
|
||||
/// "Least upper bound" (common supertype)
|
||||
pub struct Lub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
|
||||
@ -26,10 +26,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
{
|
||||
fn tag(&self) -> &'static str { "Lub" }
|
||||
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
self.fields.infcx.trait_object_mode()
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
|
||||
|
||||
fn a_is_expected(&self) -> bool { self.a_is_expected }
|
||||
|
@ -25,7 +25,7 @@ use syntax_pos::{self, Span};
|
||||
use traits::{self, ObligationCause, PredicateObligations, TraitEngine};
|
||||
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::relate::{RelateResult, TraitObjectMode};
|
||||
use ty::relate::RelateResult;
|
||||
use ty::subst::{Kind, Substs};
|
||||
use ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners};
|
||||
use ty::{FloatVid, IntVid, TyVid};
|
||||
@ -171,9 +171,6 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||
// This flag is true while there is an active snapshot.
|
||||
in_snapshot: Cell<bool>,
|
||||
|
||||
// The TraitObjectMode used here,
|
||||
trait_object_mode: TraitObjectMode,
|
||||
|
||||
// A set of constraints that regionck must validate. Each
|
||||
// constraint has the form `T:'a`, meaning "some type `T` must
|
||||
// outlive the lifetime 'a". These constraints derive from
|
||||
@ -465,7 +462,6 @@ pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||
arena: SyncDroplessArena,
|
||||
interners: Option<CtxtInterners<'tcx>>,
|
||||
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
|
||||
trait_object_mode: TraitObjectMode,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
|
||||
@ -475,7 +471,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
|
||||
arena: SyncDroplessArena::default(),
|
||||
interners: None,
|
||||
fresh_tables: None,
|
||||
trait_object_mode: TraitObjectMode::NoSquash,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -488,12 +483,6 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_trait_object_mode(mut self, mode: TraitObjectMode) -> Self {
|
||||
debug!("with_trait_object_mode: setting mode to {:?}", mode);
|
||||
self.trait_object_mode = mode;
|
||||
self
|
||||
}
|
||||
|
||||
/// Given a canonical value `C` as a starting point, create an
|
||||
/// inference context that contains each of the bound values
|
||||
/// within instantiated as a fresh variable. The `f` closure is
|
||||
@ -520,7 +509,6 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
||||
pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R {
|
||||
let InferCtxtBuilder {
|
||||
global_tcx,
|
||||
trait_object_mode,
|
||||
ref arena,
|
||||
ref mut interners,
|
||||
ref fresh_tables,
|
||||
@ -532,7 +520,6 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
||||
f(InferCtxt {
|
||||
tcx,
|
||||
in_progress_tables,
|
||||
trait_object_mode,
|
||||
projection_cache: Default::default(),
|
||||
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
|
||||
int_unification_table: RefCell::new(ut::UnificationTable::new()),
|
||||
@ -614,10 +601,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.in_snapshot.get()
|
||||
}
|
||||
|
||||
pub fn trait_object_mode(&self) -> TraitObjectMode {
|
||||
self.trait_object_mode
|
||||
}
|
||||
|
||||
pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
|
||||
t.fold_with(&mut self.freshener())
|
||||
}
|
||||
|
@ -372,13 +372,6 @@ where
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
// squashing should only be done in coherence, not NLL
|
||||
assert_eq!(self.infcx.trait_object_mode(),
|
||||
relate::TraitObjectMode::NoSquash);
|
||||
relate::TraitObjectMode::NoSquash
|
||||
}
|
||||
|
||||
fn tag(&self) -> &'static str {
|
||||
"nll::subtype"
|
||||
}
|
||||
@ -693,13 +686,6 @@ where
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
// squashing should only be done in coherence, not NLL
|
||||
assert_eq!(self.infcx.trait_object_mode(),
|
||||
relate::TraitObjectMode::NoSquash);
|
||||
relate::TraitObjectMode::NoSquash
|
||||
}
|
||||
|
||||
fn tag(&self) -> &'static str {
|
||||
"nll::generalizer"
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use traits::Obligation;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::TyVar;
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::relate::{self, Cause, Relate, RelateResult, TypeRelation};
|
||||
use ty::relate::{Cause, Relate, RelateResult, TypeRelation};
|
||||
use std::mem;
|
||||
|
||||
/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
|
||||
@ -33,10 +33,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
for Sub<'combine, 'infcx, 'gcx, 'tcx>
|
||||
{
|
||||
fn tag(&self) -> &'static str { "Sub" }
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
self.fields.infcx.trait_object_mode()
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.infcx.tcx }
|
||||
fn a_is_expected(&self) -> bool { self.a_is_expected }
|
||||
|
||||
|
@ -11,7 +11,6 @@ use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
|
||||
use traits::IntercrateMode;
|
||||
use traits::select::IntercrateAmbiguityCause;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::relate::TraitObjectMode;
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::subst::Subst;
|
||||
|
||||
@ -55,7 +54,6 @@ pub fn overlapping_impls<'gcx, F1, F2, R>(
|
||||
impl1_def_id: DefId,
|
||||
impl2_def_id: DefId,
|
||||
intercrate_mode: IntercrateMode,
|
||||
trait_object_mode: TraitObjectMode,
|
||||
on_overlap: F1,
|
||||
no_overlap: F2,
|
||||
) -> R
|
||||
@ -66,14 +64,12 @@ where
|
||||
debug!("overlapping_impls(\
|
||||
impl1_def_id={:?}, \
|
||||
impl2_def_id={:?},
|
||||
intercrate_mode={:?},
|
||||
trait_object_mode={:?})",
|
||||
intercrate_mode={:?})",
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
intercrate_mode,
|
||||
trait_object_mode);
|
||||
intercrate_mode);
|
||||
|
||||
let overlaps = tcx.infer_ctxt().with_trait_object_mode(trait_object_mode).enter(|infcx| {
|
||||
let overlaps = tcx.infer_ctxt().enter(|infcx| {
|
||||
let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode);
|
||||
overlap(selcx, impl1_def_id, impl2_def_id).is_some()
|
||||
});
|
||||
@ -85,7 +81,7 @@ where
|
||||
// In the case where we detect an error, run the check again, but
|
||||
// this time tracking intercrate ambuiguity causes for better
|
||||
// diagnostics. (These take time and can lead to false errors.)
|
||||
tcx.infer_ctxt().with_trait_object_mode(trait_object_mode).enter(|infcx| {
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode);
|
||||
selcx.enable_tracking_intercrate_ambiguity_causes();
|
||||
on_overlap(overlap(selcx, impl1_def_id, impl2_def_id).unwrap())
|
||||
|
@ -449,7 +449,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
{
|
||||
let simp = fast_reject::simplify_type(self.tcx,
|
||||
trait_ref.skip_binder().self_ty(),
|
||||
true,);
|
||||
true);
|
||||
let all_impls = self.tcx.all_impls(trait_ref.def_id());
|
||||
|
||||
match simp {
|
||||
|
@ -56,8 +56,6 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
|
||||
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
|
||||
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
|
||||
pub use self::specialize::find_associated_item;
|
||||
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
|
||||
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
|
||||
pub use self::engine::{TraitEngine, TraitEngineExt};
|
||||
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
|
||||
pub use self::util::{supertraits, supertrait_def_ids, transitive_bounds,
|
||||
|
@ -33,7 +33,7 @@ use infer::{InferCtxt, InferOk, TypeFreshener};
|
||||
use middle::lang_items;
|
||||
use mir::interpret::GlobalId;
|
||||
use ty::fast_reject;
|
||||
use ty::relate::{TypeRelation, TraitObjectMode};
|
||||
use ty::relate::TypeRelation;
|
||||
use ty::subst::{Subst, Substs};
|
||||
use ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
|
||||
@ -1416,13 +1416,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Same idea as the above, but for alt trait object modes. These
|
||||
// should only be used in intercrate mode - better safe than sorry.
|
||||
if self.infcx.trait_object_mode() != TraitObjectMode::NoSquash {
|
||||
bug!("using squashing TraitObjectMode outside of intercrate mode? param_env={:?}",
|
||||
param_env);
|
||||
}
|
||||
|
||||
// Otherwise, we can use the global cache.
|
||||
true
|
||||
}
|
||||
@ -3580,8 +3573,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
previous: &ty::PolyTraitRef<'tcx>,
|
||||
current: &ty::PolyTraitRef<'tcx>,
|
||||
) -> bool {
|
||||
let mut matcher = ty::_match::Match::new(
|
||||
self.tcx(), self.infcx.trait_object_mode());
|
||||
let mut matcher = ty::_match::Match::new(self.tcx());
|
||||
matcher.relate(previous, current).is_ok()
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,11 @@ pub mod specialization_graph;
|
||||
use hir::def_id::DefId;
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use lint;
|
||||
use traits::{self, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
|
||||
use traits::coherence;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
use traits::{self, ObligationCause, TraitEngine};
|
||||
use traits::select::IntercrateAmbiguityCause;
|
||||
use ty::{self, TyCtxt, TypeFoldable};
|
||||
use ty::subst::{Subst, Substs};
|
||||
@ -27,7 +27,6 @@ use super::{SelectionContext, FulfillmentContext};
|
||||
use super::util::impl_trait_ref_and_oblig;
|
||||
|
||||
/// Information pertinent to an overlapping impl error.
|
||||
#[derive(Debug)]
|
||||
pub struct OverlapError {
|
||||
pub with_impl: DefId,
|
||||
pub trait_desc: String,
|
||||
@ -311,9 +310,8 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
|
||||
let insert_result = sg.insert(tcx, impl_def_id);
|
||||
// Report error if there was one.
|
||||
let (overlap, used_to_be_allowed) = match insert_result {
|
||||
Err(overlap) => (Some(overlap), None),
|
||||
Ok(Some(overlap)) => (Some(overlap.error), Some(overlap.kind)),
|
||||
Ok(None) => (None, None)
|
||||
Err(overlap) => (Some(overlap), false),
|
||||
Ok(opt_overlap) => (opt_overlap, true)
|
||||
};
|
||||
|
||||
if let Some(overlap) = overlap {
|
||||
@ -323,20 +321,14 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
|
||||
String::new(), |ty| {
|
||||
format!(" for type `{}`", ty)
|
||||
}),
|
||||
if used_to_be_allowed.is_some() { " (E0119)" } else { "" }
|
||||
if used_to_be_allowed { " (E0119)" } else { "" }
|
||||
);
|
||||
let impl_span = tcx.sess.source_map().def_span(
|
||||
tcx.span_of_impl(impl_def_id).unwrap()
|
||||
);
|
||||
let mut err = if let Some(kind) = used_to_be_allowed {
|
||||
let lint = match kind {
|
||||
FutureCompatOverlapErrorKind::Issue43355 =>
|
||||
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
|
||||
FutureCompatOverlapErrorKind::Issue33140 =>
|
||||
lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
};
|
||||
let mut err = if used_to_be_allowed {
|
||||
tcx.struct_span_lint_node(
|
||||
lint,
|
||||
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
|
||||
tcx.hir().as_local_node_id(impl_def_id).unwrap(),
|
||||
impl_span,
|
||||
&msg)
|
||||
|
@ -7,7 +7,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
|
||||
use traits;
|
||||
use ty::{self, TyCtxt, TypeFoldable};
|
||||
use ty::fast_reject::{self, SimplifiedType};
|
||||
use ty::relate::TraitObjectMode;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use syntax::ast::Ident;
|
||||
use util::captures::Captures;
|
||||
@ -59,22 +58,10 @@ struct Children {
|
||||
blanket_impls: Vec<DefId>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum FutureCompatOverlapErrorKind {
|
||||
Issue43355,
|
||||
Issue33140,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FutureCompatOverlapError {
|
||||
pub error: OverlapError,
|
||||
pub kind: FutureCompatOverlapErrorKind
|
||||
}
|
||||
|
||||
/// The result of attempting to insert an impl into a group of children.
|
||||
enum Inserted {
|
||||
/// The impl was inserted as a new child in this group of children.
|
||||
BecameNewSibling(Option<FutureCompatOverlapError>),
|
||||
BecameNewSibling(Option<OverlapError>),
|
||||
|
||||
/// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc.
|
||||
ReplaceChildren(Vec<DefId>),
|
||||
@ -174,7 +161,6 @@ impl<'a, 'gcx, 'tcx> Children {
|
||||
possible_sibling,
|
||||
impl_def_id,
|
||||
traits::IntercrateMode::Issue43355,
|
||||
TraitObjectMode::NoSquash,
|
||||
|overlap| {
|
||||
if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
|
||||
return Ok((false, false));
|
||||
@ -205,36 +191,12 @@ impl<'a, 'gcx, 'tcx> Children {
|
||||
replace_children.push(possible_sibling);
|
||||
} else {
|
||||
if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
|
||||
// do future-compat checks for overlap. Have issue #43355
|
||||
// errors overwrite issue #33140 errors when both are present.
|
||||
|
||||
traits::overlapping_impls(
|
||||
tcx,
|
||||
possible_sibling,
|
||||
impl_def_id,
|
||||
traits::IntercrateMode::Fixed,
|
||||
TraitObjectMode::SquashAutoTraitsIssue33140,
|
||||
|overlap| {
|
||||
last_lint = Some(FutureCompatOverlapError {
|
||||
error: overlap_error(overlap),
|
||||
kind: FutureCompatOverlapErrorKind::Issue33140
|
||||
});
|
||||
},
|
||||
|| (),
|
||||
);
|
||||
|
||||
traits::overlapping_impls(
|
||||
tcx,
|
||||
possible_sibling,
|
||||
impl_def_id,
|
||||
traits::IntercrateMode::Fixed,
|
||||
TraitObjectMode::NoSquash,
|
||||
|overlap| {
|
||||
last_lint = Some(FutureCompatOverlapError {
|
||||
error: overlap_error(overlap),
|
||||
kind: FutureCompatOverlapErrorKind::Issue43355
|
||||
});
|
||||
},
|
||||
|overlap| last_lint = Some(overlap_error(overlap)),
|
||||
|| (),
|
||||
);
|
||||
}
|
||||
@ -301,7 +263,7 @@ impl<'a, 'gcx, 'tcx> Graph {
|
||||
pub fn insert(&mut self,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
impl_def_id: DefId)
|
||||
-> Result<Option<FutureCompatOverlapError>, OverlapError> {
|
||||
-> Result<Option<OverlapError>, OverlapError> {
|
||||
assert!(impl_def_id.is_local());
|
||||
|
||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
|
@ -19,24 +19,17 @@ use ty::relate::{self, Relate, TypeRelation, RelateResult};
|
||||
/// important thing about the result is Ok/Err. Also, matching never
|
||||
/// affects any type variables or unification state.
|
||||
pub struct Match<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
trait_object_mode: relate::TraitObjectMode
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Match<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
trait_object_mode: relate::TraitObjectMode)
|
||||
-> Match<'a, 'gcx, 'tcx> {
|
||||
Match { tcx, trait_object_mode }
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Match<'a, 'gcx, 'tcx> {
|
||||
Match { tcx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> {
|
||||
fn tag(&self) -> &'static str { "Match" }
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
self.trait_object_mode
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.tcx }
|
||||
fn a_is_expected(&self) -> bool { true } // irrelevant
|
||||
|
||||
|
@ -25,20 +25,9 @@ pub enum Cause {
|
||||
ExistentialRegionBound, // relating an existential region bound
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum TraitObjectMode {
|
||||
NoSquash,
|
||||
/// A temporary mode to treat `Send + Sync = Sync + Send`, should be
|
||||
/// used only in coherence.
|
||||
SquashAutoTraitsIssue33140
|
||||
}
|
||||
|
||||
pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
|
||||
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx>;
|
||||
|
||||
/// Return the trait object mode to be used.
|
||||
fn trait_object_mode(&self) -> TraitObjectMode;
|
||||
|
||||
/// Returns a static string we can use for printouts.
|
||||
fn tag(&self) -> &'static str;
|
||||
|
||||
@ -597,44 +586,14 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
|
||||
a: &Self,
|
||||
b: &Self)
|
||||
-> RelateResult<'tcx, Self>
|
||||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a {
|
||||
use ty::ExistentialPredicate::*;
|
||||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a {
|
||||
|
||||
let tcx = relation.tcx();
|
||||
let (a_buf, b_buf);
|
||||
let (a_norm, b_norm): (&[_], &[_]) = match relation.trait_object_mode() {
|
||||
TraitObjectMode::NoSquash => {
|
||||
(a, b)
|
||||
}
|
||||
TraitObjectMode::SquashAutoTraitsIssue33140 => {
|
||||
// Treat auto-trait "principal" components as equal
|
||||
// to the non-principal components, to make
|
||||
// `dyn Send+Sync = dyn Sync+Send`.
|
||||
let normalize = |d: &[ty::ExistentialPredicate<'tcx>]| {
|
||||
let mut result: Vec<_> = d.iter().map(|pi| match pi {
|
||||
Trait(ref a) if tcx.trait_is_auto(a.def_id) => {
|
||||
AutoTrait(a.def_id)
|
||||
},
|
||||
other => *other
|
||||
}).collect();
|
||||
|
||||
result.sort_by(|a, b| a.stable_cmp(tcx, b));
|
||||
result.dedup();
|
||||
result
|
||||
};
|
||||
|
||||
a_buf = normalize(a);
|
||||
b_buf = normalize(b);
|
||||
|
||||
(&a_buf, &b_buf)
|
||||
}
|
||||
};
|
||||
|
||||
if a_norm.len() != b_norm.len() {
|
||||
if a.len() != b.len() {
|
||||
return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
|
||||
}
|
||||
|
||||
let v = a_norm.iter().zip(b_norm.iter()).map(|(ep_a, ep_b)| {
|
||||
let tcx = relation.tcx();
|
||||
let v = a.iter().zip(b.iter()).map(|(ep_a, ep_b)| {
|
||||
use ty::ExistentialPredicate::*;
|
||||
match (*ep_a, *ep_b) {
|
||||
(Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)),
|
||||
|
@ -17,7 +17,7 @@ use rustc::traits::{
|
||||
};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::subst::Kind;
|
||||
use rustc::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
use rustc::ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
use super::{ChalkInferenceContext, ChalkArenas, ChalkExClause, ConstrainedSubst};
|
||||
@ -157,10 +157,6 @@ impl TypeRelation<'cx, 'gcx, 'tcx> for AnswerSubstitutor<'cx, 'gcx, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn trait_object_mode(&self) -> relate::TraitObjectMode {
|
||||
self.infcx.trait_object_mode()
|
||||
}
|
||||
|
||||
fn tag(&self) -> &'static str {
|
||||
"chalk_context::answer_substitutor"
|
||||
}
|
||||
|
@ -2,9 +2,8 @@ use namespace::Namespace;
|
||||
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use rustc::hir;
|
||||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc::traits::{self, IntercrateMode, FutureCompatOverlapErrorKind};
|
||||
use rustc::traits::{self, IntercrateMode};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::ty::relate::TraitObjectMode;
|
||||
|
||||
use lint;
|
||||
|
||||
@ -20,11 +19,9 @@ struct InherentOverlapChecker<'a, 'tcx: 'a> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
||||
fn check_for_common_items_in_impls(
|
||||
&self, impl1: DefId, impl2: DefId,
|
||||
overlap: traits::OverlapResult,
|
||||
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>)
|
||||
{
|
||||
fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId,
|
||||
overlap: traits::OverlapResult,
|
||||
used_to_be_allowed: bool) {
|
||||
|
||||
let name_and_namespace = |def_id| {
|
||||
let item = self.tcx.associated_item(def_id);
|
||||
@ -40,28 +37,19 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
||||
for &item2 in &impl_items2[..] {
|
||||
if (name, namespace) == name_and_namespace(item2) {
|
||||
let node_id = self.tcx.hir().as_local_node_id(impl1);
|
||||
let mut err = match used_to_be_allowed {
|
||||
Some(kind) if node_id.is_some() => {
|
||||
let lint = match kind {
|
||||
FutureCompatOverlapErrorKind::Issue43355 =>
|
||||
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
|
||||
FutureCompatOverlapErrorKind::Issue33140 =>
|
||||
lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
};
|
||||
self.tcx.struct_span_lint_node(
|
||||
lint,
|
||||
node_id.unwrap(),
|
||||
self.tcx.span_of_impl(item1).unwrap(),
|
||||
&format!("duplicate definitions with name `{}` (E0592)", name)
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
struct_span_err!(self.tcx.sess,
|
||||
self.tcx.span_of_impl(item1).unwrap(),
|
||||
E0592,
|
||||
"duplicate definitions with name `{}`",
|
||||
name)
|
||||
}
|
||||
let mut err = if used_to_be_allowed && node_id.is_some() {
|
||||
self.tcx.struct_span_lint_node(
|
||||
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
|
||||
node_id.unwrap(),
|
||||
self.tcx.span_of_impl(item1).unwrap(),
|
||||
&format!("duplicate definitions with name `{}` (E0592)", name)
|
||||
)
|
||||
} else {
|
||||
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(),
|
||||
@ -88,61 +76,36 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
||||
|
||||
for (i, &impl1_def_id) in impls.iter().enumerate() {
|
||||
for &impl2_def_id in &impls[(i + 1)..] {
|
||||
let mut used_to_be_allowed = traits::overlapping_impls(
|
||||
let used_to_be_allowed = traits::overlapping_impls(
|
||||
self.tcx,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
IntercrateMode::Issue43355,
|
||||
TraitObjectMode::NoSquash,
|
||||
|overlap| {
|
||||
self.check_for_common_items_in_impls(
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap,
|
||||
Some(FutureCompatOverlapErrorKind::Issue43355),
|
||||
false,
|
||||
);
|
||||
false
|
||||
},
|
||||
|| true,
|
||||
);
|
||||
|
||||
if used_to_be_allowed {
|
||||
used_to_be_allowed = traits::overlapping_impls(
|
||||
self.tcx,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
IntercrateMode::Fixed,
|
||||
TraitObjectMode::NoSquash,
|
||||
|overlap| {
|
||||
self.check_for_common_items_in_impls(
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap,
|
||||
None,
|
||||
);
|
||||
false
|
||||
},
|
||||
|| true,
|
||||
);
|
||||
}
|
||||
|
||||
if used_to_be_allowed {
|
||||
traits::overlapping_impls(
|
||||
self.tcx,
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
IntercrateMode::Fixed,
|
||||
TraitObjectMode::SquashAutoTraitsIssue33140,
|
||||
|overlap| {
|
||||
self.check_for_common_items_in_impls(
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap,
|
||||
Some(FutureCompatOverlapErrorKind::Issue33140),
|
||||
);
|
||||
false
|
||||
},
|
||||
|| true,
|
||||
|overlap| self.check_for_common_items_in_impls(
|
||||
impl1_def_id,
|
||||
impl2_def_id,
|
||||
overlap,
|
||||
true,
|
||||
),
|
||||
|| (),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user