Skip to content
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

Don't pass TreatProjections separately to fast_reject #109202

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams, TreatProjections};
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
use rustc_span::symbol::sym;

Expand Down Expand Up @@ -97,12 +97,7 @@ impl<'tcx> InherentCollect<'tcx> {
}
}

if let Some(simp) = simplify_type(
self.tcx,
self_ty,
TreatParams::AsCandidateKey,
TreatProjections::AsCandidateKey,
) {
if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) {
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
} else {
bug!("unexpected self type: {:?}", self_ty);
Expand Down Expand Up @@ -162,12 +157,7 @@ impl<'tcx> InherentCollect<'tcx> {
}
}

if let Some(simp) = simplify_type(
self.tcx,
ty,
TreatParams::AsCandidateKey,
TreatProjections::AsCandidateKey,
) {
if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::AsCandidateKey) {
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
} else {
bug!("unexpected primitive type: {:?}", ty);
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
use rustc_middle::middle::stability;
use rustc_middle::ty::fast_reject::TreatProjections;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::AssocItem;
use rustc_middle::ty::GenericParamDefKind;
Expand Down Expand Up @@ -701,7 +700,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}

fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey, TreatProjections::AsCandidateKey) else {
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) else {
bug!("unexpected incoherent type: {:?}", self_ty)
};
for &impl_def_id in self.tcx.incoherent_impls(simp) {
Expand Down
20 changes: 6 additions & 14 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use rustc_infer::infer::{
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::traits::util::supertraits;
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::fast_reject::TreatProjections;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
Expand Down Expand Up @@ -1524,7 +1523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.into_iter()
.any(|info| self.associated_value(info.def_id, item_name).is_some());
let found_assoc = |ty: Ty<'tcx>| {
simplify_type(tcx, ty, TreatParams::AsCandidateKey, TreatProjections::AsCandidateKey)
simplify_type(tcx, ty, TreatParams::AsCandidateKey)
.and_then(|simp| {
tcx.incoherent_impls(simp)
.iter()
Expand Down Expand Up @@ -2653,12 +2652,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// FIXME: Even though negative bounds are not implemented, we could maybe handle
// cases where a positive bound implies a negative impl.
(candidates, Vec::new())
} else if let Some(simp_rcvr_ty) = simplify_type(
self.tcx,
rcvr_ty,
TreatParams::ForLookup,
TreatProjections::ForLookup,
) {
} else if let Some(simp_rcvr_ty) =
simplify_type(self.tcx, rcvr_ty, TreatParams::ForLookup)
{
let mut potential_candidates = Vec::new();
let mut explicitly_negative = Vec::new();
for candidate in candidates {
Expand All @@ -2671,12 +2667,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
})
.any(|imp_did| {
let imp = self.tcx.impl_trait_ref(imp_did).unwrap().subst_identity();
let imp_simp = simplify_type(
self.tcx,
imp.self_ty(),
TreatParams::ForLookup,
TreatProjections::ForLookup,
);
let imp_simp =
simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
imp_simp.map_or(false, |s| s == simp_rcvr_ty)
})
{
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rustc_middle::mir::interpret;
use rustc_middle::query::LocalCrate;
use rustc_middle::traits::specialization_graph;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
use rustc_middle::util::common::to_readable_str;
Expand Down Expand Up @@ -1881,7 +1881,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.tcx,
trait_ref.self_ty(),
TreatParams::AsCandidateKey,
TreatProjections::AsCandidateKey,
);

fx_hash_map
Expand Down
37 changes: 22 additions & 15 deletions compiler/rustc_middle/src/ty/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,22 @@ pub enum TreatParams {
AsCandidateKey,
/// Treat parameters as placeholders in the given environment. This is the
/// correct mode for *lookup*, as during candidate selection.
///
/// This also treats projections with inference variables as infer vars
/// since they could be further normalized.
ForLookup,
/// Treat parameters as placeholders in the given environment. This is the
/// correct mode for *lookup*, as during candidate selection.
///
/// N.B. during deep rejection, this acts identically to `ForLookup`.
NextSolverLookup,
}

/// During fast-rejection, we have the choice of treating projection types
/// as either simplifyable or not, depending on whether we expect the projection
/// to be normalized/rigid.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum TreatProjections {
/// In candidates, we may be able to normalize the projection
/// after instantiating the candidate and equating it with a goal.
///
/// We must assume that the `impl<T> Trait<T> for <T as Id>::This`
/// can apply to all self types so we don't return a simplified type
/// for `<T as Id>::This`.
AsCandidateKey,
/// In the old solver we don't try to normalize projections
/// when looking up impls and only access them by using the
/// current self type. This means that if the self type is
Expand Down Expand Up @@ -107,7 +108,6 @@ pub fn simplify_type<'tcx>(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
treat_params: TreatParams,
treat_projections: TreatProjections,
) -> Option<SimplifiedType> {
match *ty.kind() {
ty::Bool => Some(BoolSimplifiedType),
Expand Down Expand Up @@ -136,13 +136,20 @@ pub fn simplify_type<'tcx>(
ty::FnPtr(f) => Some(FunctionSimplifiedType(f.skip_binder().inputs().len())),
ty::Placeholder(..) => Some(PlaceholderSimplifiedType),
ty::Param(_) => match treat_params {
TreatParams::ForLookup => Some(PlaceholderSimplifiedType),
TreatParams::ForLookup | TreatParams::NextSolverLookup => {
Some(PlaceholderSimplifiedType)
}
TreatParams::AsCandidateKey => None,
},
ty::Alias(..) => match treat_projections {
TreatProjections::ForLookup if !ty.needs_infer() => Some(PlaceholderSimplifiedType),
TreatProjections::NextSolverLookup => Some(PlaceholderSimplifiedType),
TreatProjections::AsCandidateKey | TreatProjections::ForLookup => None,
ty::Alias(..) => match treat_params {
// When treating `ty::Param` as a placeholder, projections also
// don't unify with anything else as long as they are fully normalized.
//
// We will have to be careful with lazy normalization here.
// FIXME(lazy_normalization): This is probably not right...
TreatParams::ForLookup if !ty.has_non_region_infer() => Some(PlaceholderSimplifiedType),
TreatParams::NextSolverLookup => Some(PlaceholderSimplifiedType),
TreatParams::ForLookup | TreatParams::AsCandidateKey => None,
},
ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
Expand Down Expand Up @@ -310,7 +317,7 @@ impl DeepRejectCtxt {
// Depending on the value of `treat_obligation_params`, we either
// treat generic parameters like placeholders or like inference variables.
ty::Param(_) => match self.treat_obligation_params {
TreatParams::ForLookup => false,
TreatParams::ForLookup | TreatParams::NextSolverLookup => false,
TreatParams::AsCandidateKey => true,
},

Expand Down Expand Up @@ -348,7 +355,7 @@ impl DeepRejectCtxt {
let k = impl_ct.kind();
match obligation_ct.kind() {
ty::ConstKind::Param(_) => match self.treat_obligation_params {
TreatParams::ForLookup => false,
TreatParams::ForLookup | TreatParams::NextSolverLookup => false,
TreatParams::AsCandidateKey => true,
},

Expand Down
26 changes: 11 additions & 15 deletions compiler/rustc_middle/src/ty/trait_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,7 @@ impl<'tcx> TyCtxt<'tcx> {
self_ty: Ty<'tcx>,
) -> impl Iterator<Item = DefId> + 'tcx {
let impls = self.trait_impls_of(trait_def_id);
if let Some(simp) = fast_reject::simplify_type(
self,
self_ty,
TreatParams::AsCandidateKey,
TreatProjections::AsCandidateKey,
) {
if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) {
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
return impls.iter().copied();
}
Expand Down Expand Up @@ -191,13 +186,17 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

// Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
// `TreatParams::AsCandidateKey` while actually adding them.
let treat_params = match treat_projections {
TreatProjections::NextSolverLookup => TreatParams::NextSolverLookup,
TreatProjections::ForLookup => TreatParams::ForLookup,
};
// This way, when searching for some impl for `T: Trait`, we do not look at any impls
// 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
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
if let Some(simp) =
fast_reject::simplify_type(self, self_ty, TreatParams::ForLookup, treat_projections)
{
if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) {
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
for &impl_def_id in impls {
if let result @ Some(_) = f(impl_def_id) {
Expand Down Expand Up @@ -258,12 +257,9 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
continue;
}

if let Some(simplified_self_ty) = fast_reject::simplify_type(
tcx,
impl_self_ty,
TreatParams::AsCandidateKey,
TreatProjections::AsCandidateKey,
) {
if let Some(simplified_self_ty) =
fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::AsCandidateKey)
{
impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
} else {
impls.blanket_impls.push(impl_def_id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::OverlapError;
use crate::traits;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};

pub use rustc_middle::traits::specialization_graph::*;
Expand Down Expand Up @@ -49,12 +49,9 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
/// Insert an impl into this set of children without comparing to any existing impls.
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
if let Some(st) = fast_reject::simplify_type(
tcx,
trait_ref.self_ty(),
TreatParams::AsCandidateKey,
TreatProjections::AsCandidateKey,
) {
if let Some(st) =
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
{
debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
} else {
Expand All @@ -69,12 +66,9 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
let vec: &mut Vec<DefId>;
if let Some(st) = fast_reject::simplify_type(
tcx,
trait_ref.self_ty(),
TreatParams::AsCandidateKey,
TreatProjections::AsCandidateKey,
) {
if let Some(st) =
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
{
debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
vec = self.non_blanket_impls.get_mut(&st).unwrap();
} else {
Expand Down Expand Up @@ -310,12 +304,8 @@ impl<'tcx> GraphExt<'tcx> for Graph {

let mut parent = trait_def_id;
let mut last_lint = None;
let simplified = fast_reject::simplify_type(
tcx,
trait_ref.self_ty(),
TreatParams::AsCandidateKey,
TreatProjections::AsCandidateKey,
);
let simplified =
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey);

// Descend the specialization tree, where `parent` is the current parent node.
loop {
Expand Down