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

Uplift more query stuff #125230

Merged
merged 5 commits into from
May 19, 2024
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
11 changes: 11 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4343,6 +4343,7 @@ dependencies = [
"rustc_hir_pretty",
"rustc_index",
"rustc_macros",
"rustc_next_trait_solver",
"rustc_query_system",
"rustc_serialize",
"rustc_session",
Expand Down Expand Up @@ -4451,7 +4452,13 @@ dependencies = [
name = "rustc_next_trait_solver"
version = "0.0.0"
dependencies = [
"derivative",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_macros",
"rustc_serialize",
"rustc_type_ir",
"rustc_type_ir_macros",
]

[[package]]
Expand Down Expand Up @@ -4752,6 +4759,7 @@ name = "rustc_trait_selection"
version = "0.0.0"
dependencies = [
"bitflags 2.5.0",
"derivative",
"itertools 0.12.1",
"rustc_ast",
"rustc_ast_ir",
Expand All @@ -4767,10 +4775,13 @@ dependencies = [
"rustc_next_trait_solver",
"rustc_parse_format",
"rustc_query_system",
"rustc_serialize",
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_transmute",
"rustc_type_ir",
"rustc_type_ir_macros",
"smallvec",
"tracing",
]
Expand Down
26 changes: 19 additions & 7 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,19 +385,31 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
a: Self,
b: Self,
) -> TypeTrace<'tcx> {
use GenericArgKind::*;
TypeTrace {
cause: cause.clone(),
values: match (a.unpack(), b.unpack()) {
(Lifetime(a), Lifetime(b)) => Regions(ExpectedFound::new(a_is_expected, a, b)),
(Type(a), Type(b)) => Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
(Const(a), Const(b)) => {
(GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
Regions(ExpectedFound::new(a_is_expected, a, b))
}
(GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
Terms(ExpectedFound::new(a_is_expected, a.into(), b.into()))
}
(GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
Terms(ExpectedFound::new(a_is_expected, a.into(), b.into()))
}

(Lifetime(_), Type(_) | Const(_))
| (Type(_), Lifetime(_) | Const(_))
| (Const(_), Lifetime(_) | Type(_)) => {
(
GenericArgKind::Lifetime(_),
GenericArgKind::Type(_) | GenericArgKind::Const(_),
)
| (
GenericArgKind::Type(_),
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_),
)
| (
GenericArgKind::Const(_),
GenericArgKind::Lifetime(_) | GenericArgKind::Type(_),
) => {
bug!("relating different kinds: {a:?} {b:?}")
}
},
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ impl<T: Hash> Hash for Obligation<'_, T> {
}
}

impl<'tcx, P> From<Obligation<'tcx, P>> for ty::Goal<'tcx, P> {
impl<'tcx, P> From<Obligation<'tcx, P>> for solve::Goal<'tcx, P> {
fn from(value: Obligation<'tcx, P>) -> Self {
ty::Goal { param_env: value.param_env, predicate: value.predicate }
solve::Goal { param_env: value.param_env, predicate: value.predicate }
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_next_trait_solver = { path = "../rustc_next_trait_solver" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ macro_rules! arena_types {
[] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>,
[] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>,
[] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>,
[] canonical_goal_evaluation: rustc_middle::traits::solve::inspect::GoalEvaluationStep<'tcx>,
[] canonical_goal_evaluation: rustc_next_trait_solver::solve::inspect::GoalEvaluationStep<rustc_middle::ty::TyCtxt<'tcx>>,
[] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>,
[] type_op_subtype:
rustc_middle::infer::canonical::Canonical<'tcx,
Expand Down
155 changes: 6 additions & 149 deletions compiler/rustc_middle/src/infer/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,20 @@

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lock;
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use rustc_type_ir::Canonical as IrCanonical;
use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo;
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
pub use rustc_type_ir as ir;
pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind};
use smallvec::SmallVec;
use std::collections::hash_map::Entry;
use std::ops::Index;

use crate::infer::MemberConstraint;
use crate::mir::ConstraintCategory;
use crate::ty::GenericArg;
use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt, TypeFlags, TypeVisitableExt};

pub type Canonical<'tcx, V> = IrCanonical<TyCtxt<'tcx>, V>;

pub type CanonicalVarInfo<'tcx> = IrCanonicalVarInfo<TyCtxt<'tcx>>;
use crate::ty::{self, List, Region, Ty, TyCtxt, TypeFlags, TypeVisitableExt};

pub type Canonical<'tcx, V> = ir::Canonical<TyCtxt<'tcx>, V>;
pub type CanonicalVarInfo<'tcx> = ir::CanonicalVarInfo<TyCtxt<'tcx>>;
pub type CanonicalVarValues<'tcx> = ir::CanonicalVarValues<TyCtxt<'tcx>>;
pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>;

impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
Expand All @@ -51,74 +48,6 @@ impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
}
}

/// A set of values corresponding to the canonical variables from some
/// `Canonical`. You can give these values to
/// `canonical_value.instantiate` to instantiate them into the canonical
/// value at the right places.
///
/// When you canonicalize a value `V`, you get back one of these
/// vectors with the original values that were replaced by canonical
/// variables. You will need to supply it later to instantiate the
/// canonicalized query response.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)]
pub struct CanonicalVarValues<'tcx> {
pub var_values: ty::GenericArgsRef<'tcx>,
}

impl CanonicalVarValues<'_> {
pub fn is_identity(&self) -> bool {
self.var_values.iter().enumerate().all(|(bv, arg)| match arg.unpack() {
ty::GenericArgKind::Lifetime(r) => {
matches!(*r, ty::ReBound(ty::INNERMOST, br) if br.var.as_usize() == bv)
}
ty::GenericArgKind::Type(ty) => {
matches!(*ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var.as_usize() == bv)
}
ty::GenericArgKind::Const(ct) => {
matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if bc.as_usize() == bv)
}
})
}

pub fn is_identity_modulo_regions(&self) -> bool {
let mut var = ty::BoundVar::ZERO;
for arg in self.var_values {
match arg.unpack() {
ty::GenericArgKind::Lifetime(r) => {
if let ty::ReBound(ty::INNERMOST, br) = *r
&& var == br.var
{
var = var + 1;
} else {
// It's ok if this region var isn't unique
}
}
ty::GenericArgKind::Type(ty) => {
if let ty::Bound(ty::INNERMOST, bt) = *ty.kind()
&& var == bt.var
{
var = var + 1;
} else {
return false;
}
}
ty::GenericArgKind::Const(ct) => {
if let ty::ConstKind::Bound(ty::INNERMOST, bc) = ct.kind()
&& var == bc
{
var = var + 1;
} else {
return false;
}
}
}
}

true
}
}

/// When we canonicalize a value to form a query, we wind up replacing
/// various parts of it with canonical variables. This struct stores
/// those replaced bits to remember for when we process the query
Expand Down Expand Up @@ -218,78 +147,6 @@ TrivialTypeTraversalImpls! {
crate::infer::canonical::Certainty,
}

impl<'tcx> CanonicalVarValues<'tcx> {
// Given a list of canonical variables, construct a set of values which are
// the identity response.
pub fn make_identity(
tcx: TyCtxt<'tcx>,
infos: CanonicalVarInfos<'tcx>,
) -> CanonicalVarValues<'tcx> {
CanonicalVarValues {
var_values: tcx.mk_args_from_iter(infos.iter().enumerate().map(
|(i, info)| -> ty::GenericArg<'tcx> {
match info.kind {
CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
Ty::new_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i).into())
.into()
}
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => {
let br = ty::BoundRegion {
var: ty::BoundVar::from_usize(i),
kind: ty::BrAnon,
};
ty::Region::new_bound(tcx, ty::INNERMOST, br).into()
}
CanonicalVarKind::Effect => ty::Const::new_bound(
tcx,
ty::INNERMOST,
ty::BoundVar::from_usize(i),
tcx.types.bool,
)
.into(),
CanonicalVarKind::Const(_, ty)
| CanonicalVarKind::PlaceholderConst(_, ty) => ty::Const::new_bound(
tcx,
ty::INNERMOST,
ty::BoundVar::from_usize(i),
ty,
)
.into(),
}
},
)),
}
}

/// Creates dummy var values which should not be used in a
/// canonical response.
pub fn dummy() -> CanonicalVarValues<'tcx> {
CanonicalVarValues { var_values: ty::List::empty() }
}

#[inline]
pub fn len(&self) -> usize {
self.var_values.len()
}
}

impl<'a, 'tcx> IntoIterator for &'a CanonicalVarValues<'tcx> {
type Item = GenericArg<'tcx>;
type IntoIter = ::std::iter::Copied<::std::slice::Iter<'a, GenericArg<'tcx>>>;

fn into_iter(self) -> Self::IntoIter {
self.var_values.iter()
}
}

impl<'tcx> Index<BoundVar> for CanonicalVarValues<'tcx> {
type Output = GenericArg<'tcx>;

fn index(&self, value: BoundVar) -> &GenericArg<'tcx> {
&self.var_values[value.as_usize()]
}
}

#[derive(Default)]
pub struct CanonicalParamEnvCache<'tcx> {
map: Lock<
Expand Down
29 changes: 2 additions & 27 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ pub mod specialization_graph;
mod structural_impls;
pub mod util;

use crate::infer::canonical::Canonical;
use crate::mir::ConstraintCategory;
use crate::ty::abstract_const::NotConstEvaluatable;
use crate::ty::GenericArgsRef;
Expand All @@ -32,6 +31,8 @@ use std::borrow::Cow;
use std::hash::{Hash, Hasher};

pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
// FIXME: Remove this import and import via `solve::`
pub use rustc_next_trait_solver::solve::BuiltinImplSource;

/// Depending on the stage of compilation, we want projection to be
/// more or less conservative.
Expand Down Expand Up @@ -736,32 +737,6 @@ pub struct ImplSourceUserDefinedData<'tcx, N> {
pub nested: Vec<N>,
}

#[derive(Copy, Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Debug)]
pub enum BuiltinImplSource {
/// Some builtin impl we don't need to differentiate. This should be used
/// unless more specific information is necessary.
Misc,
/// A builtin impl for trait objects.
///
/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will
/// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
/// in that vtable.
Object { vtable_base: usize },
/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will
/// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable
/// within that vtable.
TraitUpcasting { vtable_vptr_slot: Option<usize> },
/// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`.
///
/// This needs to be a separate variant as it is still unstable and we need to emit
/// a feature error when using it on stable.
TupleUnsizing,
}

TrivialTypeTraversalImpls! { BuiltinImplSource }

#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum ObjectSafetyViolation {
/// `Self: Sized` declared on the trait.
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_middle/src/traits/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use crate::ty::GenericArg;
use crate::ty::{self, Ty, TyCtxt};
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
use rustc_span::Span;
// FIXME: Remove this import and import via `traits::solve`.
pub use rustc_next_trait_solver::solve::NoSolution;

pub mod type_op {
use crate::ty::fold::TypeFoldable;
Expand Down Expand Up @@ -89,9 +91,6 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;

#[derive(Copy, Clone, Debug, Hash, HashStable, PartialEq, Eq)]
pub struct NoSolution;

impl<'tcx> From<TypeError<'tcx>> for NoSolution {
fn from(_: TypeError<'tcx>) -> NoSolution {
NoSolution
Expand Down
Loading
Loading