fast_reject: remove StripReferences
This commit is contained in:
parent
165142e993
commit
0efc6c02cb
7 changed files with 20 additions and 68 deletions
|
@ -26,7 +26,7 @@ use rustc_middle::mir::interpret;
|
||||||
use rustc_middle::thir;
|
use rustc_middle::thir;
|
||||||
use rustc_middle::traits::specialization_graph;
|
use rustc_middle::traits::specialization_graph;
|
||||||
use rustc_middle::ty::codec::TyEncoder;
|
use rustc_middle::ty::codec::TyEncoder;
|
||||||
use rustc_middle::ty::fast_reject::{self, SimplifiedType, SimplifyParams, StripReferences};
|
use rustc_middle::ty::fast_reject::{self, SimplifiedType, SimplifyParams};
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
|
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
|
||||||
use rustc_serialize::{opaque, Encodable, Encoder};
|
use rustc_serialize::{opaque, Encodable, Encoder};
|
||||||
|
@ -2066,7 +2066,6 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplsVisitor<'tcx> {
|
||||||
self.tcx,
|
self.tcx,
|
||||||
trait_ref.self_ty(),
|
trait_ref.self_ty(),
|
||||||
SimplifyParams::No,
|
SimplifyParams::No,
|
||||||
StripReferences::No,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
self.impls
|
self.impls
|
||||||
|
|
|
@ -54,12 +54,6 @@ pub enum SimplifyParams {
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
|
||||||
pub enum StripReferences {
|
|
||||||
Yes,
|
|
||||||
No,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists.
|
/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists.
|
||||||
///
|
///
|
||||||
/// The idea is to get something simple that we can use to quickly decide if two types could unify,
|
/// The idea is to get something simple that we can use to quickly decide if two types could unify,
|
||||||
|
@ -73,8 +67,6 @@ pub enum StripReferences {
|
||||||
/// When using `SimplifyParams::Yes`, we still return a simplified type for params and projections²,
|
/// When using `SimplifyParams::Yes`, we still return a simplified type for params and projections²,
|
||||||
/// the reasoning for this can be seen at the places doing this.
|
/// the reasoning for this can be seen at the places doing this.
|
||||||
///
|
///
|
||||||
/// For diagnostics we strip references with `StripReferences::Yes`. This is currently the best
|
|
||||||
/// way to skip some unhelpful suggestions.
|
|
||||||
///
|
///
|
||||||
/// ¹ meaning that if two outermost layers are different, then the whole types are also different.
|
/// ¹ meaning that if two outermost layers are different, then the whole types are also different.
|
||||||
/// ² FIXME(@lcnr): this seems like it can actually end up being unsound with the way it's used during
|
/// ² FIXME(@lcnr): this seems like it can actually end up being unsound with the way it's used during
|
||||||
|
@ -87,7 +79,6 @@ pub fn simplify_type(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
ty: Ty<'_>,
|
ty: Ty<'_>,
|
||||||
can_simplify_params: SimplifyParams,
|
can_simplify_params: SimplifyParams,
|
||||||
strip_references: StripReferences,
|
|
||||||
) -> Option<SimplifiedType> {
|
) -> Option<SimplifiedType> {
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Bool => Some(BoolSimplifiedType),
|
ty::Bool => Some(BoolSimplifiedType),
|
||||||
|
@ -106,16 +97,7 @@ pub fn simplify_type(
|
||||||
}
|
}
|
||||||
_ => Some(MarkerTraitObjectSimplifiedType),
|
_ => Some(MarkerTraitObjectSimplifiedType),
|
||||||
},
|
},
|
||||||
ty::Ref(_, ty, mutbl) => {
|
ty::Ref(_, _, mutbl) => Some(RefSimplifiedType(mutbl)),
|
||||||
if strip_references == StripReferences::Yes {
|
|
||||||
// For diagnostics, when recommending similar impls we want to
|
|
||||||
// recommend impls even when there is a reference mismatch,
|
|
||||||
// so we treat &T and T equivalently in that case.
|
|
||||||
simplify_type(tcx, ty, can_simplify_params, strip_references)
|
|
||||||
} else {
|
|
||||||
Some(RefSimplifiedType(mutbl))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(ClosureSimplifiedType(def_id)),
|
ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(ClosureSimplifiedType(def_id)),
|
||||||
ty::Generator(def_id, _, _) => Some(GeneratorSimplifiedType(def_id)),
|
ty::Generator(def_id, _, _) => Some(GeneratorSimplifiedType(def_id)),
|
||||||
ty::GeneratorWitness(ref tys) => {
|
ty::GeneratorWitness(ref tys) => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::traits::specialization_graph;
|
use crate::traits::specialization_graph;
|
||||||
use crate::ty::fast_reject::{self, SimplifiedType, SimplifyParams, StripReferences};
|
use crate::ty::fast_reject::{self, SimplifiedType, SimplifyParams};
|
||||||
use crate::ty::fold::TypeFoldable;
|
use crate::ty::fold::TypeFoldable;
|
||||||
use crate::ty::{Ident, Ty, TyCtxt};
|
use crate::ty::{Ident, Ty, TyCtxt};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -150,9 +150,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
) -> impl Iterator<Item = DefId> + 'tcx {
|
) -> impl Iterator<Item = DefId> + 'tcx {
|
||||||
let impls = self.trait_impls_of(def_id);
|
let impls = self.trait_impls_of(def_id);
|
||||||
if let Some(simp) =
|
if let Some(simp) = fast_reject::simplify_type(self, self_ty, SimplifyParams::No) {
|
||||||
fast_reject::simplify_type(self, self_ty, SimplifyParams::No, StripReferences::No)
|
|
||||||
{
|
|
||||||
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
|
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
|
||||||
return impls.iter().copied();
|
return impls.iter().copied();
|
||||||
}
|
}
|
||||||
|
@ -189,9 +187,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
// whose outer level is not a parameter or projection. Especially for things like
|
// whose outer level is not a parameter or projection. Especially for things like
|
||||||
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
|
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
|
||||||
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
|
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
|
||||||
if let Some(simp) =
|
if let Some(simp) = fast_reject::simplify_type(self, self_ty, SimplifyParams::Yes) {
|
||||||
fast_reject::simplify_type(self, self_ty, SimplifyParams::Yes, StripReferences::No)
|
|
||||||
{
|
|
||||||
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
|
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
|
||||||
for &impl_def_id in impls {
|
for &impl_def_id in impls {
|
||||||
if let result @ Some(_) = f(impl_def_id) {
|
if let result @ Some(_) = f(impl_def_id) {
|
||||||
|
@ -251,7 +247,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(simplified_self_ty) =
|
if let Some(simplified_self_ty) =
|
||||||
fast_reject::simplify_type(tcx, impl_self_ty, SimplifyParams::No, StripReferences::No)
|
fast_reject::simplify_type(tcx, impl_self_ty, SimplifyParams::No)
|
||||||
{
|
{
|
||||||
impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
|
impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::traits::{
|
||||||
};
|
};
|
||||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc_middle::traits::specialization_graph::OverlapMode;
|
use rustc_middle::traits::specialization_graph::OverlapMode;
|
||||||
use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences};
|
use rustc_middle::ty::fast_reject::{self, SimplifyParams};
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::subst::Subst;
|
use rustc_middle::ty::subst::Subst;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
@ -82,8 +82,8 @@ where
|
||||||
impl2_ref.iter().flat_map(|tref| tref.substs.types()),
|
impl2_ref.iter().flat_map(|tref| tref.substs.types()),
|
||||||
)
|
)
|
||||||
.any(|(ty1, ty2)| {
|
.any(|(ty1, ty2)| {
|
||||||
let t1 = fast_reject::simplify_type(tcx, ty1, SimplifyParams::No, StripReferences::No);
|
let t1 = fast_reject::simplify_type(tcx, ty1, SimplifyParams::No);
|
||||||
let t2 = fast_reject::simplify_type(tcx, ty2, SimplifyParams::No, StripReferences::No);
|
let t2 = fast_reject::simplify_type(tcx, ty2, SimplifyParams::No);
|
||||||
|
|
||||||
if let (Some(t1), Some(t2)) = (t1, t2) {
|
if let (Some(t1), Some(t2)) = (t1, t2) {
|
||||||
// Simplified successfully
|
// Simplified successfully
|
||||||
|
|
|
@ -36,7 +36,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||||
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
|
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::thir::abstract_const::NotConstEvaluatable;
|
use rustc_middle::thir::abstract_const::NotConstEvaluatable;
|
||||||
use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences};
|
use rustc_middle::ty::fast_reject::{self, SimplifyParams};
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::relate::TypeRelation;
|
use rustc_middle::ty::relate::TypeRelation;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef};
|
||||||
|
@ -2172,14 +2172,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
obligation_ty,
|
obligation_ty,
|
||||||
SimplifyParams::Yes,
|
SimplifyParams::Yes,
|
||||||
StripReferences::No,
|
|
||||||
);
|
|
||||||
let simplified_impl_ty = fast_reject::simplify_type(
|
|
||||||
self.tcx(),
|
|
||||||
impl_ty,
|
|
||||||
SimplifyParams::No,
|
|
||||||
StripReferences::No,
|
|
||||||
);
|
);
|
||||||
|
let simplified_impl_ty =
|
||||||
|
fast_reject::simplify_type(self.tcx(), impl_ty, SimplifyParams::No);
|
||||||
|
|
||||||
simplified_obligation_ty.is_some()
|
simplified_obligation_ty.is_some()
|
||||||
&& simplified_impl_ty.is_some()
|
&& simplified_impl_ty.is_some()
|
||||||
|
|
|
@ -2,7 +2,7 @@ use super::OverlapError;
|
||||||
|
|
||||||
use crate::traits;
|
use crate::traits;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::ty::fast_reject::{self, SimplifiedType, SimplifyParams, StripReferences};
|
use rustc_middle::ty::fast_reject::{self, SimplifiedType, SimplifyParams};
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
|
||||||
|
|
||||||
|
@ -49,12 +49,7 @@ impl ChildrenExt<'_> for Children {
|
||||||
/// Insert an impl into this set of children without comparing to any existing impls.
|
/// Insert an impl into this set of children without comparing to any existing impls.
|
||||||
fn insert_blindly(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) {
|
fn insert_blindly(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) {
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||||
if let Some(st) = fast_reject::simplify_type(
|
if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), SimplifyParams::No) {
|
||||||
tcx,
|
|
||||||
trait_ref.self_ty(),
|
|
||||||
SimplifyParams::No,
|
|
||||||
StripReferences::No,
|
|
||||||
) {
|
|
||||||
debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
|
debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
|
||||||
self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
|
self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,12 +64,7 @@ impl ChildrenExt<'_> for Children {
|
||||||
fn remove_existing(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) {
|
fn remove_existing(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) {
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||||
let vec: &mut Vec<DefId>;
|
let vec: &mut Vec<DefId>;
|
||||||
if let Some(st) = fast_reject::simplify_type(
|
if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), SimplifyParams::No) {
|
||||||
tcx,
|
|
||||||
trait_ref.self_ty(),
|
|
||||||
SimplifyParams::No,
|
|
||||||
StripReferences::No,
|
|
||||||
) {
|
|
||||||
debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
|
debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
|
||||||
vec = self.non_blanket_impls.get_mut(&st).unwrap();
|
vec = self.non_blanket_impls.get_mut(&st).unwrap();
|
||||||
} else {
|
} else {
|
||||||
|
@ -322,12 +312,7 @@ impl GraphExt for Graph {
|
||||||
|
|
||||||
let mut parent = trait_def_id;
|
let mut parent = trait_def_id;
|
||||||
let mut last_lint = None;
|
let mut last_lint = None;
|
||||||
let simplified = fast_reject::simplify_type(
|
let simplified = fast_reject::simplify_type(tcx, trait_ref.self_ty(), SimplifyParams::No);
|
||||||
tcx,
|
|
||||||
trait_ref.self_ty(),
|
|
||||||
SimplifyParams::No,
|
|
||||||
StripReferences::No,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Descend the specialization tree, where `parent` is the current parent node.
|
// Descend the specialization tree, where `parent` is the current parent node.
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{ExprKind, Node, QPath};
|
use rustc_hir::{ExprKind, Node, QPath};
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_middle::ty::fast_reject::{simplify_type, SimplifyParams, StripReferences};
|
use rustc_middle::ty::fast_reject::{simplify_type, SimplifyParams};
|
||||||
use rustc_middle::ty::print::with_crate_prefix;
|
use rustc_middle::ty::print::with_crate_prefix;
|
||||||
use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_span::lev_distance;
|
use rustc_span::lev_distance;
|
||||||
|
@ -1748,8 +1748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// FIXME: Even though negative bounds are not implemented, we could maybe handle
|
// FIXME: Even though negative bounds are not implemented, we could maybe handle
|
||||||
// cases where a positive bound implies a negative impl.
|
// cases where a positive bound implies a negative impl.
|
||||||
(candidates, Vec::new())
|
(candidates, Vec::new())
|
||||||
} else if let Some(simp_rcvr_ty) =
|
} else if let Some(simp_rcvr_ty) = simplify_type(self.tcx, rcvr_ty, SimplifyParams::Yes)
|
||||||
simplify_type(self.tcx, rcvr_ty, SimplifyParams::Yes, StripReferences::No)
|
|
||||||
{
|
{
|
||||||
let mut potential_candidates = Vec::new();
|
let mut potential_candidates = Vec::new();
|
||||||
let mut explicitly_negative = Vec::new();
|
let mut explicitly_negative = Vec::new();
|
||||||
|
@ -1763,12 +1762,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
.any(|imp_did| {
|
.any(|imp_did| {
|
||||||
let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
|
let imp = self.tcx.impl_trait_ref(imp_did).unwrap();
|
||||||
let imp_simp = simplify_type(
|
let imp_simp =
|
||||||
self.tcx,
|
simplify_type(self.tcx, imp.self_ty(), SimplifyParams::Yes);
|
||||||
imp.self_ty(),
|
|
||||||
SimplifyParams::Yes,
|
|
||||||
StripReferences::No,
|
|
||||||
);
|
|
||||||
imp_simp.map_or(false, |s| s == simp_rcvr_ty)
|
imp_simp.map_or(false, |s| s == simp_rcvr_ty)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue