Remove lint allows from new solver stuff

This commit is contained in:
Chayim Refael Friedman 2025-10-17 06:46:34 +03:00
parent 6232ba8d08
commit 369715b77c
57 changed files with 526 additions and 1267 deletions

View file

@ -1,10 +1,10 @@
//! `TyBuilder`, a helper for building instances of `Ty` and related types.
use chalk_ir::{
DebruijnIndex, Scalar,
DebruijnIndex,
cast::{Cast, Caster},
};
use hir_def::{GenericDefId, GenericParamId, TraitId, builtin_type::BuiltinType};
use hir_def::{GenericDefId, GenericParamId, TraitId};
use smallvec::SmallVec;
use crate::{
@ -18,7 +18,7 @@ use crate::{
DbInterner, EarlyBinder,
mapping::{ChalkToNextSolver, NextSolverToChalk},
},
primitive, to_chalk_trait_id,
to_chalk_trait_id,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@ -137,23 +137,6 @@ impl TyBuilder<()> {
TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize)).intern(Interner)
}
pub(crate) fn builtin(builtin: BuiltinType) -> Ty {
match builtin {
BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(Interner),
BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(Interner),
BuiltinType::Str => TyKind::Str.intern(Interner),
BuiltinType::Int(t) => {
TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(Interner)
}
BuiltinType::Uint(t) => {
TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(Interner)
}
BuiltinType::Float(t) => {
TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(Interner)
}
}
}
pub(crate) fn unknown_subst(
db: &dyn HirDatabase,
def: impl Into<GenericDefId>,

View file

@ -6,74 +6,28 @@ mod tests;
use base_db::Crate;
use hir_def::{
EnumVariantId, GeneralConstId, HasModule, StaticId,
expr_store::{Body, HygieneId, path::Path},
expr_store::Body,
hir::{Expr, ExprId},
resolver::{Resolver, ValueNs},
type_ref::LiteralConstRef,
};
use hir_expand::Lookup;
use rustc_type_ir::{UnevaluatedConst, inherent::IntoKind};
use stdx::never;
use rustc_type_ir::inherent::IntoKind;
use triomphe::Arc;
use crate::{
MemoryMap, TraitEnvironment,
LifetimeElisionKind, MemoryMap, TraitEnvironment, TyLoweringContext,
db::HirDatabase,
display::DisplayTarget,
generics::Generics,
infer::InferenceContext,
mir::{MirEvalError, MirLowerError},
next_solver::{
Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs,
ParamConst, SolverDefId, Ty, ValueConst,
SolverDefId, Ty, ValueConst,
},
};
use super::mir::{interpret_mir, lower_to_mir, pad16};
pub(crate) fn path_to_const<'a, 'g>(
db: &'a dyn HirDatabase,
resolver: &Resolver<'a>,
path: &Path,
args: impl FnOnce() -> &'g Generics,
_expected_ty: Ty<'a>,
) -> Option<Const<'a>> {
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
match resolver.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT) {
Some(ValueNs::GenericParam(p)) => {
let args = args();
match args
.type_or_const_param(p.into())
.and_then(|(idx, p)| p.const_param().map(|p| (idx, p.clone())))
{
Some((idx, _param)) => {
Some(Const::new_param(interner, ParamConst { index: idx as u32, id: p }))
}
None => {
never!(
"Generic list doesn't contain this param: {:?}, {:?}, {:?}",
args,
path,
p
);
None
}
}
}
Some(ValueNs::ConstId(c)) => {
let args = GenericArgs::new_from_iter(interner, []);
Some(Const::new(
interner,
rustc_type_ir::ConstKind::Unevaluated(UnevaluatedConst::new(
SolverDefId::ConstId(c),
args,
)),
))
}
_ => None,
}
}
pub fn unknown_const<'db>(_ty: Ty<'db>) -> Const<'db> {
Const::new(DbInterner::conjure(), rustc_type_ir::ConstKind::Error(ErrorGuaranteed))
}
@ -279,8 +233,14 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd
return unknown_const(infer[expr]);
}
if let Expr::Path(p) = &ctx.body[expr] {
let resolver = &ctx.resolver;
if let Some(c) = path_to_const(ctx.db, resolver, p, || ctx.generics(), infer[expr]) {
let mut ctx = TyLoweringContext::new(
ctx.db,
&ctx.resolver,
ctx.body,
ctx.generic_def,
LifetimeElisionKind::Infer,
);
if let Some(c) = ctx.path_to_const(p) {
return c;
}
}

View file

@ -1062,9 +1062,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
TyKind::Str => write!(f, "str")?,
TyKind::Bool => write!(f, "bool")?,
TyKind::Char => write!(f, "char")?,
TyKind::Float(t) => write!(f, "{}", primitive::float_ty_to_string_ns(t))?,
TyKind::Int(t) => write!(f, "{}", primitive::int_ty_to_string_ns(t))?,
TyKind::Uint(t) => write!(f, "{}", primitive::uint_ty_to_string_ns(t))?,
TyKind::Float(t) => write!(f, "{}", primitive::float_ty_to_string(t))?,
TyKind::Int(t) => write!(f, "{}", primitive::int_ty_to_string(t))?,
TyKind::Uint(t) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
TyKind::Slice(t) => {
write!(f, "[")?;
t.hir_fmt(f)?;

View file

@ -7,7 +7,6 @@ use hir_def::{
TypeAliasId, TypeOrConstParamId, TypeParamId, hir::generics::LocalTypeOrConstParamId,
lang_item::LangItem, signatures::TraitFlags,
};
use intern::Symbol;
use rustc_hash::FxHashSet;
use rustc_type_ir::{
AliasTyKind, ClauseKind, PredicatePolarity, TypeSuperVisitable as _, TypeVisitable as _,
@ -441,8 +440,7 @@ fn receiver_is_dispatchable<'db>(
// Type `U`
// FIXME: That seems problematic to fake a generic param like that?
let unsized_self_ty =
crate::next_solver::Ty::new_param(interner, self_param_id, u32::MAX, Symbol::empty());
let unsized_self_ty = crate::next_solver::Ty::new_param(interner, self_param_id, u32::MAX);
// `Receiver[Self => U]`
let unsized_receiver_ty = receiver_for_self_ty(interner, func, receiver_ty, unsized_self_ty);
@ -454,8 +452,8 @@ fn receiver_is_dispatchable<'db>(
TraitRef::new(interner, unsize_did.into(), [self_param_ty, unsized_self_ty]);
// U: Trait<Arg1, ..., ArgN>
let args = GenericArgs::for_item(interner, trait_.into(), |name, index, kind, _| {
if index == 0 { unsized_self_ty.into() } else { mk_param(interner, index, name, kind) }
let args = GenericArgs::for_item(interner, trait_.into(), |index, kind, _| {
if index == 0 { unsized_self_ty.into() } else { mk_param(interner, index, kind) }
});
let trait_predicate = TraitRef::new_from_args(interner, trait_.into(), args);
@ -494,8 +492,8 @@ fn receiver_for_self_ty<'db>(
let args = crate::next_solver::GenericArgs::for_item(
interner,
SolverDefId::FunctionId(func),
|name, index, kind, _| {
if index == 0 { self_ty.into() } else { mk_param(interner, index, name, kind) }
|index, kind, _| {
if index == 0 { self_ty.into() } else { mk_param(interner, index, kind) }
},
);

View file

@ -258,7 +258,7 @@ impl Generics {
}
/// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
pub fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
pub(crate) fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
Substitution::from_iter(
Interner,
self.iter_id().enumerate().map(|(index, id)| match id {

View file

@ -57,7 +57,6 @@ use triomphe::Arc;
use crate::{
ImplTraitId, IncorrectGenericsLenKind, PathLoweringDiagnostic, TargetFeatures,
db::{HirDatabase, InternedClosureId, InternedOpaqueTyId},
generics::Generics,
infer::{
coerce::{CoerceMany, DynamicCoerceMany},
diagnostics::{Diagnostics, InferenceTyLoweringContext as TyLoweringContext},
@ -72,10 +71,7 @@ use crate::{
Tys,
abi::Safety,
fold::fold_tys,
infer::{
DefineOpaqueTypes,
traits::{Obligation, ObligationCause},
},
infer::traits::{Obligation, ObligationCause},
mapping::ChalkToNextSolver,
},
traits::FnTrait,
@ -763,8 +759,7 @@ pub(crate) struct InferenceContext<'body, 'db> {
/// and resolve the path via its methods. This will ensure proper error reporting.
pub(crate) resolver: Resolver<'db>,
target_features: OnceCell<(TargetFeatures, TargetFeatureIsSafeInTarget)>,
generic_def: GenericDefId,
generics: OnceCell<Generics>,
pub(crate) generic_def: GenericDefId,
table: unify::InferenceTable<'db>,
/// The traits in scope, disregarding block modules. This is used for caching purposes.
traits_in_scope: FxHashSet<TraitId>,
@ -873,7 +868,6 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
return_ty: types.error, // set in collect_* calls
types,
target_features: OnceCell::new(),
generics: OnceCell::new(),
table,
tuple_field_accesses_rev: Default::default(),
resume_yield_tys: None,
@ -902,10 +896,6 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
}
}
pub(crate) fn generics(&self) -> &Generics {
self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def))
}
#[inline]
fn krate(&self) -> Crate {
self.resolver.krate()
@ -1133,7 +1123,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
GenericArgs::for_item_with_defaults(
self.interner(),
va_list.into(),
|_, _, id, _| self.table.next_var_for_param(id),
|_, id, _| self.table.next_var_for_param(id),
),
),
None => self.err_ty(),
@ -1676,7 +1666,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
.table
.infer_ctxt
.at(&ObligationCause::new(), self.table.trait_env.env)
.eq(DefineOpaqueTypes::Yes, expected, actual)
.eq(expected, actual)
.map(|infer_ok| self.table.register_infer_ok(infer_ok));
if let Err(_err) = result {
// FIXME: Emit diagnostic.

View file

@ -26,7 +26,7 @@ use crate::{
PolyProjectionPredicate, Predicate, PredicateKind, SolverDefId, Ty, TyKind,
abi::Safety,
infer::{
BoundRegionConversionTime, DefineOpaqueTypes, InferOk, InferResult,
BoundRegionConversionTime, InferOk, InferResult,
traits::{ObligationCause, PredicateObligations},
},
util::explicit_item_bounds,
@ -307,7 +307,7 @@ impl<'db> InferenceContext<'_, 'db> {
.table
.infer_ctxt
.at(&ObligationCause::new(), self.table.trait_env.env)
.eq(DefineOpaqueTypes::Yes, inferred_fnptr_sig, generalized_fnptr_sig)
.eq(inferred_fnptr_sig, generalized_fnptr_sig)
.map(|infer_ok| self.table.register_infer_ok(infer_ok));
let resolved_sig =
@ -692,18 +692,16 @@ impl<'db> InferenceContext<'_, 'db> {
let InferOk { value: (), obligations } = table
.infer_ctxt
.at(&cause, table.trait_env.env)
.eq(DefineOpaqueTypes::Yes, expected_ty, supplied_ty)?;
.eq(expected_ty, supplied_ty)?;
all_obligations.extend(obligations);
}
let supplied_output_ty = supplied_sig.output();
let cause = ObligationCause::new();
let InferOk { value: (), obligations } =
table.infer_ctxt.at(&cause, table.trait_env.env).eq(
DefineOpaqueTypes::Yes,
expected_sigs.liberated_sig.output(),
supplied_output_ty,
)?;
let InferOk { value: (), obligations } = table
.infer_ctxt
.at(&cause, table.trait_env.env)
.eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?;
all_obligations.extend(obligations);
let inputs = supplied_sig

View file

@ -63,7 +63,7 @@ use crate::{
GenericArgs, PolyFnSig, PredicateKind, Region, RegionKind, SolverDefId, TraitRef, Ty,
TyKind,
infer::{
DefineOpaqueTypes, InferCtxt, InferOk, InferResult,
InferCtxt, InferOk, InferResult,
relate::RelateResult,
select::{ImplSource, SelectionError},
traits::{Obligation, ObligationCause, PredicateObligation, PredicateObligations},
@ -149,7 +149,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
let res = if this.use_lub {
at.lub(b, a)
} else {
at.sup(DefineOpaqueTypes::Yes, b, a)
at.sup(b, a)
.map(|InferOk { value: (), obligations }| InferOk { value: b, obligations })
};
@ -1460,19 +1460,12 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
//
// Another example is `break` with no argument expression.
assert!(expression_ty.is_unit(), "if let hack without unit type");
icx.table
.infer_ctxt
.at(cause, icx.table.trait_env.env)
.eq(
// needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
DefineOpaqueTypes::Yes,
expected,
found,
)
.map(|infer_ok| {
icx.table.infer_ctxt.at(cause, icx.table.trait_env.env).eq(expected, found).map(
|infer_ok| {
icx.table.register_infer_ok(infer_ok);
expression_ty
})
},
)
};
debug!(?result);

View file

@ -46,7 +46,7 @@ use crate::{
AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, TraitRef, Ty, TyKind,
TypeError,
infer::{
DefineOpaqueTypes, InferOk,
InferOk,
traits::{Obligation, ObligationCause},
},
obligation_ctxt::ObligationCtxt,
@ -1333,7 +1333,7 @@ impl<'db> InferenceContext<'_, 'db> {
self.interner(),
box_id.into(),
[inner_ty.into()],
|_, _, id, _| self.table.next_var_for_param(id),
|_, id, _| self.table.next_var_for_param(id),
),
)
} else {
@ -2122,7 +2122,7 @@ impl<'db> InferenceContext<'_, 'db> {
.table
.infer_ctxt
.at(&ObligationCause::new(), this.table.trait_env.env)
.eq(DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty);
.eq(formal_input_ty, coerced_ty);
// If neither check failed, the types are compatible
match formal_ty_error {

View file

@ -358,7 +358,7 @@ impl<'db> InferenceContext<'_, 'db> {
self.interner(),
box_adt.into(),
std::iter::once(inner_ty.into()).chain(alloc_ty.map(Into::into)),
|_, _, id, _| self.table.next_var_for_param(id),
|_, id, _| self.table.next_var_for_param(id),
),
)
}

View file

@ -118,7 +118,7 @@ impl<'db> InferenceContext<'_, 'db> {
self.interner(),
generic_def.into(),
self_subst.iter().flat_map(|it| it.iter()).chain(substs.iter().skip(parent_substs_len)),
|_, _, id, _| GenericArg::error_from_id(self.interner(), id),
|_, id, _| GenericArg::error_from_id(self.interner(), id),
);
Some(ValuePathResolution::GenericDef(value_def, generic_def, substs))
@ -352,7 +352,7 @@ impl<'db> InferenceContext<'_, 'db> {
self.interner(),
trait_.into(),
[ty.into()],
|_, _, id, _| self.table.next_var_for_param(id),
|_, id, _| self.table.next_var_for_param(id),
);
let trait_ref = TraitRef::new(self.interner(), trait_.into(), args);
self.table.register_predicate(Obligation::new(

View file

@ -25,7 +25,7 @@ use crate::{
SolverDefId, SolverDefIds, TraitRef, Ty, TyKind, TypingMode,
fulfill::{FulfillmentCtxt, NextSolverError},
infer::{
DbInternerInferExt, DefineOpaqueTypes, InferCtxt, InferOk, InferResult,
DbInternerInferExt, InferCtxt, InferOk, InferResult,
at::ToTrace,
snapshot::CombinedSnapshot,
traits::{Obligation, ObligationCause, PredicateObligation},
@ -148,7 +148,7 @@ fn could_unify_impl<'db>(
let ((ty1_with_vars, ty2_with_vars), _) = infcx.instantiate_canonical(tys);
let mut ctxt = ObligationCtxt::new(&infcx);
let can_unify = at
.eq(DefineOpaqueTypes::No, ty1_with_vars, ty2_with_vars)
.eq(ty1_with_vars, ty2_with_vars)
.map(|infer_ok| ctxt.register_infer_ok_obligations(infer_ok))
.is_ok();
can_unify && select(&mut ctxt).is_empty()
@ -452,11 +452,7 @@ impl<'db> InferenceTable<'db> {
/// Unify two relatable values (e.g. `Ty`) and return new trait goals arising from it, so the
/// caller needs to deal with them.
pub(crate) fn try_unify<T: ToTrace<'db>>(&mut self, t1: T, t2: T) -> InferResult<'db, ()> {
self.infer_ctxt.at(&ObligationCause::new(), self.trait_env.env).eq(
DefineOpaqueTypes::Yes,
t1,
t2,
)
self.infer_ctxt.at(&ObligationCause::new(), self.trait_env.env).eq(t1, t2)
}
pub(crate) fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {

View file

@ -82,7 +82,7 @@ use traits::FnTrait;
use triomphe::Arc;
use crate::{
builder::{ParamKind, TyBuilder},
builder::TyBuilder,
chalk_ext::*,
db::HirDatabase,
display::{DisplayTarget, HirDisplay},

View file

@ -434,13 +434,16 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
}
fn lower_path_inner(&mut self, typeable: TyDefId, infer_args: bool) -> Ty {
let interner = DbInterner::conjure();
let generic_def = match typeable {
TyDefId::BuiltinType(builtin) => return TyBuilder::builtin(builtin),
TyDefId::BuiltinType(builtin) => {
return crate::next_solver::Ty::from_builtin_type(interner, builtin)
.to_chalk(interner);
}
TyDefId::AdtId(it) => it.into(),
TyDefId::TypeAliasId(it) => it.into(),
};
let substs = self.substs_from_path_segment(generic_def, infer_args, None, false);
let interner = DbInterner::conjure();
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
self.ctx.db.ty(typeable).instantiate(interner, args).to_chalk(interner)
}

View file

@ -5,8 +5,6 @@
//! - Building the type for an item: This happens through the `ty` query.
//!
//! This usually involves resolving names, collecting generic arguments etc.
#![allow(unused)]
// FIXME(next-solver): this should get removed as things get moved to rustc_type_ir from chalk_ir
pub(crate) mod path;
use std::{
@ -20,19 +18,15 @@ use either::Either;
use hir_def::{
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId,
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
TypeParamId, VariantId,
expr_store::{
ExpressionStore,
path::{GenericArg, Path},
},
LocalFieldId, Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, TypeParamId,
VariantId,
expr_store::{ExpressionStore, HygieneId, path::Path},
hir::generics::{
GenericParamDataRef, TypeOrConstParamData, TypeParamData, TypeParamProvenance,
WherePredicate,
GenericParamDataRef, TypeOrConstParamData, TypeParamProvenance, WherePredicate,
},
item_tree::FieldsShape,
lang_item::LangItem,
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs, ValueNs},
signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
type_ref::{
ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier,
@ -40,7 +34,6 @@ use hir_def::{
},
};
use hir_expand::name::Name;
use intern::{Symbol, sym};
use la_arena::{Arena, ArenaMap, Idx};
use path::{PathDiagnosticCallback, PathLoweringContext};
use rustc_ast_ir::Mutability;
@ -50,7 +43,7 @@ use rustc_type_ir::{
AliasTyKind, ConstKind, DebruijnIndex, ExistentialPredicate, ExistentialProjection,
ExistentialTraitRef, FnSig, OutlivesPredicate,
TyKind::{self},
TypeFoldable, TypeFolder, TypeVisitableExt, Upcast,
TypeVisitableExt,
inherent::{GenericArg as _, GenericArgs as _, IntoKind as _, Region as _, SliceLike, Ty as _},
};
use salsa::plumbing::AsId;
@ -59,19 +52,17 @@ use stdx::never;
use triomphe::Arc;
use crate::{
FnAbi, ImplTraitId, Interner, ParamKind, TraitEnvironment, TyDefId, TyLoweringDiagnostic,
TyLoweringDiagnosticKind, ValueTyDefId,
consteval::{intern_const_ref, path_to_const, unknown_const_as_generic},
FnAbi, ImplTraitId, TraitEnvironment, TyDefId, TyLoweringDiagnostic, TyLoweringDiagnosticKind,
ValueTyDefId,
consteval::intern_const_ref,
db::HirDatabase,
generics::{Generics, generics, trait_self_param_idx},
lower::{Diagnostics, PathDiagnosticCallbackData, create_diagnostics},
next_solver::{
AdtDef, AliasTy, Binder, BoundExistentialPredicates, BoundRegionKind, BoundTyKind,
BoundVarKind, BoundVarKinds, Clause, Clauses, Const, DbInterner, EarlyBinder,
EarlyParamRegion, ErrorGuaranteed, GenericArgs, ParamConst, ParamEnv, PolyFnSig, Predicate,
Region, SolverDefId, TraitPredicate, TraitRef, Ty, Tys,
abi::Safety,
mapping::{ChalkToNextSolver, convert_ty_for_result},
AliasTy, Binder, BoundExistentialPredicates, Clause, Clauses, Const, DbInterner,
EarlyBinder, EarlyParamRegion, ErrorGuaranteed, GenericArg, GenericArgs, ParamConst,
ParamEnv, PolyFnSig, Predicate, Region, SolverDefId, TraitPredicate, TraitRef, Ty, Tys,
UnevaluatedConst, abi::Safety,
},
};
@ -95,11 +86,11 @@ struct ImplTraitLoweringState<'db> {
mode: ImplTraitLoweringMode,
// This is structured as a struct with fields and not as an enum because it helps with the borrow checker.
opaque_type_data: Arena<ImplTrait<'db>>,
param_and_variable_counter: u16,
}
impl<'db> ImplTraitLoweringState<'db> {
fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState<'db> {
Self { mode, opaque_type_data: Arena::new(), param_and_variable_counter: 0 }
Self { mode, opaque_type_data: Arena::new() }
}
}
@ -279,8 +270,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
let const_ref = &self.store[const_ref.expr];
match const_ref {
hir_def::hir::Expr::Path(path) => {
path_to_const(self.db, self.resolver, path, || self.generics(), const_type)
.unwrap_or_else(|| unknown_const(const_type))
self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type))
}
hir_def::hir::Expr::Literal(literal) => intern_const_ref(
self.db,
@ -324,9 +314,39 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
}
}
pub(crate) fn path_to_const(&mut self, path: &Path) -> Option<Const<'db>> {
match self.resolver.resolve_path_in_value_ns_fully(self.db, path, HygieneId::ROOT) {
Some(ValueNs::GenericParam(p)) => {
let args = self.generics();
match args.type_or_const_param_idx(p.into()) {
Some(idx) => Some(self.const_param(p, idx as u32)),
None => {
never!(
"Generic list doesn't contain this param: {:?}, {:?}, {:?}",
args,
path,
p
);
None
}
}
}
Some(ValueNs::ConstId(c)) => {
let args = GenericArgs::new_from_iter(self.interner, []);
Some(Const::new(
self.interner,
rustc_type_ir::ConstKind::Unevaluated(UnevaluatedConst::new(
SolverDefId::ConstId(c),
args,
)),
))
}
_ => None,
}
}
pub(crate) fn lower_path_as_const(&mut self, path: &Path, const_type: Ty<'db>) -> Const<'db> {
path_to_const(self.db, self.resolver, path, || self.generics(), const_type)
.unwrap_or_else(|| unknown_const(const_type))
self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type))
}
fn generics(&self) -> &Generics {
@ -338,12 +358,12 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
.is_some_and(|disallow_params_after| index >= disallow_params_after)
}
fn type_param(&mut self, id: TypeParamId, index: u32, name: Symbol) -> Ty<'db> {
fn type_param(&mut self, id: TypeParamId, index: u32) -> Ty<'db> {
if self.param_index_is_disallowed(index) {
// FIXME: Report an error.
Ty::new_error(self.interner, ErrorGuaranteed)
} else {
Ty::new_param(self.interner, id, index, name)
Ty::new_param(self.interner, id, index)
}
}
@ -387,20 +407,9 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
res = Some(TypeNs::GenericParam(type_param_id));
let generics = self.generics();
let (idx, data) =
let (idx, _data) =
generics.type_or_const_param(type_param_id.into()).expect("matching generics");
let type_data = match data {
TypeOrConstParamData::TypeParamData(ty) => ty,
_ => unreachable!(),
};
self.type_param(
type_param_id,
idx as u32,
type_data
.name
.as_ref()
.map_or_else(|| sym::MISSING_NAME, |d| d.symbol().clone()),
)
self.type_param(type_param_id, idx as u32)
}
&TypeRef::RawPtr(inner, mutability) => {
let inner_ty = self.lower_ty(inner);
@ -1058,10 +1067,7 @@ fn type_for_const<'db>(db: &'db dyn HirDatabase, def: ConstId) -> EarlyBinder<'d
/// Build the declared type of a static.
fn type_for_static<'db>(db: &'db dyn HirDatabase, def: StaticId) -> EarlyBinder<'db, Ty<'db>> {
let resolver = def.resolver(db);
let module = resolver.module();
let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block());
let data = db.static_signature(def);
let parent = def.loc(db).container;
let mut ctx = TyLoweringContext::new(
db,
&resolver,
@ -1177,7 +1183,6 @@ pub(crate) fn impl_self_ty_with_diagnostics_query<'db>(
impl_id: ImplId,
) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) {
let resolver = impl_id.resolver(db);
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
let impl_data = db.impl_signature(impl_id);
let mut ctx = TyLoweringContext::new(
@ -1451,7 +1456,6 @@ pub(crate) fn trait_environment_query<'db>(
return TraitEnvironment::empty(def.krate(db));
}
let interner = DbInterner::new_with(db, Some(def.krate(db)), None);
let resolver = def.resolver(db);
let mut ctx = TyLoweringContext::new(
db,
@ -1509,7 +1513,7 @@ pub(crate) fn trait_environment_query<'db>(
continue;
};
let idx = idx as u32 + generics.parent_count as u32;
let param_ty = Ty::new_param(ctx.interner, param_id, idx, p.name.clone());
let param_ty = Ty::new_param(ctx.interner, param_id, idx);
if explicitly_unsized_tys.contains(&param_ty) {
continue;
}
@ -1635,11 +1639,7 @@ where
return;
}
let param_name = param_data
.name
.as_ref()
.map_or_else(|| sym::MISSING_NAME, |name| name.symbol().clone());
let param_ty = Ty::new_param(interner, param_id, param_idx, param_name);
let param_ty = Ty::new_param(interner, param_id, param_idx);
if explicitly_unsized_tys.contains(&param_ty) {
return;
}
@ -1724,83 +1724,12 @@ fn implicitly_sized_clauses<'a, 'subst, 'db>(
)
}
pub(crate) fn make_binders<'db, T: rustc_type_ir::TypeVisitable<DbInterner<'db>>>(
interner: DbInterner<'db>,
generics: &Generics,
value: T,
) -> Binder<'db, T> {
Binder::bind_with_vars(
value,
BoundVarKinds::new_from_iter(
interner,
generics.iter_id().map(|x| match x {
hir_def::GenericParamId::ConstParamId(_) => BoundVarKind::Const,
hir_def::GenericParamId::TypeParamId(_) => BoundVarKind::Ty(BoundTyKind::Anon),
hir_def::GenericParamId::LifetimeParamId(_) => {
BoundVarKind::Region(BoundRegionKind::Anon)
}
}),
),
)
}
/// Checks if the provided generic arg matches its expected kind, then lower them via
/// provided closures. Use unknown if there was kind mismatch.
///
pub(crate) fn lower_generic_arg<'a, 'db, T>(
db: &'db dyn HirDatabase,
kind_id: GenericParamId,
arg: &'a GenericArg,
this: &mut T,
store: &ExpressionStore,
for_type: impl FnOnce(&mut T, TypeRefId) -> Ty<'db> + 'a,
for_const: impl FnOnce(&mut T, &ConstRef, Ty<'db>) -> Const<'db> + 'a,
for_const_ty_path_fallback: impl FnOnce(&mut T, &Path, Ty<'db>) -> Const<'db> + 'a,
for_lifetime: impl FnOnce(&mut T, &LifetimeRefId) -> Region<'db> + 'a,
) -> crate::next_solver::GenericArg<'db> {
let interner = DbInterner::new_with(db, None, None);
let kind = match kind_id {
GenericParamId::TypeParamId(_) => ParamKind::Type,
GenericParamId::ConstParamId(id) => {
let ty = db.const_param_ty(id);
ParamKind::Const(ty)
}
GenericParamId::LifetimeParamId(_) => ParamKind::Lifetime,
};
match (arg, kind) {
(GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, *type_ref).into(),
(GenericArg::Const(c), ParamKind::Const(c_ty)) => {
for_const(this, c, c_ty.to_nextsolver(interner)).into()
}
(GenericArg::Lifetime(lifetime_ref), ParamKind::Lifetime) => {
for_lifetime(this, lifetime_ref).into()
}
(GenericArg::Const(_), ParamKind::Type) => Ty::new_error(interner, ErrorGuaranteed).into(),
(GenericArg::Lifetime(_), ParamKind::Type) => {
Ty::new_error(interner, ErrorGuaranteed).into()
}
(GenericArg::Type(t), ParamKind::Const(c_ty)) => match &store[*t] {
TypeRef::Path(p) => {
for_const_ty_path_fallback(this, p, c_ty.to_nextsolver(interner)).into()
}
_ => unknown_const_as_generic(c_ty.to_nextsolver(interner)),
},
(GenericArg::Lifetime(_), ParamKind::Const(c_ty)) => {
unknown_const(c_ty.to_nextsolver(interner)).into()
}
(GenericArg::Type(_), ParamKind::Lifetime) => Region::error(interner).into(),
(GenericArg::Const(_), ParamKind::Lifetime) => Region::error(interner).into(),
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenericDefaults<'db>(
Option<Arc<[Option<EarlyBinder<'db, crate::next_solver::GenericArg<'db>>>]>>,
);
pub struct GenericDefaults<'db>(Option<Arc<[Option<EarlyBinder<'db, GenericArg<'db>>>]>>);
impl<'db> GenericDefaults<'db> {
#[inline]
pub fn get(&self, idx: usize) -> Option<EarlyBinder<'db, crate::next_solver::GenericArg<'db>>> {
pub fn get(&self, idx: usize) -> Option<EarlyBinder<'db, GenericArg<'db>>> {
self.0.as_ref()?[idx]
}
}
@ -1837,17 +1766,17 @@ pub(crate) fn generic_defaults_with_diagnostics_query(
let mut has_any_default = false;
let mut defaults = generic_params
.iter_parents_with_store()
.map(|((id, p), store)| {
.map(|((_id, p), store)| {
ctx.store = store;
let (result, has_default) = handle_generic_param(&mut ctx, idx, id, p, &generic_params);
let (result, has_default) = handle_generic_param(&mut ctx, idx, p);
has_any_default |= has_default;
idx += 1;
result
})
.collect::<Vec<_>>();
ctx.diagnostics.clear(); // Don't include diagnostics from the parent.
defaults.extend(generic_params.iter_self().map(|(id, p)| {
let (result, has_default) = handle_generic_param(&mut ctx, idx, id, p, &generic_params);
defaults.extend(generic_params.iter_self().map(|(_id, p)| {
let (result, has_default) = handle_generic_param(&mut ctx, idx, p);
has_any_default |= has_default;
idx += 1;
result
@ -1863,10 +1792,8 @@ pub(crate) fn generic_defaults_with_diagnostics_query(
fn handle_generic_param<'db>(
ctx: &mut TyLoweringContext<'db, '_>,
idx: usize,
id: GenericParamId,
p: GenericParamDataRef<'_>,
generic_params: &Generics,
) -> (Option<EarlyBinder<'db, crate::next_solver::GenericArg<'db>>>, bool) {
) -> (Option<EarlyBinder<'db, GenericArg<'db>>>, bool) {
ctx.lowering_param_default(idx as u32);
match p {
GenericParamDataRef::TypeParamData(p) => {
@ -1874,11 +1801,7 @@ pub(crate) fn generic_defaults_with_diagnostics_query(
(ty.map(|ty| EarlyBinder::bind(ty.into())), p.default.is_some())
}
GenericParamDataRef::ConstParamData(p) => {
let GenericParamId::ConstParamId(id) = id else {
unreachable!("Unexpected lifetime or type argument")
};
let mut val = p.default.map(|c| {
let val = p.default.map(|c| {
let param_ty = ctx.lower_ty(p.ty);
let c = ctx.lower_const(c, param_ty);
c.into()
@ -1999,11 +1922,6 @@ pub(crate) fn associated_ty_item_bounds<'db>(
db: &'db dyn HirDatabase,
type_alias: TypeAliasId,
) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> {
let trait_ = match type_alias.lookup(db).container {
ItemContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"),
};
let type_alias_data = db.type_alias_signature(type_alias);
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db);
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
@ -2051,7 +1969,7 @@ pub(crate) fn associated_ty_item_bounds<'db>(
p.term,
)),
),
rustc_type_ir::ClauseKind::TypeOutlives(outlives_predicate) => None,
rustc_type_ir::ClauseKind::TypeOutlives(_) => None,
rustc_type_ir::ClauseKind::RegionOutlives(_)
| rustc_type_ir::ClauseKind::ConstArgHasType(_, _)
| rustc_type_ir::ClauseKind::WellFormed(_)
@ -2066,15 +1984,15 @@ pub(crate) fn associated_ty_item_bounds<'db>(
});
}
if !ctx.unsized_types.contains(&self_ty) {
let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate());
if !ctx.unsized_types.contains(&self_ty)
&& let Some(sized_trait) = LangItem::Sized.resolve_trait(db, resolver.krate())
{
let sized_clause = Binder::dummy(ExistentialPredicate::Trait(ExistentialTraitRef::new(
interner,
trait_.into(),
[] as [crate::next_solver::GenericArg<'_>; 0],
sized_trait.into(),
[] as [GenericArg<'_>; 0],
)));
bounds.push(sized_clause);
bounds.shrink_to_fit();
}
EarlyBinder::bind(BoundExistentialPredicates::new_from_iter(interner, bounds))
@ -2117,7 +2035,6 @@ fn named_associated_type_shorthand_candidates<'db, R>(
) -> Option<R> {
let db = interner.db;
let mut search = |t: TraitRef<'db>| -> Option<R> {
let trait_id = t.def_id.0;
let mut checked_traits = FxHashSet::default();
let mut check_trait = |trait_ref: TraitRef<'db>| {
let trait_id = trait_ref.def_id.0;
@ -2192,10 +2109,7 @@ fn named_associated_type_shorthand_candidates<'db, R>(
let trait_generics = generics(db, trait_id.into());
tracing::debug!(?trait_generics);
if trait_generics[param_id.local_id()].is_trait_self() {
let args = crate::next_solver::GenericArgs::identity_for_item(
interner,
trait_id.into(),
);
let args = GenericArgs::identity_for_item(interner, trait_id.into());
let trait_ref = TraitRef::new_from_args(interner, trait_id.into(), args);
tracing::debug!(?args, ?trait_ref);
return search(trait_ref);

View file

@ -1,11 +1,8 @@
//! A wrapper around [`TyLoweringContext`] specifically for lowering paths.
use std::ops::Deref;
use either::Either;
use hir_def::{
AssocItemId, GenericDefId, GenericParamId, Lookup, TraitId, TypeAliasId,
builtin_type::BuiltinType,
GenericDefId, GenericParamId, Lookup, TraitId, TypeAliasId,
expr_store::{
ExpressionStore, HygieneId,
path::{GenericArg, GenericArgs, GenericArgsParentheses, Path, PathSegment, PathSegments},
@ -18,13 +15,11 @@ use hir_def::{
type_ref::{TypeRef, TypeRefId},
};
use hir_expand::name::Name;
use intern::sym;
use rustc_hash::FxHashSet;
use rustc_type_ir::{
AliasTerm, AliasTy, AliasTyKind, TypeVisitableExt,
inherent::{GenericArgs as _, IntoKind, Region as _, SliceLike, Ty as _},
AliasTerm, AliasTy, AliasTyKind,
inherent::{GenericArgs as _, Region as _, SliceLike, Ty as _},
};
use smallvec::{SmallVec, smallvec};
use smallvec::SmallVec;
use stdx::never;
use crate::{
@ -34,16 +29,12 @@ use crate::{
db::HirDatabase,
generics::{Generics, generics},
lower::PathDiagnosticCallbackData,
lower_nextsolver::{
LifetimeElisionKind, PredicateFilter, generic_predicates_filtered_by,
named_associated_type_shorthand_candidates,
},
lower_nextsolver::{LifetimeElisionKind, named_associated_type_shorthand_candidates},
next_solver::{
AdtDef, Binder, Clause, Const, DbInterner, ErrorGuaranteed, Predicate, ProjectionPredicate,
Region, SolverDefId, TraitRef, Ty,
Binder, Clause, Const, DbInterner, ErrorGuaranteed, Predicate, ProjectionPredicate, Region,
TraitRef, Ty,
mapping::{ChalkToNextSolver, convert_binder_to_early_binder},
},
primitive,
};
use super::{
@ -173,22 +164,6 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
}
}
fn prohibit_parenthesized_generic_args(&mut self) -> bool {
if let Some(generic_args) = self.current_or_prev_segment.args_and_bindings {
match generic_args.parenthesized {
GenericArgsParentheses::No => {}
GenericArgsParentheses::ReturnTypeNotation | GenericArgsParentheses::ParenSugar => {
let segment = self.current_segment_u32();
self.on_diagnostic(
PathLoweringDiagnostic::ParenthesizedGenericArgsWithoutFnTrait { segment },
);
return true;
}
}
}
false
}
// When calling this, the current segment is the resolved segment (we don't advance it yet).
pub(crate) fn lower_partly_resolved_path(
&mut self,
@ -274,19 +249,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
Ty::new_error(self.ctx.interner, ErrorGuaranteed)
}
Some(idx) => {
let (pidx, param) = generics.iter().nth(idx).unwrap();
let (pidx, _param) = generics.iter().nth(idx).unwrap();
assert_eq!(pidx, param_id.into());
let p = match param {
GenericParamDataRef::TypeParamData(p) => p,
_ => unreachable!(),
};
self.ctx.type_param(
param_id,
idx as u32,
p.name
.as_ref()
.map_or_else(|| sym::MISSING_NAME.clone(), |p| p.symbol().clone()),
)
self.ctx.type_param(param_id, idx as u32)
}
}
}
@ -520,11 +485,10 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
let Some(res) = res else {
return Ty::new_error(self.ctx.interner, ErrorGuaranteed);
};
let db = self.ctx.db;
let def = self.ctx.def;
let segment = self.current_or_prev_segment;
let assoc_name = segment.name;
let mut check_alias = |name: &Name, t: TraitRef<'db>, associated_ty: TypeAliasId| {
let check_alias = |name: &Name, t: TraitRef<'db>, associated_ty: TypeAliasId| {
if name != assoc_name {
return None;
}

View file

@ -37,7 +37,7 @@ use crate::{
Canonical, DbInterner, ErrorGuaranteed, GenericArgs, Goal, Predicate, Region, SolverDefId,
TraitRef, Ty, TyKind, TypingMode,
infer::{
DbInternerInferExt, DefineOpaqueTypes,
DbInternerInferExt,
traits::{Obligation, ObligationCause, PredicateObligation},
},
obligation_ctxt::ObligationCtxt,
@ -1654,7 +1654,7 @@ fn is_valid_trait_method_candidate<'db>(
let res = table
.infer_ctxt
.at(&ObligationCause::dummy(), table.trait_env.env)
.relate(DefineOpaqueTypes::No, expected_receiver, variance, receiver_ty);
.relate(expected_receiver, variance, receiver_ty);
let Ok(infer_ok) = res else {
return IsValidCandidate::No;
};

View file

@ -1,5 +1,4 @@
//! Things relevant to the next trait solver.
#![allow(unused, unreachable_pub)]
pub mod abi;
mod consts;

View file

@ -2,10 +2,9 @@
use std::hash::Hash;
use hir_def::{ConstParamId, TypeOrConstParamId};
use intern::{Interned, Symbol};
use hir_def::ConstParamId;
use macros::{TypeFoldable, TypeVisitable};
use rustc_ast_ir::{try_visit, visit::VisitorResult};
use rustc_ast_ir::visit::VisitorResult;
use rustc_type_ir::{
BoundVar, DebruijnIndex, FlagComputation, Flags, TypeFoldable, TypeSuperFoldable,
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, WithCachedTypeInfo,
@ -14,7 +13,7 @@ use rustc_type_ir::{
};
use crate::{
ConstScalar, MemoryMap,
MemoryMap,
interner::InternedWrapperNoDebug,
next_solver::{ClauseKind, ParamEnv},
};
@ -429,7 +428,7 @@ impl<'db> PlaceholderLike<DbInterner<'db>> for PlaceholderConst {
impl<'db> Relate<DbInterner<'db>> for ExprConst {
fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
relation: &mut R,
_relation: &mut R,
a: Self,
b: Self,
) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> {

View file

@ -1,9 +1,8 @@
//! Fold impls for the next-trait-solver.
use rustc_type_ir::{
BoundVar, DebruijnIndex, RegionKind, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt,
inherent::{IntoKind, Region as _},
DebruijnIndex, RegionKind, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
inherent::IntoKind,
};
use crate::next_solver::BoundConst;
@ -55,7 +54,7 @@ pub(crate) struct BoundVarReplacer<'db, D> {
}
impl<'db, D: BoundVarReplacerDelegate<'db>> BoundVarReplacer<'db, D> {
pub fn new(tcx: DbInterner<'db>, delegate: D) -> Self {
pub(crate) fn new(tcx: DbInterner<'db>, delegate: D) -> Self {
BoundVarReplacer { interner: tcx, current_index: DebruijnIndex::ZERO, delegate }
}
}

View file

@ -2,7 +2,7 @@
mod errors;
use std::{marker::PhantomData, mem, ops::ControlFlow, vec::ExtractIf};
use std::{mem, ops::ControlFlow};
use rustc_hash::FxHashSet;
use rustc_next_trait_solver::{
@ -46,6 +46,7 @@ pub struct FulfillmentCtxt<'db> {
/// outside of this snapshot leads to subtle bugs if the snapshot
/// gets rolled back. Because of this we explicitly check that we only
/// use the context in exactly this snapshot.
#[expect(unused)]
usable_in_snapshot: usize,
}
@ -69,10 +70,6 @@ impl<'db> ObligationStorage<'db> {
self.pending.push((obligation, stalled_on));
}
fn has_pending_obligations(&self) -> bool {
!self.pending.is_empty() || !self.overflowed.is_empty()
}
fn clone_pending(&self) -> PredicateObligations<'db> {
let mut obligations: PredicateObligations<'db> =
self.pending.iter().map(|(o, _)| o.clone()).collect();
@ -125,10 +122,10 @@ impl<'db> FulfillmentCtxt<'db> {
}
impl<'db> FulfillmentCtxt<'db> {
#[tracing::instrument(level = "trace", skip(self, infcx))]
#[tracing::instrument(level = "trace", skip(self, _infcx))]
pub(crate) fn register_predicate_obligation(
&mut self,
infcx: &InferCtxt<'db>,
_infcx: &InferCtxt<'db>,
obligation: PredicateObligation<'db>,
) {
// FIXME: See the comment in `try_evaluate_obligations()`.
@ -138,7 +135,7 @@ impl<'db> FulfillmentCtxt<'db> {
pub(crate) fn register_predicate_obligations(
&mut self,
infcx: &InferCtxt<'db>,
_infcx: &InferCtxt<'db>,
obligations: impl IntoIterator<Item = PredicateObligation<'db>>,
) {
// FIXME: See the comment in `try_evaluate_obligations()`.
@ -148,7 +145,7 @@ impl<'db> FulfillmentCtxt<'db> {
pub(crate) fn collect_remaining_errors(
&mut self,
infcx: &InferCtxt<'db>,
_infcx: &InferCtxt<'db>,
) -> Vec<NextSolverError<'db>> {
self.obligations
.pending
@ -235,10 +232,6 @@ impl<'db> FulfillmentCtxt<'db> {
self.collect_remaining_errors(infcx)
}
fn has_pending_obligations(&self) -> bool {
self.obligations.has_pending_obligations()
}
pub(crate) fn pending_obligations(&self) -> PredicateObligations<'db> {
self.obligations.clone_pending()
}

View file

@ -9,15 +9,15 @@ use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt};
use rustc_type_ir::{
AliasRelationDirection, AliasTermKind, HostEffectPredicate, Interner, PredicatePolarity,
error::ExpectedFound,
inherent::{IntoKind, PlaceholderConst, SliceLike, Span as _},
inherent::{IntoKind, SliceLike, Span as _},
lang_items::SolverTraitLangItem,
solve::{CandidateSource, Certainty, GoalSource, MaybeCause, NoSolution},
solve::{Certainty, GoalSource, MaybeCause, NoSolution},
};
use tracing::{instrument, trace};
use crate::next_solver::{
AliasTerm, Binder, ClauseKind, Const, ConstKind, DbInterner, PolyTraitPredicate, PredicateKind,
SolverContext, SolverDefId, Span, Term, TraitPredicate, Ty, TyKind, TypeError,
SolverContext, Span, Term, TraitPredicate, Ty, TyKind, TypeError,
fulfill::NextSolverError,
infer::{
InferCtxt,
@ -529,7 +529,6 @@ impl<'db> ProofTreeVisitor<'db> for BestObligation<'db> {
}
}
let mut impl_where_bound_count = 0;
for nested_goal in nested_goals {
trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
@ -542,34 +541,27 @@ impl<'db> ProofTreeVisitor<'db> for BestObligation<'db> {
recursion_depth: self.obligation.recursion_depth + 1,
};
let obligation;
match (child_mode, nested_goal.source()) {
let obligation = match (child_mode, nested_goal.source()) {
(
ChildMode::Trait(_) | ChildMode::Host(_),
GoalSource::Misc | GoalSource::TypeRelating | GoalSource::NormalizeGoal(_),
) => {
continue;
}
(ChildMode::Trait(parent_trait_pred), GoalSource::ImplWhereBound) => {
obligation = make_obligation();
impl_where_bound_count += 1;
(ChildMode::Trait(_parent_trait_pred), GoalSource::ImplWhereBound) => {
make_obligation()
}
(
ChildMode::Host(parent_host_pred),
ChildMode::Host(_parent_host_pred),
GoalSource::ImplWhereBound | GoalSource::AliasBoundConstCondition,
) => {
obligation = make_obligation();
impl_where_bound_count += 1;
}
) => make_obligation(),
// Skip over a higher-ranked predicate.
(_, GoalSource::InstantiateHigherRanked) => {
obligation = self.obligation.clone();
}
(_, GoalSource::InstantiateHigherRanked) => self.obligation.clone(),
(ChildMode::PassThrough, _)
| (_, GoalSource::AliasWellFormed | GoalSource::AliasBoundConstCondition) => {
obligation = make_obligation();
make_obligation()
}
}
};
self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
}
@ -628,35 +620,29 @@ impl<'db> NextSolverError<'db> {
}
mod wf {
use std::iter;
use hir_def::ItemContainerId;
use rustc_type_ir::inherent::{
AdtDef, BoundExistentialPredicates, GenericArg, GenericArgs as _, IntoKind, SliceLike,
Term as _, Ty as _,
AdtDef, BoundExistentialPredicates, GenericArgs as _, IntoKind, SliceLike, Term as _,
Ty as _,
};
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::{
Interner, PredicatePolarity, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
TypeVisitor,
Interner, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
};
use tracing::{debug, instrument, trace};
use tracing::{debug, instrument};
use crate::next_solver::infer::InferCtxt;
use crate::next_solver::infer::traits::{
Obligation, ObligationCause, PredicateObligation, PredicateObligations,
};
use crate::next_solver::infer::traits::{Obligation, ObligationCause, PredicateObligations};
use crate::next_solver::{
AliasTerm, Binder, ClauseKind, Const, ConstKind, Ctor, DbInterner, ExistentialPredicate,
GenericArgs, ParamEnv, Predicate, PredicateKind, Region, SolverDefId, Term, TraitPredicate,
TraitRef, Ty, TyKind,
Binder, ClauseKind, Const, ConstKind, Ctor, DbInterner, ExistentialPredicate, GenericArgs,
ParamEnv, Predicate, PredicateKind, Region, SolverDefId, Term, TraitRef, Ty, TyKind,
};
/// Compute the predicates that are required for a type to be well-formed.
///
/// This is only intended to be used in the new solver, since it does not
/// take into account recursion depth or proper error-reporting spans.
pub fn unnormalized_obligations<'db>(
pub(crate) fn unnormalized_obligations<'db>(
infcx: &InferCtxt<'db>,
param_env: ParamEnv<'db>,
term: Term<'db>,
@ -683,158 +669,11 @@ mod wf {
recursion_depth: usize,
}
/// Controls whether we "elaborate" supertraits and so forth on the WF
/// predicates. This is a kind of hack to address #43784. The
/// underlying problem in that issue was a trait structure like:
///
/// ```ignore (illustrative)
/// trait Foo: Copy { }
/// trait Bar: Foo { }
/// impl<T: Bar> Foo for T { }
/// impl<T> Bar for T { }
/// ```
///
/// Here, in the `Foo` impl, we will check that `T: Copy` holds -- but
/// we decide that this is true because `T: Bar` is in the
/// where-clauses (and we can elaborate that to include `T:
/// Copy`). This wouldn't be a problem, except that when we check the
/// `Bar` impl, we decide that `T: Foo` must hold because of the `Foo`
/// impl. And so nowhere did we check that `T: Copy` holds!
///
/// To resolve this, we elaborate the WF requirements that must be
/// proven when checking impls. This means that (e.g.) the `impl Bar
/// for T` will be forced to prove not only that `T: Foo` but also `T:
/// Copy` (which it won't be able to do, because there is no `Copy`
/// impl for `T`).
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
enum Elaborate {
All,
None,
}
impl<'a, 'db> WfPredicates<'a, 'db> {
fn interner(&self) -> DbInterner<'db> {
self.infcx.interner
}
/// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
fn add_wf_preds_for_trait_pred(
&mut self,
trait_pred: TraitPredicate<'db>,
elaborate: Elaborate,
) {
let tcx = self.interner();
let trait_ref = trait_pred.trait_ref;
// Negative trait predicates don't require supertraits to hold, just
// that their args are WF.
if trait_pred.polarity == PredicatePolarity::Negative {
self.add_wf_preds_for_negative_trait_pred(trait_ref);
return;
}
// if the trait predicate is not const, the wf obligations should not be const as well.
let obligations = self.nominal_obligations(trait_ref.def_id.0.into(), trait_ref.args);
debug!("compute_trait_pred obligations {:?}", obligations);
let param_env = self.param_env;
let depth = self.recursion_depth;
let extend = |PredicateObligation { predicate, mut cause, .. }| {
Obligation::with_depth(tcx, cause, depth, param_env, predicate)
};
if let Elaborate::All = elaborate {
let implied_obligations = rustc_type_ir::elaborate::elaborate(tcx, obligations);
let implied_obligations = implied_obligations.map(extend);
self.out.extend(implied_obligations);
} else {
self.out.extend(obligations);
}
self.out.extend(
trait_ref
.args
.iter()
.enumerate()
.filter_map(|(i, arg)| arg.as_term().map(|t| (i, t)))
.filter(|(_, term)| !term.has_escaping_bound_vars())
.map(|(i, term)| {
let mut cause = ObligationCause::misc();
// The first arg is the self ty - use the correct span for it.
Obligation::with_depth(
tcx,
cause,
depth,
param_env,
ClauseKind::WellFormed(term),
)
}),
);
}
// Compute the obligations that are required for `trait_ref` to be WF,
// given that it is a *negative* trait predicate.
fn add_wf_preds_for_negative_trait_pred(&mut self, trait_ref: TraitRef<'db>) {
for arg in trait_ref.args {
if let Some(term) = arg.as_term() {
self.add_wf_preds_for_term(term);
}
}
}
/// Pushes the obligations required for an alias (except inherent) to be WF
/// into `self.out`.
fn add_wf_preds_for_alias_term(&mut self, data: AliasTerm<'db>) {
// A projection is well-formed if
//
// (a) its predicates hold (*)
// (b) its args are wf
//
// (*) The predicates of an associated type include the predicates of
// the trait that it's contained in. For example, given
//
// trait A<T>: Clone {
// type X where T: Copy;
// }
//
// The predicates of `<() as A<i32>>::X` are:
// [
// `(): Sized`
// `(): Clone`
// `(): A<i32>`
// `i32: Sized`
// `i32: Clone`
// `i32: Copy`
// ]
let obligations = self.nominal_obligations(data.def_id, data.args);
self.out.extend(obligations);
self.add_wf_preds_for_projection_args(data.args);
}
fn add_wf_preds_for_projection_args(&mut self, args: GenericArgs<'db>) {
let tcx = self.interner();
let cause = ObligationCause::new();
let param_env = self.param_env;
let depth = self.recursion_depth;
self.out.extend(
args.iter()
.filter_map(|arg| arg.as_term())
.filter(|term| !term.has_escaping_bound_vars())
.map(|term| {
Obligation::with_depth(
tcx,
cause.clone(),
depth,
param_env,
ClauseKind::WellFormed(term),
)
}),
);
}
fn require_sized(&mut self, subty: Ty<'db>) {
if !subty.has_escaping_bound_vars() {
let cause = ObligationCause::new();
@ -895,7 +734,7 @@ mod wf {
fn add_wf_preds_for_dyn_ty(
&mut self,
ty: Ty<'db>,
_ty: Ty<'db>,
data: &[Binder<'db, ExistentialPredicate<'db>>],
region: Region<'db>,
) {
@ -1013,7 +852,7 @@ mod wf {
));
}
TyKind::Pat(base_ty, pat) => {
TyKind::Pat(base_ty, _pat) => {
self.require_sized(base_ty);
}
@ -1036,7 +875,7 @@ mod wf {
let obligations = self.nominal_obligations(data.def_id, data.args);
self.out.extend(obligations);
}
TyKind::Alias(rustc_type_ir::Inherent, data) => {
TyKind::Alias(rustc_type_ir::Inherent, _data) => {
return;
}
@ -1148,7 +987,7 @@ mod wf {
// Let the visitor iterate into the argument/return
// types appearing in the fn signature.
}
TyKind::UnsafeBinder(ty) => {}
TyKind::UnsafeBinder(_ty) => {}
TyKind::Dynamic(data, r) => {
// WfObject
@ -1291,7 +1130,7 @@ mod wf {
///
/// Requires that trait definitions have been processed so that we can
/// elaborate predicates and walk supertraits.
pub fn object_region_bounds<'db>(
pub(crate) fn object_region_bounds<'db>(
interner: DbInterner<'db>,
existential_predicates: &[Binder<'db, ExistentialPredicate<'db>>],
) -> Vec<Region<'db>> {

View file

@ -1,27 +1,20 @@
//! Things related to generic args in the next-trait-solver.
use hir_def::{GenericDefId, GenericParamId};
use intern::{Interned, Symbol};
use macros::{TypeFoldable, TypeVisitable};
use rustc_type_ir::inherent::Const as _;
use rustc_type_ir::{
ClosureArgs, CollectAndApply, ConstVid, CoroutineArgs, CoroutineClosureArgs, FnSig, FnSigTys,
GenericArgKind, IntTy, Interner, TermKind, TyKind, TyVid, TypeFoldable, TypeVisitable,
Variance,
inherent::{
GenericArg as _, GenericArgs as _, GenericsOf, IntoKind, SliceLike, Term as _, Ty as _,
},
ClosureArgs, CollectAndApply, ConstVid, CoroutineArgs, CoroutineClosureArgs, FnSigTys,
GenericArgKind, Interner, TermKind, TyKind, TyVid, Variance,
inherent::{GenericArg as _, GenericsOf, IntoKind, SliceLike, Term as _, Ty as _},
relate::{Relate, VarianceDiagInfo},
};
use smallvec::SmallVec;
use crate::db::HirDatabase;
use crate::next_solver::{Binder, PolyFnSig};
use crate::next_solver::{PolyFnSig, interned_vec_db};
use super::{
Const, DbInterner, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId, Ty, Tys,
generics::{GenericParamDef, Generics},
interned_vec_db,
generics::Generics,
};
#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
@ -191,7 +184,7 @@ impl<'db> GenericArgs<'db> {
mut mk_kind: F,
) -> GenericArgs<'db>
where
F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
F: FnMut(u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let defs = interner.generics_of(def_id);
let count = defs.count();
@ -202,9 +195,7 @@ impl<'db> GenericArgs<'db> {
/// Creates an all-error `GenericArgs`.
pub fn error_for_item(interner: DbInterner<'db>, def_id: SolverDefId) -> GenericArgs<'db> {
GenericArgs::for_item(interner, def_id, |_, _, id, _| {
GenericArg::error_from_id(interner, id)
})
GenericArgs::for_item(interner, def_id, |_, id, _| GenericArg::error_from_id(interner, id))
}
/// Like `for_item`, but prefers the default of a parameter if it has any.
@ -214,14 +205,12 @@ impl<'db> GenericArgs<'db> {
mut fallback: F,
) -> GenericArgs<'db>
where
F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
F: FnMut(u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let defaults = interner.db.generic_defaults_ns(def_id);
Self::for_item(interner, def_id.into(), |name, idx, id, prev| {
match defaults.get(idx as usize) {
Some(default) => default.instantiate(interner, prev),
None => fallback(name, idx, id, prev),
}
Self::for_item(interner, def_id.into(), |idx, id, prev| match defaults.get(idx as usize) {
Some(default) => default.instantiate(interner, prev),
None => fallback(idx, id, prev),
})
}
@ -233,11 +222,11 @@ impl<'db> GenericArgs<'db> {
mut fallback: F,
) -> GenericArgs<'db>
where
F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
F: FnMut(u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let mut iter = first.into_iter();
Self::for_item(interner, def_id, |name, idx, id, prev| {
iter.next().unwrap_or_else(|| fallback(name, idx, id, prev))
Self::for_item(interner, def_id, |idx, id, prev| {
iter.next().unwrap_or_else(|| fallback(idx, id, prev))
})
}
@ -249,14 +238,14 @@ impl<'db> GenericArgs<'db> {
mut fallback: F,
) -> GenericArgs<'db>
where
F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
F: FnMut(u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let defaults = interner.db.generic_defaults_ns(def_id);
Self::fill_rest(interner, def_id.into(), first, |name, idx, id, prev| {
Self::fill_rest(interner, def_id.into(), first, |idx, id, prev| {
defaults
.get(idx as usize)
.map(|default| default.instantiate(interner, prev))
.unwrap_or_else(|| fallback(name, idx, id, prev))
.unwrap_or_else(|| fallback(idx, id, prev))
})
}
@ -266,9 +255,8 @@ impl<'db> GenericArgs<'db> {
defs: Generics,
mk_kind: &mut F,
) where
F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
F: FnMut(u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let self_len = defs.own_params.len() as u32;
if let Some(def_id) = defs.parent {
let parent_defs = interner.generics_of(def_id.into());
Self::fill_item(args, interner, parent_defs, mk_kind);
@ -278,12 +266,11 @@ impl<'db> GenericArgs<'db> {
fn fill_single<F>(args: &mut SmallVec<[GenericArg<'db>; 8]>, defs: &Generics, mk_kind: &mut F)
where
F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
F: FnMut(u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let start_len = args.len();
args.reserve(defs.own_params.len());
for param in &defs.own_params {
let kind = mk_kind(&param.name, args.len() as u32, param.id, args);
let kind = mk_kind(args.len() as u32, param.id, args);
args.push(kind);
}
}
@ -374,9 +361,7 @@ impl<'db> rustc_type_ir::inherent::GenericArgs<DbInterner<'db>> for GenericArgs<
interner: DbInterner<'db>,
def_id: <DbInterner<'db> as rustc_type_ir::Interner>::DefId,
) -> <DbInterner<'db> as rustc_type_ir::Interner>::GenericArgs {
Self::for_item(interner, def_id, |name, index, kind, _| {
mk_param(interner, index, name, kind)
})
Self::for_item(interner, def_id, |index, kind, _| mk_param(interner, index, kind))
}
fn extend_with_error(
@ -384,7 +369,7 @@ impl<'db> rustc_type_ir::inherent::GenericArgs<DbInterner<'db>> for GenericArgs<
def_id: <DbInterner<'db> as rustc_type_ir::Interner>::DefId,
original_args: &[<DbInterner<'db> as rustc_type_ir::Interner>::GenericArg],
) -> <DbInterner<'db> as rustc_type_ir::Interner>::GenericArgs {
Self::for_item(interner, def_id, |name, index, kind, _| {
Self::for_item(interner, def_id, |index, kind, _| {
if let Some(arg) = original_args.get(index as usize) {
*arg
} else {
@ -461,7 +446,7 @@ impl<'db> rustc_type_ir::inherent::GenericArgs<DbInterner<'db>> for GenericArgs<
signature_parts_ty,
tupled_upvars_ty,
coroutine_captures_by_ref_ty,
coroutine_witness_ty,
_coroutine_witness_ty,
] => rustc_type_ir::CoroutineClosureArgsParts {
parent_args: GenericArgs::new_from_iter(
DbInterner::conjure(),
@ -494,18 +479,12 @@ impl<'db> rustc_type_ir::inherent::GenericArgs<DbInterner<'db>> for GenericArgs<
}
}
pub fn mk_param<'db>(
interner: DbInterner<'db>,
index: u32,
name: &Symbol,
id: GenericParamId,
) -> GenericArg<'db> {
let name = name.clone();
pub fn mk_param<'db>(interner: DbInterner<'db>, index: u32, id: GenericParamId) -> GenericArg<'db> {
match id {
GenericParamId::LifetimeParamId(id) => {
Region::new_early_param(interner, EarlyParamRegion { index, id }).into()
}
GenericParamId::TypeParamId(id) => Ty::new_param(interner, id, index, name).into(),
GenericParamId::TypeParamId(id) => Ty::new_param(interner, id, index).into(),
GenericParamId::ConstParamId(id) => {
Const::new_param(interner, ParamConst { index, id }).into()
}
@ -596,13 +575,4 @@ impl<'db> DbInterner<'db> {
{
T::collect_and_apply(iter, |xs| self.mk_args(xs))
}
pub(super) fn check_args_compatible(self, def_id: SolverDefId, args: GenericArgs<'db>) -> bool {
// TODO
true
}
pub(super) fn debug_assert_args_compatible(self, def_id: SolverDefId, args: GenericArgs<'db>) {
// TODO
}
}

View file

@ -1,36 +1,25 @@
//! Things related to generics in the next-trait-solver.
use hir_def::{
ConstParamId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId, Lookup,
TypeOrConstParamId, TypeParamId,
db::DefDatabase,
expr_store::ExpressionStore,
ConstParamId, GenericDefId, GenericParamId, LifetimeParamId, TypeOrConstParamId, TypeParamId,
hir::generics::{
GenericParamDataRef, GenericParams, LifetimeParamData, LocalLifetimeParamId,
LocalTypeOrConstParamId, TypeOrConstParamData, TypeParamData, TypeParamProvenance,
WherePredicate,
GenericParams, LocalTypeOrConstParamId, TypeOrConstParamData, TypeParamData,
TypeParamProvenance,
},
};
use hir_expand::name::Name;
use intern::{Symbol, sym};
use la_arena::Arena;
use rustc_type_ir::inherent::Ty as _;
use triomphe::Arc;
use crate::{db::HirDatabase, generics::parent_generic_def, next_solver::Ty};
use crate::{db::HirDatabase, generics::parent_generic_def};
use super::{Const, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId};
use super::SolverDefId;
use super::{DbInterner, GenericArg};
use super::DbInterner;
pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
let mk_lt = |parent, index, local_id, lt: &LifetimeParamData| {
let name = lt.name.symbol().clone();
let mk_lt = |parent, index, local_id| {
let id = GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id });
GenericParamDef { name, index, id }
GenericParamDef { index, id }
};
let mk_ty = |parent, index, local_id, p: &TypeOrConstParamData| {
let name = p.name().map(|n| n.symbol().clone()).unwrap_or_else(|| sym::MISSING_NAME);
let id = TypeOrConstParamId { parent, local_id };
let id = match p {
TypeOrConstParamData::TypeParamData(_) => {
@ -40,7 +29,7 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
GenericParamId::ConstParamId(ConstParamId::from_unchecked(id))
}
};
GenericParamDef { name, index, id }
GenericParamDef { index, id }
};
let own_params_for_generic_params = |parent, params: &GenericParams| {
let mut result = Vec::with_capacity(params.len());
@ -51,8 +40,8 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
type_and_consts.next();
index += 1;
}
result.extend(params.iter_lt().map(|(local_id, data)| {
let lt = mk_lt(parent, index, local_id, data);
result.extend(params.iter_lt().map(|(local_id, _data)| {
let lt = mk_lt(parent, index, local_id);
index += 1;
lt
}));
@ -78,7 +67,7 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => {
(Some(type_alias_id.into()), Vec::new())
}
crate::ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
crate::ImplTraitId::AsyncBlockTypeImplTrait(_def, _) => {
let param = TypeOrConstParamData::TypeParamData(TypeParamData {
name: None,
default: None,
@ -121,8 +110,6 @@ pub struct Generics {
#[derive(Debug)]
pub struct GenericParamDef {
pub(crate) name: Symbol,
//def_id: GenericDefId,
index: u32,
pub(crate) id: GenericParamId,
}

View file

@ -36,7 +36,7 @@ use crate::next_solver::{
AliasTerm, AliasTy, Binder, Const, DbInterner, GenericArg, Goal, ParamEnv,
PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, Predicate, Region, Span, Term,
TraitRef, Ty,
fulfill::{FulfillmentCtxt, NextSolverError},
fulfill::NextSolverError,
infer::relate::lattice::{LatticeOp, LatticeOpKind},
};
@ -45,16 +45,6 @@ use super::{
traits::{Obligation, ObligationCause},
};
/// Whether we should define opaque types or just treat them opaquely.
///
/// Currently only used to prevent predicate matching from matching anything
/// against opaque types.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum DefineOpaqueTypes {
Yes,
No,
}
#[derive(Clone, Copy)]
pub struct At<'a, 'db> {
pub infcx: &'a InferCtxt<'db>,
@ -107,12 +97,7 @@ impl<'a, 'db> At<'a, 'db> {
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
/// `sup(i32, x)`, since the "expected" type is the type that
/// appears in the signature.
pub fn sup<T>(
self,
define_opaque_types: DefineOpaqueTypes,
expected: T,
actual: T,
) -> InferResult<'db, ()>
pub fn sup<T>(self, expected: T, actual: T) -> InferResult<'db, ()>
where
T: ToTrace<'db>,
{
@ -128,12 +113,7 @@ impl<'a, 'db> At<'a, 'db> {
}
/// Makes `expected <: actual`.
pub fn sub<T>(
self,
define_opaque_types: DefineOpaqueTypes,
expected: T,
actual: T,
) -> InferResult<'db, ()>
pub fn sub<T>(self, expected: T, actual: T) -> InferResult<'db, ()>
where
T: ToTrace<'db>,
{
@ -149,31 +129,7 @@ impl<'a, 'db> At<'a, 'db> {
}
/// Makes `expected == actual`.
pub fn eq<T>(
self,
define_opaque_types: DefineOpaqueTypes,
expected: T,
actual: T,
) -> InferResult<'db, ()>
where
T: ToTrace<'db>,
{
self.eq_trace(
define_opaque_types,
ToTrace::to_trace(self.cause, expected, actual),
expected,
actual,
)
}
/// Makes `expected == actual`.
pub fn eq_trace<T>(
self,
define_opaque_types: DefineOpaqueTypes,
trace: TypeTrace<'db>,
expected: T,
actual: T,
) -> InferResult<'db, ()>
pub fn eq<T>(self, expected: T, actual: T) -> InferResult<'db, ()>
where
T: Relate<DbInterner<'db>>,
{
@ -188,20 +144,14 @@ impl<'a, 'db> At<'a, 'db> {
.map(|goals| self.goals_to_obligations(goals))
}
pub fn relate<T>(
self,
define_opaque_types: DefineOpaqueTypes,
expected: T,
variance: Variance,
actual: T,
) -> InferResult<'db, ()>
pub fn relate<T>(self, expected: T, variance: Variance, actual: T) -> InferResult<'db, ()>
where
T: ToTrace<'db>,
{
match variance {
Variance::Covariant => self.sub(define_opaque_types, expected, actual),
Variance::Invariant => self.eq(define_opaque_types, expected, actual),
Variance::Contravariant => self.sup(define_opaque_types, expected, actual),
Variance::Covariant => self.sub(expected, actual),
Variance::Invariant => self.eq(expected, actual),
Variance::Contravariant => self.sup(expected, actual),
// We could make this make sense but it's not readily
// exposed and I don't feel like dealing with it. Note

View file

@ -8,7 +8,7 @@
use rustc_hash::FxHashMap;
use rustc_index::Idx;
use rustc_type_ir::InferTy::{self, FloatVar, IntVar, TyVar};
use rustc_type_ir::inherent::{Const as _, IntoKind as _, Region as _, SliceLike, Ty as _};
use rustc_type_ir::inherent::{Const as _, IntoKind as _, SliceLike, Ty as _};
use rustc_type_ir::{
BoundVar, CanonicalQueryInput, DebruijnIndex, Flags, InferConst, RegionKind, TyVid, TypeFlags,
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UniverseIndex,

View file

@ -8,22 +8,11 @@
use crate::next_solver::BoundConst;
use crate::next_solver::{
AliasTy, Binder, BoundRegion, BoundTy, Canonical, CanonicalVarValues, Const, DbInterner, Goal,
ParamEnv, Predicate, PredicateKind, Region, Ty, TyKind,
fold::FnMutDelegate,
infer::{
DefineOpaqueTypes, InferCtxt, TypeTrace,
traits::{Obligation, PredicateObligations},
},
BoundRegion, BoundTy, Canonical, CanonicalVarValues, DbInterner, fold::FnMutDelegate,
};
use rustc_type_ir::{
AliasRelationDirection, AliasTyKind, BoundVar, GenericArgKind, InferTy, TypeFoldable, Upcast,
Variance,
GenericArgKind, TypeFoldable,
inherent::{IntoKind, SliceLike},
relate::{
Relate, TypeRelation, VarianceDiagInfo,
combine::{super_combine_consts, super_combine_tys},
},
};
pub trait CanonicalExt<'db, V> {

View file

@ -22,26 +22,13 @@
//! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
use crate::next_solver::{
AliasTy, Binder, Canonical, CanonicalVarValues, CanonicalVars, Const, DbInterner, GenericArg,
Goal, ParamEnv, PlaceholderConst, PlaceholderRegion, PlaceholderTy, Predicate, PredicateKind,
Region, Ty, TyKind,
infer::{
DefineOpaqueTypes, InferCtxt, TypeTrace,
traits::{Obligation, PredicateObligations},
},
Canonical, CanonicalVarValues, Const, DbInterner, GenericArg, PlaceholderConst,
PlaceholderRegion, PlaceholderTy, Region, Ty, TyKind, infer::InferCtxt,
};
use instantiate::CanonicalExt;
use rustc_index::IndexVec;
use rustc_type_ir::inherent::IntoKind;
use rustc_type_ir::{
AliasRelationDirection, AliasTyKind, CanonicalVarKind, InferTy, TypeFoldable, UniverseIndex,
Upcast, Variance,
inherent::{SliceLike, Ty as _},
relate::{
Relate, TypeRelation, VarianceDiagInfo,
combine::{super_combine_consts, super_combine_tys},
},
};
use rustc_type_ir::{CanonicalVarKind, InferTy, TypeFoldable, UniverseIndex, inherent::Ty as _};
pub mod canonicalizer;
pub mod instantiate;

View file

@ -1,19 +1,19 @@
//! Definition of `InferCtxtLike` from the librarified type layer.
use rustc_type_ir::{
ConstVid, FloatVarValue, FloatVid, GenericArgKind, InferConst, InferTy, IntTy, IntVarValue,
IntVid, RegionVid, TyVid, TypeFoldable, TypingMode, UniverseIndex,
inherent::{Const as _, IntoKind, Span as _, Ty as _},
ConstVid, FloatVarValue, FloatVid, GenericArgKind, InferConst, InferTy, IntVarValue, IntVid,
RegionVid, TyVid, TypeFoldable, TypingMode, UniverseIndex,
inherent::{Const as _, IntoKind, Ty as _},
relate::combine::PredicateEmittingRelation,
};
use crate::next_solver::{
Binder, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, OpaqueTypeKey, ParamEnv,
Region, SolverDefId, Span, Ty, TyKind,
Binder, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, OpaqueTypeKey, Region,
SolverDefId, Span, Ty, TyKind,
infer::opaque_types::{OpaqueHiddenType, table::OpaqueTypeStorageEntries},
};
use super::{BoundRegionConversionTime, InferCtxt, relate::RelateResult, traits::ObligationCause};
use super::{BoundRegionConversionTime, InferCtxt, relate::RelateResult};
impl<'db> rustc_type_ir::InferCtxtLike for InferCtxt<'db> {
type Interner = DbInterner<'db>;
@ -250,16 +250,16 @@ impl<'db> rustc_type_ir::InferCtxtLike for InferCtxt<'db> {
self.probe(|_| probe())
}
fn sub_regions(&self, sub: Region<'db>, sup: Region<'db>, span: Span) {
fn sub_regions(&self, sub: Region<'db>, sup: Region<'db>, _span: Span) {
self.inner.borrow_mut().unwrap_region_constraints().make_subregion(sub, sup);
}
fn equate_regions(&self, a: Region<'db>, b: Region<'db>, span: Span) {
fn equate_regions(&self, a: Region<'db>, b: Region<'db>, _span: Span) {
self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(a, b);
}
fn register_ty_outlives(&self, ty: Ty<'db>, r: Region<'db>, span: Span) {
//self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(Span::dummy()));
fn register_ty_outlives(&self, _ty: Ty<'db>, _r: Region<'db>, _span: Span) {
// self.register_type_outlives_constraint(ty, r, &ObligationCause::dummy());
}
type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;

View file

@ -6,32 +6,23 @@ use std::ops::Range;
use std::sync::Arc;
pub use BoundRegionConversionTime::*;
pub use at::DefineOpaqueTypes;
use ena::undo_log::UndoLogs;
use ena::unify as ut;
use hir_def::GenericParamId;
use hir_def::lang_item::LangItem;
use intern::Symbol;
use opaque_types::{OpaqueHiddenType, OpaqueTypeStorage};
use region_constraints::{
GenericKind, RegionConstraintCollector, RegionConstraintStorage, UndoLog, VarInfos, VerifyBound,
};
pub use relate::StructurallyRelateAliases;
pub use relate::combine::PredicateEmittingRelation;
use rustc_hash::{FxHashMap, FxHashSet};
use region_constraints::{RegionConstraintCollector, RegionConstraintStorage};
use rustc_next_trait_solver::solve::SolverDelegateEvalExt;
use rustc_pattern_analysis::Captures;
use rustc_type_ir::TypeFoldable;
use rustc_type_ir::error::{ExpectedFound, TypeError};
use rustc_type_ir::inherent::{
Const as _, GenericArg as _, GenericArgs as _, IntoKind, ParamEnv as _, SliceLike, Term as _,
Ty as _,
Const as _, GenericArg as _, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _,
};
use rustc_type_ir::{
BoundVar, ClosureKind, ConstVid, FloatTy, FloatVarValue, FloatVid, GenericArgKind, InferConst,
InferTy, IntTy, IntVarValue, IntVid, OutlivesPredicate, RegionVid, TyVid, UniverseIndex,
ClosureKind, ConstVid, FloatVarValue, FloatVid, GenericArgKind, InferConst, InferTy,
IntVarValue, IntVid, OutlivesPredicate, RegionVid, TyVid, UniverseIndex,
};
use rustc_type_ir::{TermKind, TypeVisitableExt};
use rustc_type_ir::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use snapshot::undo_log::InferCtxtUndoLogs;
use tracing::{debug, instrument};
use traits::{ObligationCause, PredicateObligations};
@ -39,19 +30,17 @@ use type_variable::TypeVariableOrigin;
use unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
use crate::next_solver::fold::BoundVarReplacerDelegate;
use crate::next_solver::infer::opaque_types::table::OpaqueTypeStorageEntries;
use crate::next_solver::infer::select::EvaluationResult;
use crate::next_solver::infer::traits::PredicateObligation;
use crate::next_solver::obligation_ctxt::ObligationCtxt;
use crate::next_solver::{BoundConst, BoundRegion, BoundTy, BoundVarKind, Goal, SolverContext};
use super::generics::GenericParamDef;
use super::{
AliasTerm, Binder, BoundRegionKind, CanonicalQueryInput, CanonicalVarValues, Const, ConstKind,
DbInterner, ErrorGuaranteed, FxIndexMap, GenericArg, GenericArgs, OpaqueTypeKey, ParamEnv,
PlaceholderRegion, PolyCoercePredicate, PolyExistentialProjection, PolyExistentialTraitRef,
PolyFnSig, PolyRegionOutlivesPredicate, PolySubtypePredicate, Predicate, Region, SolverDefId,
SubtypePredicate, Term, TraitPredicate, TraitRef, Ty, TyKind, TypingMode,
AliasTerm, Binder, CanonicalQueryInput, CanonicalVarValues, Const, ConstKind, DbInterner,
ErrorGuaranteed, GenericArg, GenericArgs, OpaqueTypeKey, ParamEnv, PolyCoercePredicate,
PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyRegionOutlivesPredicate,
PolySubtypePredicate, Region, SolverDefId, SubtypePredicate, Term, TraitRef, Ty, TyKind,
TypingMode,
};
pub mod at;
@ -82,8 +71,6 @@ pub struct InferOk<'db, T> {
}
pub type InferResult<'db, T> = Result<InferOk<'db, T>, TypeError<DbInterner<'db>>>;
pub(crate) type FixupResult<T> = Result<T, FixupError>; // "fixup result"
pub(crate) type UnificationTable<'a, 'db, T> = ut::UnificationTable<
ut::InPlace<T, &'a mut ut::UnificationStorage<T>, &'a mut InferCtxtUndoLogs<'db>>,
>;
@ -440,6 +427,7 @@ impl<'db> InferCtxt<'db> {
/// check::<&'_ T>();
/// }
/// ```
#[expect(dead_code, reason = "this is used in rustc")]
fn predicate_must_hold_considering_regions(
&self,
obligation: &PredicateObligation<'db>,
@ -452,14 +440,13 @@ impl<'db> InferCtxt<'db> {
/// not entirely accurate if inference variables are involved.
///
/// This version ignores all outlives constraints.
#[expect(dead_code, reason = "this is used in rustc")]
fn predicate_must_hold_modulo_regions(&self, obligation: &PredicateObligation<'db>) -> bool {
self.evaluate_obligation(obligation).must_apply_modulo_regions()
}
/// Evaluate a given predicate, capturing overflow and propagating it back.
fn evaluate_obligation(&self, obligation: &PredicateObligation<'db>) -> EvaluationResult {
let param_env = obligation.param_env;
self.probe(|snapshot| {
let mut ocx = ObligationCtxt::new(self);
ocx.register_obligation(obligation.clone());
@ -583,16 +570,16 @@ impl<'db> InferCtxt<'db> {
self.enter_forall(predicate, |SubtypePredicate { a_is_expected, a, b }| {
if a_is_expected {
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b))
Ok(self.at(cause, param_env).sub(a, b))
} else {
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a))
Ok(self.at(cause, param_env).sup(b, a))
}
})
}
pub fn region_outlives_predicate(
&self,
cause: &traits::ObligationCause,
_cause: &traits::ObligationCause,
predicate: PolyRegionOutlivesPredicate<'db>,
) {
self.enter_forall(predicate, |OutlivesPredicate(r_a, r_b)| {
@ -632,7 +619,7 @@ impl<'db> InferCtxt<'db> {
}
pub fn next_const_var(&self) -> Const<'db> {
self.next_const_var_with_origin(ConstVariableOrigin { param_def_id: None })
self.next_const_var_with_origin(ConstVariableOrigin {})
}
pub fn next_const_vid(&self) -> ConstVid {
@ -640,7 +627,7 @@ impl<'db> InferCtxt<'db> {
.borrow_mut()
.const_unification_table()
.new_key(ConstVariableValue::Unknown {
origin: ConstVariableOrigin { param_def_id: None },
origin: ConstVariableOrigin {},
universe: self.universe(),
})
.vid
@ -657,7 +644,7 @@ impl<'db> InferCtxt<'db> {
}
pub fn next_const_var_in_universe(&self, universe: UniverseIndex) -> Const<'db> {
let origin = ConstVariableOrigin { param_def_id: None };
let origin = ConstVariableOrigin {};
let vid = self
.inner
.borrow_mut()
@ -738,7 +725,7 @@ impl<'db> InferCtxt<'db> {
self.next_region_var_in_universe(universe)
}
fn var_for_def(&self, id: GenericParamId, name: &Symbol) -> GenericArg<'db> {
fn var_for_def(&self, id: GenericParamId) -> GenericArg<'db> {
match id {
GenericParamId::LifetimeParamId(_) => {
// Create a region inference variable for the given
@ -763,7 +750,7 @@ impl<'db> InferCtxt<'db> {
Ty::new_var(self.interner, ty_var_id).into()
}
GenericParamId::ConstParamId(_) => {
let origin = ConstVariableOrigin { param_def_id: None };
let origin = ConstVariableOrigin {};
let const_var_id = self
.inner
.borrow_mut()
@ -778,9 +765,7 @@ impl<'db> InferCtxt<'db> {
/// Given a set of generics defined on a type or impl, returns the generic parameters mapping
/// each type/region parameter to a fresh inference variable.
pub fn fresh_args_for_item(&self, def_id: SolverDefId) -> GenericArgs<'db> {
GenericArgs::for_item(self.interner, def_id, |name, index, kind, _| {
self.var_for_def(kind, name)
})
GenericArgs::for_item(self.interner, def_id, |_index, kind, _| self.var_for_def(kind))
}
/// Like `fresh_args_for_item()`, but first uses the args from `first`.
@ -789,8 +774,8 @@ impl<'db> InferCtxt<'db> {
def_id: SolverDefId,
first: impl IntoIterator<Item = GenericArg<'db>>,
) -> GenericArgs<'db> {
GenericArgs::fill_rest(self.interner, def_id, first, |name, index, kind, _| {
self.var_for_def(kind, name)
GenericArgs::fill_rest(self.interner, def_id, first, |_index, kind, _| {
self.var_for_def(kind)
})
}
@ -828,8 +813,8 @@ impl<'db> InferCtxt<'db> {
defining_opaque_types_and_generators.contains(&id.into())
}
TypingMode::Coherence | TypingMode::PostAnalysis => false,
TypingMode::Borrowck { defining_opaque_types } => unimplemented!(),
TypingMode::PostBorrowckAnalysis { defined_opaque_types } => unimplemented!(),
TypingMode::Borrowck { defining_opaque_types: _ } => unimplemented!(),
TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => unimplemented!(),
}
}
@ -998,7 +983,7 @@ impl<'db> InferCtxt<'db> {
// use [`InferCtxt::enter_forall`] instead.
pub fn instantiate_binder_with_fresh_vars<T>(
&self,
lbrct: BoundRegionConversionTime,
_lbrct: BoundRegionConversionTime,
value: Binder<'db, T>,
) -> T
where
@ -1014,7 +999,7 @@ impl<'db> InferCtxt<'db> {
for bound_var_kind in bound_vars {
let arg: GenericArg<'db> = match bound_var_kind {
BoundVarKind::Ty(_) => self.next_ty_var().into(),
BoundVarKind::Region(br) => self.next_region_var().into(),
BoundVarKind::Region(_) => self.next_region_var().into(),
BoundVarKind::Const => self.next_const_var().into(),
};
args.push(arg);
@ -1070,7 +1055,7 @@ impl<'db> InferCtxt<'db> {
#[inline]
pub fn is_ty_infer_var_definitely_unchanged<'a>(
&'a self,
) -> (impl Fn(TyOrConstInferVar) -> bool + Captures<'db> + 'a) {
) -> impl Fn(TyOrConstInferVar) -> bool + Captures<'db> + 'a {
// This hoists the borrow/release out of the loop body.
let inner = self.inner.try_borrow();

View file

@ -1,40 +1,10 @@
//! Things related to the infer context of the next-trait-solver.
use std::sync::Arc;
use tracing::{debug, instrument};
use crate::next_solver::{
Clause, ClauseKind, FxIndexMap, GenericArgs, OpaqueTypeKey, ProjectionPredicate, SolverDefId,
TypingMode, util::BottomUpFolder,
};
pub(crate) mod table;
pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable};
use crate::next_solver::{
AliasTy, Binder, BoundRegion, BoundTy, Canonical, CanonicalVarValues, Const, DbInterner, Goal,
ParamEnv, Predicate, PredicateKind, Region, Ty, TyKind,
fold::FnMutDelegate,
infer::{
DefineOpaqueTypes, InferCtxt, TypeTrace,
traits::{Obligation, PredicateObligations},
},
};
use rustc_type_ir::{
AliasRelationDirection, AliasTyKind, BoundConstness, BoundVar, Flags, GenericArgKind, InferTy,
Interner, RegionKind, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, Upcast, Variance,
error::{ExpectedFound, TypeError},
inherent::{DefId, GenericArgs as _, IntoKind, SliceLike},
relate::{
Relate, TypeRelation, VarianceDiagInfo,
combine::{super_combine_consts, super_combine_tys},
},
};
use super::{InferOk, traits::ObligationCause};
use crate::next_solver::{OpaqueTypeKey, Ty, infer::InferCtxt};
#[derive(Copy, Clone, Debug)]
pub struct OpaqueHiddenType<'db> {

View file

@ -54,7 +54,7 @@ impl<'db> OpaqueTypeStorage<'db> {
assert!(entry.is_some());
}
pub fn is_empty(&self) -> bool {
pub(crate) fn is_empty(&self) -> bool {
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
opaque_types.is_empty() && duplicate_entries.is_empty()
}
@ -66,14 +66,14 @@ impl<'db> OpaqueTypeStorage<'db> {
std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries))
}
pub fn num_entries(&self) -> OpaqueTypeStorageEntries {
pub(crate) fn num_entries(&self) -> OpaqueTypeStorageEntries {
OpaqueTypeStorageEntries {
opaque_types: self.opaque_types.len(),
duplicate_entries: self.duplicate_entries.len(),
}
}
pub fn opaque_types_added_since(
pub(crate) fn opaque_types_added_since(
&self,
prev_entries: OpaqueTypeStorageEntries,
) -> impl Iterator<Item = (OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)> {
@ -89,7 +89,7 @@ impl<'db> OpaqueTypeStorage<'db> {
///
/// Outside of canonicalization one should generally use `iter_opaque_types`
/// to also consider duplicate entries.
pub fn iter_lookup_table(
pub(crate) fn iter_lookup_table(
&self,
) -> impl Iterator<Item = (OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)> {
self.opaque_types.iter().map(|(k, v)| (*k, *v))
@ -100,13 +100,13 @@ impl<'db> OpaqueTypeStorage<'db> {
/// These have to considered when checking all opaque type uses but are e.g.
/// irrelevant for canonical inputs as nested queries never meaningfully
/// accesses them.
pub fn iter_duplicate_entries(
pub(crate) fn iter_duplicate_entries(
&self,
) -> impl Iterator<Item = (OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)> {
self.duplicate_entries.iter().copied()
}
pub fn iter_opaque_types(
pub(crate) fn iter_opaque_types(
&self,
) -> impl Iterator<Item = (OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)> {
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
@ -144,7 +144,7 @@ impl<'db> Deref for OpaqueTypeTable<'_, 'db> {
impl<'a, 'db> OpaqueTypeTable<'a, 'db> {
#[instrument(skip(self), level = "debug")]
pub fn register(
pub(crate) fn register(
&mut self,
key: OpaqueTypeKey<'db>,
hidden_type: OpaqueHiddenType<'db>,
@ -159,7 +159,11 @@ impl<'a, 'db> OpaqueTypeTable<'a, 'db> {
None
}
pub fn add_duplicate(&mut self, key: OpaqueTypeKey<'db>, hidden_type: OpaqueHiddenType<'db>) {
pub(crate) fn add_duplicate(
&mut self,
key: OpaqueTypeKey<'db>,
hidden_type: OpaqueHiddenType<'db>,
) {
self.storage.duplicate_entries.push((key, hidden_type));
self.undo_log.push(UndoLog::DuplicateOpaqueType);
}

View file

@ -1,7 +1,6 @@
//! See `README.md`.
use std::ops::Range;
use std::sync::Arc;
use std::{cmp, fmt, mem};
use ena::undo_log::{Rollback, UndoLogs};
@ -18,9 +17,7 @@ use super::MemberConstraint;
use super::unify_key::RegionVidKey;
use crate::next_solver::infer::snapshot::undo_log::{InferCtxtUndoLogs, Snapshot};
use crate::next_solver::infer::unify_key::RegionVariableValue;
use crate::next_solver::{
AliasTy, Binder, DbInterner, OpaqueTypeKey, ParamTy, PlaceholderTy, Region, Ty,
};
use crate::next_solver::{AliasTy, Binder, DbInterner, ParamTy, PlaceholderTy, Region, Ty};
#[derive(Debug, Clone, Default)]
pub struct RegionConstraintStorage<'db> {
@ -254,6 +251,7 @@ pub(crate) enum UndoLog<'db> {
AddConstraint(usize),
/// We added the given `verify`.
#[expect(dead_code, reason = "this is used in rustc")]
AddVerify(usize),
/// We added a GLB/LUB "combination variable".

View file

@ -7,8 +7,8 @@ use rustc_type_ir::error::TypeError;
use rustc_type_ir::inherent::{Const as _, IntoKind, Ty as _};
use rustc_type_ir::relate::VarianceDiagInfo;
use rustc_type_ir::{
AliasRelationDirection, AliasTyKind, ConstVid, InferConst, InferCtxtLike, InferTy, RegionKind,
TermKind, TyVid, UniverseIndex, Variance,
AliasRelationDirection, ConstVid, InferConst, InferCtxtLike, InferTy, RegionKind, TermKind,
TyVid, UniverseIndex, Variance,
};
use rustc_type_ir::{Interner, TypeVisitable, TypeVisitableExt};
use tracing::{debug, instrument, warn};
@ -21,9 +21,8 @@ use crate::next_solver::infer::unify_key::ConstVariableValue;
use crate::next_solver::infer::{InferCtxt, relate};
use crate::next_solver::util::MaxUniverse;
use crate::next_solver::{
AliasTy, Binder, ClauseKind, Const, ConstKind, DbInterner, GenericArgs, PredicateKind,
ProjectionPredicate, Region, SolverDefId, Term, TermVid, Ty, TyKind, TypingMode,
UnevaluatedConst,
AliasTy, Binder, ClauseKind, Const, ConstKind, DbInterner, GenericArgs, PredicateKind, Region,
SolverDefId, Term, TermVid, Ty, TyKind, TypingMode, UnevaluatedConst,
};
impl<'db> InferCtxt<'db> {

View file

@ -2,13 +2,10 @@
//! the end of the file for details.
use rustc_type_ir::TypeFoldable;
use rustc_type_ir::{BoundVar, UniverseIndex};
use tracing::{debug, instrument};
use super::RelateResult;
use crate::next_solver::fold::FnMutDelegate;
use crate::next_solver::infer::InferCtxt;
use crate::next_solver::infer::snapshot::CombinedSnapshot;
use crate::next_solver::{
Binder, BoundConst, BoundRegion, BoundTy, Const, DbInterner, PlaceholderConst,
PlaceholderRegion, PlaceholderTy, Region, Ty,

View file

@ -30,7 +30,7 @@ use crate::next_solver::{
AliasTy, Binder, Const, DbInterner, Goal, ParamEnv, Predicate, PredicateKind, Region, Span, Ty,
TyKind,
infer::{
DefineOpaqueTypes, InferCtxt, TypeTrace,
InferCtxt, TypeTrace,
relate::RelateResult,
traits::{Obligation, PredicateObligations},
},
@ -92,10 +92,7 @@ impl<'db> TypeRelation<DbInterner<'db>> for LatticeOp<'_, 'db> {
match variance {
Variance::Invariant => {
self.obligations.extend(
self.infcx
.at(&self.trace.cause, self.param_env)
.eq_trace(DefineOpaqueTypes::Yes, self.trace.clone(), a, b)?
.into_obligations(),
self.infcx.at(&self.trace.cause, self.param_env).eq(a, b)?.into_obligations(),
);
Ok(a)
}
@ -213,12 +210,12 @@ impl<'infcx, 'db> LatticeOp<'infcx, 'db> {
let at = self.infcx.at(&self.trace.cause, self.param_env);
match self.kind {
LatticeOpKind::Glb => {
self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, v, a)?.into_obligations());
self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, v, b)?.into_obligations());
self.obligations.extend(at.sub(v, a)?.into_obligations());
self.obligations.extend(at.sub(v, b)?.into_obligations());
}
LatticeOpKind::Lub => {
self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, a, v)?.into_obligations());
self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, b, v)?.into_obligations());
self.obligations.extend(at.sub(a, v)?.into_obligations());
self.obligations.extend(at.sub(b, v)?.into_obligations());
}
}
Ok(())

View file

@ -1,15 +1,14 @@
//! Things for resolving vars in the infer context of the next-trait-solver.
use rustc_type_ir::{
ConstKind, FallibleTypeFolder, InferConst, InferTy, RegionKind, TyKind, TypeFoldable,
TypeFolder, TypeSuperFoldable, TypeVisitableExt,
data_structures::DelayedMap,
inherent::{Const as _, IntoKind, Ty as _},
inherent::{Const as _, Ty as _},
};
use crate::next_solver::{Const, DbInterner, ErrorGuaranteed, Region, Ty};
use super::{FixupError, FixupResult, InferCtxt};
use super::InferCtxt;
///////////////////////////////////////////////////////////////////////////
// OPPORTUNISTIC VAR RESOLVER

View file

@ -1,3 +1,5 @@
#![expect(dead_code, reason = "this is used by rustc")]
use std::ops::ControlFlow;
use hir_def::{ImplId, TraitId};
@ -61,7 +63,7 @@ pub enum NotConstEvaluatable {
/// so they are noops when unioned with a definite error, and within
/// the categories it's easy to see that the unions are correct.
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub enum EvaluationResult {
pub(crate) enum EvaluationResult {
/// Evaluation successful.
EvaluatedToOk,
/// Evaluation successful, but there were unevaluated region obligations.
@ -91,17 +93,17 @@ pub enum EvaluationResult {
impl EvaluationResult {
/// Returns `true` if this evaluation result is known to apply, even
/// considering outlives constraints.
pub fn must_apply_considering_regions(self) -> bool {
pub(crate) fn must_apply_considering_regions(self) -> bool {
self == EvaluatedToOk
}
/// Returns `true` if this evaluation result is known to apply, ignoring
/// outlives constraints.
pub fn must_apply_modulo_regions(self) -> bool {
pub(crate) fn must_apply_modulo_regions(self) -> bool {
self <= EvaluatedToOkModuloRegions
}
pub fn may_apply(self) -> bool {
pub(crate) fn may_apply(self) -> bool {
match self {
EvaluatedToOkModuloOpaqueTypes
| EvaluatedToOk
@ -113,7 +115,7 @@ impl EvaluationResult {
}
}
pub fn is_stack_dependent(self) -> bool {
pub(crate) fn is_stack_dependent(self) -> bool {
match self {
EvaluatedToAmbigStackDependent => true,
@ -135,9 +137,9 @@ pub enum OverflowError {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SignatureMismatchData<'db> {
pub found_trait_ref: TraitRef<'db>,
pub expected_trait_ref: TraitRef<'db>,
pub terr: TypeError<'db>,
pub(crate) found_trait_ref: TraitRef<'db>,
pub(crate) expected_trait_ref: TraitRef<'db>,
pub(crate) terr: TypeError<'db>,
}
/// When performing resolution, it is typically the case that there
@ -147,7 +149,7 @@ pub struct SignatureMismatchData<'db> {
/// - `Ok(None)`: could not definitely determine anything, usually due
/// to inconclusive type inference.
/// - `Err(e)`: error `e` occurred
pub type SelectionResult<'db, T> = Result<Option<T>, SelectionError<'db>>;
pub(crate) type SelectionResult<'db, T> = Result<Option<T>, SelectionError<'db>>;
/// Given the successful resolution of an obligation, the `ImplSource`
/// indicates where the impl comes from.
@ -179,7 +181,7 @@ pub type SelectionResult<'db, T> = Result<Option<T>, SelectionError<'db>>;
///
/// See explanation on `ImplSourceUserDefinedData`.
#[derive(Debug, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
pub enum ImplSource<'db, N> {
pub(crate) enum ImplSource<'db, N> {
/// ImplSource identifying a particular impl.
UserDefined(ImplSourceUserDefinedData<'db, N>),
@ -194,28 +196,28 @@ pub enum ImplSource<'db, N> {
}
impl<'db, N> ImplSource<'db, N> {
pub fn nested_obligations(self) -> Vec<N> {
pub(crate) fn nested_obligations(self) -> Vec<N> {
match self {
ImplSource::UserDefined(i) => i.nested,
ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
}
}
pub fn borrow_nested_obligations(&self) -> &[N] {
pub(crate) fn borrow_nested_obligations(&self) -> &[N] {
match self {
ImplSource::UserDefined(i) => &i.nested,
ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
}
}
pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
pub(crate) fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
match self {
ImplSource::UserDefined(i) => &mut i.nested,
ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
}
}
pub fn map<M, F>(self, f: F) -> ImplSource<'db, M>
pub(crate) fn map<M, F>(self, f: F) -> ImplSource<'db, M>
where
F: FnMut(N) -> M,
{
@ -244,15 +246,15 @@ impl<'db, N> ImplSource<'db, N> {
/// is `()`, because codegen only requires a shallow resolution of an
/// impl, and nested obligations are satisfied later.
#[derive(Debug, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
pub struct ImplSourceUserDefinedData<'db, N> {
pub(crate) struct ImplSourceUserDefinedData<'db, N> {
#[type_visitable(ignore)]
#[type_foldable(identity)]
pub impl_def_id: ImplId,
pub args: GenericArgs<'db>,
pub nested: Vec<N>,
pub(crate) impl_def_id: ImplId,
pub(crate) args: GenericArgs<'db>,
pub(crate) nested: Vec<N>,
}
pub type Selection<'db> = ImplSource<'db, PredicateObligation<'db>>;
pub(crate) type Selection<'db> = ImplSource<'db, PredicateObligation<'db>>;
impl<'db> InferCtxt<'db> {
pub(crate) fn select(

View file

@ -41,9 +41,7 @@ fn const_vars_since_snapshot<'db>(
range.clone(),
iter_idx_range(range)
.map(|index| match table.probe_value(index) {
ConstVariableValue::Known { value: _ } => {
ConstVariableOrigin { param_def_id: None }
}
ConstVariableValue::Known { value: _ } => ConstVariableOrigin {},
ConstVariableValue::Unknown { origin, universe: _ } => origin,
})
.collect(),
@ -228,7 +226,6 @@ impl<'a, 'db> TypeFolder<DbInterner<'db>> for InferenceFudger<'a, 'db> {
fn fold_region(&mut self, r: Region<'db>) -> Region<'db> {
if let RegionKind::ReVar(vid) = r.kind() {
if self.snapshot_vars.region_vars.contains(&vid) {
let idx = vid.index() - self.snapshot_vars.region_vars.start.index();
self.infcx.next_region_var()
} else {
r

View file

@ -1,7 +1,5 @@
//! Snapshotting in the infer ctxt of the next-trait-solver.
use std::marker::PhantomData;
use ena::snapshot_vec as sv;
use ena::undo_log::{Rollback, UndoLogs};
use ena::unify as ut;
@ -14,7 +12,6 @@ use crate::next_solver::infer::opaque_types::OpaqueHiddenType;
use crate::next_solver::infer::unify_key::ConstVidKey;
use crate::next_solver::infer::unify_key::RegionVidKey;
use crate::next_solver::infer::{InferCtxtInner, region_constraints, type_variable};
use crate::traits;
pub struct Snapshot {
pub(crate) undo_len: usize,
@ -31,6 +28,7 @@ pub(crate) enum UndoLog<'db> {
FloatUnificationTable(sv::UndoLog<ut::Delegate<FloatVid>>),
RegionConstraintCollector(region_constraints::UndoLog<'db>),
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'db>>>),
#[expect(dead_code, reason = "this is used in rustc")]
PushRegionObligation,
}

View file

@ -9,17 +9,13 @@ use std::{
use hir_def::TraitId;
use macros::{TypeFoldable, TypeVisitable};
use rustc_type_ir::Upcast;
use rustc_type_ir::elaborate::Elaboratable;
use rustc_type_ir::{
PredicatePolarity, Upcast,
solve::{Certainty, NoSolution},
};
use rustc_type_ir::{TypeFoldable, TypeVisitable};
use tracing::debug;
use crate::next_solver::{
Binder, Clause, DbInterner, Goal, ParamEnv, PolyTraitPredicate, Predicate, SolverDefId, Span,
TraitPredicate, TraitRef, Ty,
Clause, DbInterner, Goal, ParamEnv, PolyTraitPredicate, Predicate, Span, TraitPredicate,
TraitRef, Ty,
};
use super::InferCtxt;
@ -106,9 +102,9 @@ impl<'db> Elaboratable<DbInterner<'db>> for PredicateObligation<'db> {
fn child_with_derived_cause(
&self,
clause: Clause<'db>,
span: Span,
parent_trait_pred: PolyTraitPredicate<'db>,
index: usize,
_span: Span,
_parent_trait_pred: PolyTraitPredicate<'db>,
_index: usize,
) -> Self {
let cause = ObligationCause::new();
Obligation {
@ -153,16 +149,16 @@ impl<'db, P> From<Obligation<'db, P>> for Goal<'db, P> {
}
}
pub type PredicateObligation<'db> = Obligation<'db, Predicate<'db>>;
pub type TraitObligation<'db> = Obligation<'db, TraitPredicate<'db>>;
pub(crate) type PredicateObligation<'db> = Obligation<'db, Predicate<'db>>;
pub(crate) type TraitObligation<'db> = Obligation<'db, TraitPredicate<'db>>;
pub type PredicateObligations<'db> = Vec<PredicateObligation<'db>>;
pub(crate) type PredicateObligations<'db> = Vec<PredicateObligation<'db>>;
impl<'db> PredicateObligation<'db> {
/// Flips the polarity of the inner predicate.
///
/// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`.
pub fn flip_polarity(&self, tcx: DbInterner<'db>) -> Option<PredicateObligation<'db>> {
pub fn flip_polarity(&self, _interner: DbInterner<'db>) -> Option<PredicateObligation<'db>> {
Some(PredicateObligation {
cause: self.cause.clone(),
param_env: self.param_env,
@ -215,7 +211,7 @@ impl<'db, O> Obligation<'db, O> {
/// `bound` or is not known to meet bound (note that this is
/// conservative towards *no impl*, which is the opposite of the
/// `evaluate` methods).
pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
pub(crate) fn type_known_to_meet_bound_modulo_regions<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>,

View file

@ -6,18 +6,18 @@ use std::marker::PhantomData;
use ena::unify::{NoError, UnifyKey, UnifyValue};
use rustc_type_ir::{ConstVid, RegionKind, RegionVid, UniverseIndex, inherent::IntoKind};
use crate::next_solver::{Const, Region, SolverDefId, Ty};
use crate::next_solver::{Const, Region};
#[derive(Clone, Debug)]
pub enum RegionVariableValue<'db> {
pub(crate) enum RegionVariableValue<'db> {
Known { value: Region<'db> },
Unknown { universe: UniverseIndex },
}
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RegionVidKey<'db> {
pub vid: RegionVid,
pub phantom: PhantomData<RegionVariableValue<'db>>,
pub(crate) struct RegionVidKey<'db> {
pub(crate) vid: RegionVid,
pub(crate) phantom: PhantomData<RegionVariableValue<'db>>,
}
impl<'db> From<RegionVid> for RegionVidKey<'db> {
@ -41,7 +41,7 @@ impl<'db> UnifyKey for RegionVidKey<'db> {
}
}
pub struct RegionUnificationError;
pub(crate) struct RegionUnificationError;
impl<'db> UnifyValue for RegionVariableValue<'db> {
type Error = RegionUnificationError;
@ -90,15 +90,10 @@ impl<'db> UnifyValue for RegionVariableValue<'db> {
// Generic consts.
#[derive(Copy, Clone, Debug)]
pub struct ConstVariableOrigin {
/// `DefId` of the const parameter this was instantiated for, if any.
///
/// This should only be used for diagnostics.
pub param_def_id: Option<SolverDefId>,
}
pub struct ConstVariableOrigin {}
#[derive(Clone, Debug)]
pub enum ConstVariableValue<'db> {
pub(crate) enum ConstVariableValue<'db> {
Known { value: Const<'db> },
Unknown { origin: ConstVariableOrigin, universe: UniverseIndex },
}
@ -106,7 +101,7 @@ pub enum ConstVariableValue<'db> {
impl<'db> ConstVariableValue<'db> {
/// If this value is known, returns the const it is known to be.
/// Otherwise, `None`.
pub fn known(&self) -> Option<Const<'db>> {
pub(crate) fn known(&self) -> Option<Const<'db>> {
match self {
ConstVariableValue::Unknown { .. } => None,
ConstVariableValue::Known { value } => Some(*value),
@ -115,9 +110,9 @@ impl<'db> ConstVariableValue<'db> {
}
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct ConstVidKey<'db> {
pub vid: ConstVid,
pub phantom: PhantomData<Const<'db>>,
pub(crate) struct ConstVidKey<'db> {
pub(crate) vid: ConstVid,
pub(crate) phantom: PhantomData<Const<'db>>,
}
impl<'db> From<ConstVid> for ConstVidKey<'db> {

View file

@ -1,4 +1,4 @@
pub use rustc_next_trait_solver::solve::inspect::*;
pub(crate) use rustc_next_trait_solver::solve::inspect::*;
use rustc_ast_ir::try_visit;
use rustc_next_trait_solver::{
@ -23,11 +23,11 @@ use crate::next_solver::{
obligation_ctxt::ObligationCtxt,
};
pub struct InspectConfig {
pub max_depth: usize,
pub(crate) struct InspectConfig {
pub(crate) max_depth: usize,
}
pub struct InspectGoal<'a, 'db> {
pub(crate) struct InspectGoal<'a, 'db> {
infcx: &'a SolverContext<'db>,
depth: usize,
orig_values: Vec<GenericArg<'db>>,
@ -103,7 +103,7 @@ impl<'db> NormalizesToTermHack<'db> {
}
}
pub struct InspectCandidate<'a, 'db> {
pub(crate) struct InspectCandidate<'a, 'db> {
goal: &'a InspectGoal<'a, 'db>,
kind: inspect::ProbeKind<DbInterner<'db>>,
steps: Vec<&'a inspect::ProbeStep<DbInterner<'db>>>,
@ -113,15 +113,15 @@ pub struct InspectCandidate<'a, 'db> {
}
impl<'a, 'db> InspectCandidate<'a, 'db> {
pub fn kind(&self) -> inspect::ProbeKind<DbInterner<'db>> {
pub(crate) fn kind(&self) -> inspect::ProbeKind<DbInterner<'db>> {
self.kind
}
pub fn result(&self) -> Result<Certainty, NoSolution> {
pub(crate) fn result(&self) -> Result<Certainty, NoSolution> {
self.result.map(|c| c.value.certainty)
}
pub fn goal(&self) -> &'a InspectGoal<'a, 'db> {
pub(crate) fn goal(&self) -> &'a InspectGoal<'a, 'db> {
self.goal
}
@ -133,14 +133,17 @@ impl<'a, 'db> InspectCandidate<'a, 'db> {
///
/// This is *not* the certainty of the candidate's full nested evaluation, which
/// can be accessed with [`Self::result`] instead.
pub fn shallow_certainty(&self) -> Certainty {
pub(crate) fn shallow_certainty(&self) -> Certainty {
self.shallow_certainty
}
/// Visit all nested goals of this candidate without rolling
/// back their inference constraints. This function modifies
/// the state of the `infcx`.
pub fn visit_nested_no_probe<V: ProofTreeVisitor<'db>>(&self, visitor: &mut V) -> V::Result {
pub(crate) fn visit_nested_no_probe<V: ProofTreeVisitor<'db>>(
&self,
visitor: &mut V,
) -> V::Result {
for goal in self.instantiate_nested_goals() {
try_visit!(goal.visit_with(visitor));
}
@ -152,7 +155,7 @@ impl<'a, 'db> InspectCandidate<'a, 'db> {
/// inference constraints. This function modifies the state of the `infcx`.
///
/// See [`Self::instantiate_impl_args`] if you need the impl args too.
pub fn instantiate_nested_goals(&self) -> Vec<InspectGoal<'a, 'db>> {
pub(crate) fn instantiate_nested_goals(&self) -> Vec<InspectGoal<'a, 'db>> {
let infcx = self.goal.infcx;
let param_env = self.goal.goal.param_env;
let mut orig_values = self.goal.orig_values.to_vec();
@ -200,7 +203,7 @@ impl<'a, 'db> InspectCandidate<'a, 'db> {
/// Instantiate the args of an impl if this candidate came from a
/// `CandidateSource::Impl`. This function modifies the state of the
/// `infcx`.
pub fn instantiate_impl_args(&self) -> GenericArgs<'db> {
pub(crate) fn instantiate_impl_args(&self) -> GenericArgs<'db> {
let infcx = self.goal.infcx;
let param_env = self.goal.goal.param_env;
let mut orig_values = self.goal.orig_values.to_vec();
@ -241,7 +244,7 @@ impl<'a, 'db> InspectCandidate<'a, 'db> {
panic!("expected impl args probe step for `instantiate_impl_args`");
}
pub fn instantiate_proof_tree_for_nested_goal(
pub(crate) fn instantiate_proof_tree_for_nested_goal(
&self,
source: GoalSource,
goal: Goal<'db, Predicate<'db>>,
@ -307,29 +310,33 @@ impl<'a, 'db> InspectCandidate<'a, 'db> {
/// Visit all nested goals of this candidate, rolling back
/// all inference constraints.
pub fn visit_nested_in_probe<V: ProofTreeVisitor<'db>>(&self, visitor: &mut V) -> V::Result {
#[expect(dead_code, reason = "used in rustc")]
pub(crate) fn visit_nested_in_probe<V: ProofTreeVisitor<'db>>(
&self,
visitor: &mut V,
) -> V::Result {
self.goal.infcx.probe(|_| self.visit_nested_no_probe(visitor))
}
}
impl<'a, 'db> InspectGoal<'a, 'db> {
pub fn infcx(&self) -> &'a InferCtxt<'db> {
pub(crate) fn infcx(&self) -> &'a InferCtxt<'db> {
self.infcx
}
pub fn goal(&self) -> Goal<'db, Predicate<'db>> {
pub(crate) fn goal(&self) -> Goal<'db, Predicate<'db>> {
self.goal
}
pub fn result(&self) -> Result<Certainty, NoSolution> {
pub(crate) fn result(&self) -> Result<Certainty, NoSolution> {
self.result
}
pub fn source(&self) -> GoalSource {
pub(crate) fn source(&self) -> GoalSource {
self.source
}
pub fn depth(&self) -> usize {
pub(crate) fn depth(&self) -> usize {
self.depth
}
@ -405,7 +412,7 @@ impl<'a, 'db> InspectGoal<'a, 'db> {
}
}
pub fn candidates(&'a self) -> Vec<InspectCandidate<'a, 'db>> {
pub(crate) fn candidates(&'a self) -> Vec<InspectCandidate<'a, 'db>> {
let mut candidates = vec![];
let mut nested_goals = vec![];
self.candidates_recur(&mut candidates, &mut nested_goals, &self.final_revision);
@ -415,7 +422,7 @@ impl<'a, 'db> InspectGoal<'a, 'db> {
/// Returns the single candidate applicable for the current goal, if it exists.
///
/// Returns `None` if there are either no or multiple applicable candidates.
pub fn unique_applicable_candidate(&'a self) -> Option<InspectCandidate<'a, 'db>> {
pub(crate) fn unique_applicable_candidate(&'a self) -> Option<InspectCandidate<'a, 'db>> {
// FIXME(-Znext-solver): This does not handle impl candidates
// hidden by env candidates.
let mut candidates = self.candidates();
@ -467,7 +474,7 @@ impl<'a, 'db> InspectGoal<'a, 'db> {
}
/// The public API to interact with proof trees.
pub trait ProofTreeVisitor<'db> {
pub(crate) trait ProofTreeVisitor<'db> {
type Result: VisitorResult;
fn config(&self) -> InspectConfig {

View file

@ -1,72 +1,48 @@
//! Things related to the Interner in the next-trait-solver.
#![allow(unused)] // FIXME(next-solver): Remove this.
use std::{fmt, ops::ControlFlow};
pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db};
use base_db::Crate;
use chalk_ir::{ProgramClauseImplication, SeparatorTraitRef, Variances};
use hir_def::{
AdtId, AttrDefId, BlockId, CallableDefId, EnumVariantId, GenericDefId, ItemContainerId, Lookup,
StructId, TypeAliasId, UnionId, VariantId,
AdtId, AttrDefId, BlockId, CallableDefId, EnumVariantId, ItemContainerId, StructId, UnionId,
VariantId,
lang_item::LangItem,
signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags},
};
use intern::sym::non_exhaustive;
use intern::{Interned, impl_internable, sym};
use la_arena::Idx;
use rustc_abi::{Align, ReprFlags, ReprOptions};
use rustc_ast_ir::visit::VisitorResult;
use rustc_abi::{ReprFlags, ReprOptions};
use rustc_hash::FxHashSet;
use rustc_index::{IndexVec, bit_set::DenseBitSet};
use rustc_index::bit_set::DenseBitSet;
use rustc_type_ir::{
AliasTerm, AliasTermKind, AliasTy, AliasTyKind, BoundVar, CollectAndApply, DebruijnIndex,
EarlyBinder, FlagComputation, Flags, GenericArgKind, ImplPolarity, InferTy,
ProjectionPredicate, RegionKind, TermKind, TraitPredicate, TraitRef, TypeVisitableExt,
UniverseIndex, Upcast, Variance, WithCachedTypeInfo,
elaborate::{self, elaborate},
AliasTermKind, AliasTyKind, BoundVar, CollectAndApply, DebruijnIndex, EarlyBinder,
FlagComputation, Flags, GenericArgKind, ImplPolarity, InferTy, TraitRef, TypeVisitableExt,
UniverseIndex, Upcast, Variance,
elaborate::elaborate,
error::TypeError,
inherent::{
self, AdtDef as _, Const as _, GenericArgs as _, GenericsOf, IntoKind, ParamEnv as _,
Region as _, SliceLike as _, Span as _, Ty as _,
},
ir_print,
inherent::{self, GenericsOf, IntoKind, SliceLike as _, Span as _, Ty as _},
lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem},
relate,
solve::SizedTraitKind,
};
use salsa::plumbing::AsId;
use smallvec::{SmallVec, smallvec};
use syntax::ast::SelfParamKind;
use tracing::debug;
use triomphe::Arc;
use crate::{
ConstScalar, FnAbi, Interner,
FnAbi,
db::HirDatabase,
lower_nextsolver::{self, TyLoweringContext},
method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TyFingerprint},
next_solver::{
AdtIdWrapper, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper,
CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, ImplIdWrapper, InternedWrapperNoDebug,
RegionAssumptions, SolverContext, SolverDefIds, TraitIdWrapper, TypeAliasIdWrapper,
TypingMode,
infer::{
DbInternerInferExt, InferCtxt,
traits::{Obligation, ObligationCause},
},
obligation_ctxt::ObligationCtxt,
util::{ContainsTypeErrors, explicit_item_bounds, for_trait_impls},
},
};
use super::{
Binder, BoundExistentialPredicate, BoundExistentialPredicates, BoundTy, BoundTyKind, Clause,
ClauseKind, Clauses, Const, ConstKind, ErrorGuaranteed, ExprConst, ExternalConstraints,
ExternalConstraintsData, GenericArg, GenericArgs, InternedClausesWrapper, ParamConst, ParamEnv,
ParamTy, PlaceholderConst, PlaceholderTy, PredefinedOpaques, PredefinedOpaquesData, Predicate,
PredicateKind, SolverDefId, Term, Ty, TyKind, Tys, Valtree, ValueConst,
Binder, BoundExistentialPredicates, BoundTy, BoundTyKind, Clause, ClauseKind, Clauses, Const,
ErrorGuaranteed, ExprConst, ExternalConstraints, GenericArg, GenericArgs, ParamConst, ParamEnv,
ParamTy, PlaceholderConst, PlaceholderTy, PredefinedOpaques, Predicate, SolverDefId, Term, Ty,
TyKind, Tys, Valtree, ValueConst,
abi::Safety,
fold::{BoundVarReplacer, BoundVarReplacerDelegate, FnMutDelegate},
generics::{Generics, generics},
@ -631,7 +607,6 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
self,
interner: DbInterner<'db>,
) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
let db = interner.db();
let hir_def::AdtId::StructId(struct_id) = self.inner().id else {
return None;
};
@ -647,23 +622,10 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
) -> EarlyBinder<DbInterner<'db>, impl IntoIterator<Item = Ty<'db>>> {
let db = interner.db();
// FIXME: this is disabled just to match the behavior with chalk right now
let field_tys = |id: VariantId| {
let variant_data = id.fields(db);
let fields = if variant_data.fields().is_empty() {
vec![]
} else {
let field_types = db.field_types_ns(id);
variant_data
.fields()
.iter()
.map(|(idx, _)| {
let ty = field_types[idx];
ty.skip_binder()
})
.collect()
};
let _field_tys = |id: VariantId| {
db.field_types_ns(id).iter().map(|(_, ty)| ty.skip_binder()).collect::<Vec<_>>()
};
let field_tys = |id: VariantId| vec![];
let field_tys = |_id: VariantId| vec![];
let tys: Vec<_> = match self.inner().id {
hir_def::AdtId::StructId(id) => field_tys(id.into()),
hir_def::AdtId::UnionId(id) => field_tys(id.into()),
@ -696,7 +658,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
fn destructor(
self,
interner: DbInterner<'db>,
_interner: DbInterner<'db>,
) -> Option<rustc_type_ir::solve::AdtDestructorKind> {
// FIXME(next-solver)
None
@ -742,7 +704,7 @@ impl<'db> inherent::Features<DbInterner<'db>> for Features {
false
}
fn feature_bound_holds_in_crate(self, symbol: ()) -> bool {
fn feature_bound_holds_in_crate(self, _symbol: ()) -> bool {
false
}
}
@ -1002,7 +964,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn mk_tracked<T: fmt::Debug + Clone>(
self,
data: T,
dep_node: Self::DepNodeIndex,
_dep_node: Self::DepNodeIndex,
) -> Self::Tracked<T> {
Tracked(data)
}
@ -1024,7 +986,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn canonical_param_env_cache_get_or_insert<R>(
self,
param_env: Self::ParamEnv,
_param_env: Self::ParamEnv,
f: impl FnOnce() -> rustc_type_ir::CanonicalParamEnvCacheEntry<Self>,
from_entry: impl FnOnce(&rustc_type_ir::CanonicalParamEnvCacheEntry<Self>) -> R,
) -> R {
@ -1162,17 +1124,17 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
(TraitRef::new_from_args(self, trait_def_id.try_into().unwrap(), trait_args), alias_args)
}
fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool {
fn check_args_compatible(self, _def_id: Self::DefId, _args: Self::GenericArgs) -> bool {
// FIXME
true
}
fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) {}
fn debug_assert_args_compatible(self, _def_id: Self::DefId, _args: Self::GenericArgs) {}
fn debug_assert_existential_args_compatible(
self,
def_id: Self::DefId,
args: Self::GenericArgs,
_def_id: Self::DefId,
_args: Self::GenericArgs,
) {
}
@ -1240,11 +1202,11 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
self.db().callable_item_signature(def_id.0)
}
fn coroutine_movability(self, def_id: Self::CoroutineId) -> rustc_ast_ir::Movability {
fn coroutine_movability(self, _def_id: Self::CoroutineId) -> rustc_ast_ir::Movability {
unimplemented!()
}
fn coroutine_for_closure(self, def_id: Self::CoroutineId) -> Self::CoroutineId {
fn coroutine_for_closure(self, _def_id: Self::CoroutineId) -> Self::CoroutineId {
unimplemented!()
}
@ -1421,9 +1383,10 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
})
}
#[expect(unreachable_code)]
fn const_conditions(
self,
def_id: Self::DefId,
_def_id: Self::DefId,
) -> EarlyBinder<
Self,
impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
@ -1431,7 +1394,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
EarlyBinder::bind([unimplemented!()])
}
fn has_target_features(self, def_id: Self::FunctionId) -> bool {
fn has_target_features(self, _def_id: Self::FunctionId) -> bool {
false
}
@ -1462,7 +1425,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
hir_def::lang_item::LangItemTarget::Union(union_id) => union_id.into(),
hir_def::lang_item::LangItemTarget::TypeAlias(type_alias_id) => type_alias_id.into(),
hir_def::lang_item::LangItemTarget::Trait(trait_id) => trait_id.into(),
hir_def::lang_item::LangItemTarget::EnumVariant(enum_variant_id) => unimplemented!(),
hir_def::lang_item::LangItemTarget::EnumVariant(_) => unimplemented!(),
}
}
@ -1552,7 +1515,6 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
CoroutineReturn,
CoroutineYield,
FutureOutput,
AsyncFnOnceOutput,
CallRefFuture,
CallOnceFuture,
AsyncFnOnceOutput,
@ -1596,7 +1558,6 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
AsyncFnMut,
AsyncFnOnce,
AsyncFnOnceOutput,
AsyncFnOnceOutput,
)
}
@ -1636,7 +1597,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
};
if fps.is_empty() {
for_trait_impls(
_ = for_trait_impls(
self.db(),
self.krate.expect("Must have self.krate"),
self.block,
@ -1658,7 +1619,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
},
);
} else {
for_trait_impls(
_ = for_trait_impls(
self.db(),
self.krate.expect("Must have self.krate"),
self.block,
@ -1698,7 +1659,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
}
}
fn has_item_definition(self, def_id: Self::DefId) -> bool {
fn has_item_definition(self, _def_id: Self::DefId) -> bool {
// FIXME(next-solver): should check if the associated item has a value.
true
}
@ -1746,13 +1707,13 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
trait_data.flags.contains(TraitFlags::FUNDAMENTAL)
}
fn trait_may_be_implemented_via_object(self, trait_def_id: Self::TraitId) -> bool {
fn trait_may_be_implemented_via_object(self, _trait_def_id: Self::TraitId) -> bool {
// FIXME(next-solver): should check the `TraitFlags` for
// the `#[rustc_do_not_implement_via_object]` flag
true
}
fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool {
fn is_impl_trait_in_trait(self, _def_id: Self::DefId) -> bool {
// FIXME(next-solver)
false
}
@ -1761,22 +1722,22 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
panic!("Bug encountered in next-trait-solver: {}", msg.to_string())
}
fn is_general_coroutine(self, coroutine_def_id: Self::CoroutineId) -> bool {
fn is_general_coroutine(self, _coroutine_def_id: Self::CoroutineId) -> bool {
// FIXME(next-solver)
true
}
fn coroutine_is_async(self, coroutine_def_id: Self::CoroutineId) -> bool {
fn coroutine_is_async(self, _coroutine_def_id: Self::CoroutineId) -> bool {
// FIXME(next-solver)
true
}
fn coroutine_is_gen(self, coroutine_def_id: Self::CoroutineId) -> bool {
fn coroutine_is_gen(self, _coroutine_def_id: Self::CoroutineId) -> bool {
// FIXME(next-solver)
false
}
fn coroutine_is_async_gen(self, coroutine_def_id: Self::CoroutineId) -> bool {
fn coroutine_is_async_gen(self, _coroutine_def_id: Self::CoroutineId) -> bool {
// FIXME(next-solver)
false
}
@ -1870,19 +1831,19 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
Binder::bind_with_vars(inner, bound_vars)
}
fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds {
fn opaque_types_defined_by(self, _defining_anchor: Self::LocalDefId) -> Self::LocalDefIds {
// FIXME(next-solver)
SolverDefIds::new_from_iter(self, [])
}
fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool {
fn alias_has_const_conditions(self, _def_id: Self::DefId) -> bool {
// FIXME(next-solver)
false
}
fn explicit_implied_const_bounds(
self,
def_id: Self::DefId,
_def_id: Self::DefId,
) -> EarlyBinder<
Self,
impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
@ -1899,14 +1860,14 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
self.db().function_signature(id).flags.contains(FnFlags::CONST)
}
fn impl_is_const(self, def_id: Self::ImplId) -> bool {
fn impl_is_const(self, _def_id: Self::ImplId) -> bool {
false
}
fn opt_alias_variances(
self,
kind: impl Into<rustc_type_ir::AliasTermKind>,
def_id: Self::DefId,
_kind: impl Into<rustc_type_ir::AliasTermKind>,
_def_id: Self::DefId,
) -> Option<Self::VariancesOf> {
None
}
@ -1933,7 +1894,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn coroutine_hidden_types(
self,
def_id: Self::CoroutineId,
_def_id: Self::CoroutineId,
) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::CoroutineWitnessTypes<Self>>>
{
// FIXME(next-solver)
@ -1952,14 +1913,14 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
self.db().trait_signature(trait_.0).flags.contains(TraitFlags::UNSAFE)
}
fn impl_self_is_guaranteed_unsized(self, def_id: Self::ImplId) -> bool {
fn impl_self_is_guaranteed_unsized(self, _def_id: Self::ImplId) -> bool {
false
}
fn impl_specializes(
self,
specializing_impl_def_id: Self::ImplId,
parent_impl_def_id: Self::ImplId,
_specializing_impl_def_id: Self::ImplId,
_parent_impl_def_id: Self::ImplId,
) -> bool {
false
}
@ -1970,7 +1931,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn opaque_types_and_coroutines_defined_by(
self,
defining_anchor: Self::LocalDefId,
_defining_anchor: Self::LocalDefId,
) -> Self::LocalDefIds {
Default::default()
}

View file

@ -5,8 +5,6 @@ use std::any::type_name_of_val;
use rustc_type_ir::inherent::SliceLike;
use rustc_type_ir::{self as ty, ir_print::IrPrint};
use crate::db::HirDatabase;
use super::SolverDefId;
use super::interner::DbInterner;

View file

@ -1,35 +1,25 @@
//! Things useful for mapping to/from Chalk and next-trait-solver types.
use base_db::Crate;
use chalk_ir::{
CanonicalVarKind, CanonicalVarKinds, FnPointer, InferenceVar, Substitution, TyVariableKind,
WellFormed, cast::Cast, fold::Shift, interner::HasInterner,
};
use hir_def::{
CallableDefId, ConstParamId, FunctionId, GeneralConstId, LifetimeParamId, TypeAliasId,
TypeOrConstParamId, TypeParamId, signatures::TraitFlags,
InferenceVar, Substitution, TyVariableKind, WellFormed, cast::Cast, fold::Shift,
interner::HasInterner,
};
use hir_def::{CallableDefId, ConstParamId, GeneralConstId, TypeParamId, signatures::TraitFlags};
use hir_def::{GenericDefId, GenericParamId};
use intern::sym;
use rustc_type_ir::{
AliasTerm, BoundVar, DebruijnIndex, ExistentialProjection, ExistentialTraitRef, Interner as _,
AliasTerm, BoundVar, DebruijnIndex, ExistentialProjection, ExistentialTraitRef,
OutlivesPredicate, ProjectionPredicate, TypeFoldable, TypeSuperFoldable, TypeVisitable,
TypeVisitableExt, UniverseIndex, elaborate,
inherent::{BoundVarLike, Clause as _, IntoKind, PlaceholderLike, SliceLike, Ty as _},
UniverseIndex, elaborate,
inherent::{BoundVarLike, IntoKind, SliceLike, Ty as _},
shift_vars,
solve::Goal,
};
use salsa::plumbing::FromId;
use salsa::{Id, plumbing::AsId};
use crate::next_solver::BoundConst;
use crate::{
ConstScalar, ImplTraitId, Interner, MemoryMap,
db::{
HirDatabase, InternedClosureId, InternedCoroutineId, InternedLifetimeParamId,
InternedOpaqueTyId, InternedTypeOrConstParamId,
},
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
ConstScalar, Interner, MemoryMap,
db::{InternedClosureId, InternedCoroutineId, InternedOpaqueTyId},
from_assoc_type_id, from_chalk_trait_id,
mapping::ToChalk,
next_solver::{
Binder, ClauseKind, ConstBytes, TraitPredicate, UnevaluatedConst,
@ -42,11 +32,10 @@ use crate::{
};
use super::{
BoundExistentialPredicate, BoundExistentialPredicates, BoundRegion, BoundRegionKind, BoundTy,
BoundTyKind, Canonical, CanonicalVars, Clause, Clauses, Const, Ctor, EarlyParamRegion,
ErrorGuaranteed, ExistentialPredicate, GenericArg, GenericArgs, ParamConst, ParamEnv, ParamTy,
Placeholder, PlaceholderConst, PlaceholderRegion, PlaceholderTy, Predicate, PredicateKind,
Region, SolverDefId, SubtypePredicate, Term, TraitRef, Ty, Tys, ValueConst, VariancesOf,
BoundExistentialPredicates, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, Canonical,
CanonicalVars, Clause, Clauses, Const, EarlyParamRegion, ErrorGuaranteed, ExistentialPredicate,
GenericArg, GenericArgs, ParamConst, ParamEnv, ParamTy, Predicate, PredicateKind, Region,
SolverDefId, SubtypePredicate, Term, TraitRef, Ty, Tys, ValueConst,
};
// FIXME: This should urgently go (as soon as we finish the migration off Chalk, that is).
@ -167,7 +156,7 @@ where
}
impl NextSolverToChalk<'_, chalk_ir::Mutability> for rustc_ast_ir::Mutability {
fn to_chalk(self, interner: DbInterner<'_>) -> chalk_ir::Mutability {
fn to_chalk(self, _interner: DbInterner<'_>) -> chalk_ir::Mutability {
match self {
rustc_ast_ir::Mutability::Not => chalk_ir::Mutability::Not,
rustc_ast_ir::Mutability::Mut => chalk_ir::Mutability::Mut,
@ -176,7 +165,7 @@ impl NextSolverToChalk<'_, chalk_ir::Mutability> for rustc_ast_ir::Mutability {
}
impl NextSolverToChalk<'_, chalk_ir::Safety> for crate::next_solver::abi::Safety {
fn to_chalk(self, interner: DbInterner<'_>) -> chalk_ir::Safety {
fn to_chalk(self, _interner: DbInterner<'_>) -> chalk_ir::Safety {
match self {
crate::next_solver::abi::Safety::Unsafe => chalk_ir::Safety::Unsafe,
crate::next_solver::abi::Safety::Safe => chalk_ir::Safety::Safe,
@ -349,8 +338,6 @@ impl<'db> ChalkToNextSolver<'db, Ty<'db>> for chalk_ir::Ty<Interner> {
let id =
from_assoc_type_id(projection.associated_ty_id);
let def_id = SolverDefId::TypeAliasId(id);
let generics = interner.generics_of(def_id);
let parent_len = generics.parent_count;
let substs = projection.substitution.iter(Interner).skip(1);
let args = GenericArgs::new_from_iter(
@ -363,7 +350,7 @@ impl<'db> ChalkToNextSolver<'db, Ty<'db>> for chalk_ir::Ty<Interner> {
);
(def_id, args)
}
chalk_ir::AliasTy::Opaque(opaque_ty) => {
chalk_ir::AliasTy::Opaque(_opaque_ty) => {
panic!("Invalid ExistentialPredicate (opaques can't be named).");
}
};
@ -379,10 +366,10 @@ impl<'db> ChalkToNextSolver<'db, Ty<'db>> for chalk_ir::Ty<Interner> {
);
ExistentialPredicate::Projection(projection)
}
chalk_ir::WhereClause::LifetimeOutlives(lifetime_outlives) => {
chalk_ir::WhereClause::LifetimeOutlives(_lifetime_outlives) => {
return None;
}
chalk_ir::WhereClause::TypeOutlives(type_outlives) => return None,
chalk_ir::WhereClause::TypeOutlives(_type_outlives) => return None,
};
Some(Binder::bind_with_vars(clause, bound_vars))
@ -621,7 +608,7 @@ impl<'db> NextSolverToChalk<'db, chalk_ir::VariableKinds<Interner>> for BoundVar
}
impl<'db> ChalkToNextSolver<'db, BoundVarKind> for chalk_ir::VariableKind<Interner> {
fn to_nextsolver(&self, interner: DbInterner<'db>) -> BoundVarKind {
fn to_nextsolver(&self, _interner: DbInterner<'db>) -> BoundVarKind {
match self {
chalk_ir::VariableKind::Ty(_ty_variable_kind) => BoundVarKind::Ty(BoundTyKind::Anon),
chalk_ir::VariableKind::Lifetime => BoundVarKind::Region(BoundRegionKind::Anon),
@ -631,7 +618,7 @@ impl<'db> ChalkToNextSolver<'db, BoundVarKind> for chalk_ir::VariableKind<Intern
}
impl<'db> NextSolverToChalk<'db, chalk_ir::VariableKind<Interner>> for BoundVarKind {
fn to_chalk(self, interner: DbInterner<'db>) -> chalk_ir::VariableKind<Interner> {
fn to_chalk(self, _interner: DbInterner<'db>) -> chalk_ir::VariableKind<Interner> {
match self {
BoundVarKind::Ty(_) => chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
BoundVarKind::Region(_) => chalk_ir::VariableKind::Lifetime,
@ -676,7 +663,7 @@ impl<'db> ChalkToNextSolver<'db, crate::lower_nextsolver::ImplTraitIdx<'db>>
{
fn to_nextsolver(
&self,
interner: DbInterner<'db>,
_interner: DbInterner<'db>,
) -> crate::lower_nextsolver::ImplTraitIdx<'db> {
crate::lower_nextsolver::ImplTraitIdx::from_raw(self.into_raw())
}
@ -739,7 +726,7 @@ impl<'db> NextSolverToChalk<'db, chalk_ir::UniverseIndex> for rustc_type_ir::Uni
impl<'db> ChalkToNextSolver<'db, rustc_type_ir::InferTy>
for (chalk_ir::InferenceVar, chalk_ir::TyVariableKind)
{
fn to_nextsolver(&self, interner: DbInterner<'db>) -> rustc_type_ir::InferTy {
fn to_nextsolver(&self, _interner: DbInterner<'db>) -> rustc_type_ir::InferTy {
match self.1 {
chalk_ir::TyVariableKind::General => {
rustc_type_ir::InferTy::TyVar(rustc_type_ir::TyVid::from_u32(self.0.index()))
@ -755,7 +742,7 @@ impl<'db> ChalkToNextSolver<'db, rustc_type_ir::InferTy>
}
impl<'db> ChalkToNextSolver<'db, rustc_ast_ir::Mutability> for chalk_ir::Mutability {
fn to_nextsolver(&self, interner: DbInterner<'db>) -> rustc_ast_ir::Mutability {
fn to_nextsolver(&self, _interner: DbInterner<'db>) -> rustc_ast_ir::Mutability {
match self {
chalk_ir::Mutability::Mut => rustc_ast_ir::Mutability::Mut,
chalk_ir::Mutability::Not => rustc_ast_ir::Mutability::Not,
@ -808,7 +795,7 @@ impl<'db, T: HasInterner<Interner = Interner> + ChalkToNextSolver<'db, U>, U>
chalk_ir::VariableKind::Lifetime => {
rustc_type_ir::CanonicalVarKind::Region(UniverseIndex::ROOT)
}
chalk_ir::VariableKind::Const(ty) => {
chalk_ir::VariableKind::Const(_ty) => {
rustc_type_ir::CanonicalVarKind::Const(UniverseIndex::ROOT)
}
}),
@ -863,25 +850,25 @@ impl<'db, T: NextSolverToChalk<'db, U>, U: HasInterner<Interner = Interner>>
impl<'db> ChalkToNextSolver<'db, Predicate<'db>> for chalk_ir::Goal<Interner> {
fn to_nextsolver(&self, interner: DbInterner<'db>) -> Predicate<'db> {
match self.data(Interner) {
chalk_ir::GoalData::Quantified(quantifier_kind, binders) => {
chalk_ir::GoalData::Quantified(_quantifier_kind, binders) => {
if !binders.binders.is_empty(Interner) {
panic!("Should not be constructed.");
}
let (val, _) = binders.clone().into_value_and_skipped_binders();
val.shifted_out(Interner).unwrap().to_nextsolver(interner)
}
chalk_ir::GoalData::Implies(program_clauses, goal) => {
chalk_ir::GoalData::Implies(_program_clauses, _goal) => {
panic!("Should not be constructed.")
}
chalk_ir::GoalData::All(goals) => panic!("Should not be constructed."),
chalk_ir::GoalData::Not(goal) => panic!("Should not be constructed."),
chalk_ir::GoalData::All(_goals) => panic!("Should not be constructed."),
chalk_ir::GoalData::Not(_goal) => panic!("Should not be constructed."),
chalk_ir::GoalData::EqGoal(eq_goal) => {
let arg_to_term = |g: &chalk_ir::GenericArg<Interner>| match g.data(Interner) {
chalk_ir::GenericArgData::Ty(ty) => Term::Ty(ty.to_nextsolver(interner)),
chalk_ir::GenericArgData::Const(const_) => {
Term::Const(const_.to_nextsolver(interner))
}
chalk_ir::GenericArgData::Lifetime(lifetime) => unreachable!(),
chalk_ir::GenericArgData::Lifetime(_lifetime) => unreachable!(),
};
let pred_kind = PredicateKind::AliasRelate(
arg_to_term(&eq_goal.a),
@ -1112,16 +1099,16 @@ impl<'db> ChalkToNextSolver<'db, PredicateKind<'db>> for chalk_ir::DomainGoal<In
Term::Ty(ty.to_nextsolver(interner)),
)),
},
chalk_ir::DomainGoal::IsLocal(ty) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::IsUpstream(ty) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::IsFullyVisible(ty) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::LocalImplAllowed(trait_ref) => {
chalk_ir::DomainGoal::IsLocal(_ty) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::IsUpstream(_ty) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::IsFullyVisible(_ty) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::LocalImplAllowed(_trait_ref) => {
panic!("Should not be constructed.")
}
chalk_ir::DomainGoal::Compatible => panic!("Should not be constructed."),
chalk_ir::DomainGoal::DownstreamType(ty) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::DownstreamType(_ty) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::Reveal => panic!("Should not be constructed."),
chalk_ir::DomainGoal::ObjectSafe(trait_id) => panic!("Should not be constructed."),
chalk_ir::DomainGoal::ObjectSafe(_trait_id) => panic!("Should not be constructed."),
}
}
}
@ -1176,7 +1163,7 @@ impl<'db> NextSolverToChalk<'db, chalk_ir::GoalData<Interner>> for PredicateKind
rustc_type_ir::PredicateKind::AliasRelate(
alias_term,
target_term,
alias_relation_direction,
_alias_relation_direction,
) => {
let term_to_generic_arg = |term: Term<'db>| match term {
Term::Ty(ty) => chalk_ir::GenericArg::new(
@ -1462,7 +1449,7 @@ pub fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>) -> cra
},
// For `Placeholder`, `Bound` and `Param`, see the comment on the reverse conversion.
rustc_type_ir::TyKind::Placeholder(placeholder) => {
rustc_type_ir::TyKind::Placeholder(_placeholder) => {
unimplemented!(
"A `rustc_type_ir::TyKind::Placeholder` doesn't have a direct \
correspondence in Chalk, as it represents a universally instantiated `Bound`.\n\
@ -1511,10 +1498,10 @@ pub fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>) -> cra
let binders = chalk_ir::VariableKinds::from_iter(
Interner,
p.bound_vars().iter().map(|b| match b {
BoundVarKind::Ty(kind) => {
BoundVarKind::Ty(_kind) => {
chalk_ir::VariableKind::Ty(TyVariableKind::General)
}
BoundVarKind::Region(kind) => chalk_ir::VariableKind::Lifetime,
BoundVarKind::Region(_kind) => chalk_ir::VariableKind::Lifetime,
BoundVarKind::Const => {
chalk_ir::VariableKind::Const(crate::TyKind::Error.intern(Interner))
}
@ -1644,7 +1631,7 @@ pub fn convert_const_for_result<'db>(
rustc_type_ir::ConstKind::Infer(rustc_type_ir::InferConst::Var(var)) => {
chalk_ir::ConstValue::InferenceVar(chalk_ir::InferenceVar::from(var.as_u32()))
}
rustc_type_ir::ConstKind::Infer(rustc_type_ir::InferConst::Fresh(fresh)) => {
rustc_type_ir::ConstKind::Infer(rustc_type_ir::InferConst::Fresh(_fresh)) => {
panic!("Vars should not be freshened.")
}
rustc_type_ir::ConstKind::Param(param) => {
@ -1657,7 +1644,7 @@ pub fn convert_const_for_result<'db>(
var.var.index(),
))
}
rustc_type_ir::ConstKind::Placeholder(placeholder_const) => {
rustc_type_ir::ConstKind::Placeholder(_placeholder_const) => {
unimplemented!(
"A `rustc_type_ir::ConstKind::Placeholder` doesn't have a direct \
correspondence in Chalk, as it represents a universally instantiated `Bound`.\n\
@ -1717,7 +1704,7 @@ pub fn convert_region_for_result<'db>(
bound.var.as_usize(),
))
}
rustc_type_ir::RegionKind::RePlaceholder(placeholder) => unimplemented!(
rustc_type_ir::RegionKind::RePlaceholder(_placeholder) => unimplemented!(
"A `rustc_type_ir::RegionKind::RePlaceholder` doesn't have a direct \
correspondence in Chalk, as it represents a universally instantiated `Bound`.\n\
It therefore feels safer to leave it panicking, but if you hit this panic \

View file

@ -5,7 +5,6 @@ use rustc_type_ir::{
inherent::{IntoKind, Term as _},
};
use crate::next_solver::SolverDefId;
use crate::next_solver::{
Binder, Const, ConstKind, DbInterner, Goal, ParamEnv, Predicate, PredicateKind, Term, Ty,
TyKind,

View file

@ -1,14 +1,15 @@
use hir_def::TraitId;
use rustc_type_ir::relate::Relate;
use rustc_type_ir::{TypeFoldable, Upcast, Variance};
use crate::next_solver::fulfill::{FulfillmentCtxt, NextSolverError};
use crate::next_solver::infer::at::ToTrace;
use crate::next_solver::infer::traits::{
Obligation, ObligationCause, PredicateObligation, PredicateObligations,
use crate::next_solver::{
Const, DbInterner, ParamEnv, Term, TraitRef, Ty, TypeError,
fulfill::{FulfillmentCtxt, NextSolverError},
infer::{
InferCtxt, InferOk,
at::ToTrace,
traits::{Obligation, ObligationCause, PredicateObligation, PredicateObligations},
},
};
use crate::next_solver::infer::{DefineOpaqueTypes, InferCtxt, InferOk, TypeTrace};
use crate::next_solver::{Const, DbInterner, ParamEnv, Term, TraitRef, Ty, TypeError};
/// Used if you want to have pleasant experience when dealing
/// with obligations outside of hir or mir typeck.
@ -69,21 +70,7 @@ impl<'a, 'db> ObligationCtxt<'a, 'db> {
) -> Result<(), TypeError<'db>> {
self.infcx
.at(cause, param_env)
.eq(DefineOpaqueTypes::Yes, expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}
pub fn eq_trace<T: Relate<DbInterner<'db>>>(
&mut self,
cause: &ObligationCause,
param_env: ParamEnv<'db>,
trace: TypeTrace<'db>,
expected: T,
actual: T,
) -> Result<(), TypeError<'db>> {
self.infcx
.at(cause, param_env)
.eq_trace(DefineOpaqueTypes::Yes, trace, expected, actual)
.eq(expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}
@ -97,7 +84,7 @@ impl<'a, 'db> ObligationCtxt<'a, 'db> {
) -> Result<(), TypeError<'db>> {
self.infcx
.at(cause, param_env)
.sub(DefineOpaqueTypes::Yes, expected, actual)
.sub(expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}
@ -111,7 +98,7 @@ impl<'a, 'db> ObligationCtxt<'a, 'db> {
) -> Result<(), TypeError<'db>> {
self.infcx
.at(cause, param_env)
.relate(DefineOpaqueTypes::Yes, expected, variance, actual)
.relate(expected, variance, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}
@ -125,7 +112,7 @@ impl<'a, 'db> ObligationCtxt<'a, 'db> {
) -> Result<(), TypeError<'db>> {
self.infcx
.at(cause, param_env)
.sup(DefineOpaqueTypes::Yes, expected, actual)
.sup(expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}

View file

@ -1,11 +1,10 @@
//! Things related to opaques in the next-trait-solver.
use intern::Interned;
use rustc_ast_ir::try_visit;
use crate::next_solver::SolverDefId;
use super::{CanonicalVarKind, DbInterner, interned_vec_nolifetime_salsa};
use super::{DbInterner, interned_vec_nolifetime_salsa};
pub type OpaqueTypeKey<'db> = rustc_type_ir::OpaqueTypeKey<DbInterner<'db>>;
pub type PredefinedOpaquesData<'db> = rustc_type_ir::solve::PredefinedOpaquesData<DbInterner<'db>>;

View file

@ -2,19 +2,16 @@
use std::cmp::Ordering;
use intern::Interned;
use macros::{TypeFoldable, TypeVisitable};
use rustc_ast_ir::try_visit;
use rustc_type_ir::{
self as ty, CollectAndApply, DebruijnIndex, EarlyBinder, FlagComputation, Flags,
PredicatePolarity, TypeFlags, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
TypeVisitable, Upcast, UpcastFrom, VisitorResult, WithCachedTypeInfo,
TypeVisitable, Upcast, UpcastFrom, WithCachedTypeInfo,
elaborate::Elaboratable,
error::{ExpectedFound, TypeError},
inherent::{IntoKind, SliceLike},
relate::Relate,
};
use smallvec::{SmallVec, smallvec};
use smallvec::SmallVec;
use crate::next_solver::TraitIdWrapper;
@ -56,11 +53,11 @@ fn stable_cmp_existential_predicate<'db>(
// FIXME: this is actual unstable - see impl in predicate.rs in `rustc_middle`
match (a, b) {
(ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal,
(ExistentialPredicate::Projection(a), ExistentialPredicate::Projection(b)) => {
(ExistentialPredicate::Projection(_a), ExistentialPredicate::Projection(_b)) => {
// Should sort by def path hash
Ordering::Equal
}
(ExistentialPredicate::AutoTrait(a), ExistentialPredicate::AutoTrait(b)) => {
(ExistentialPredicate::AutoTrait(_a), ExistentialPredicate::AutoTrait(_b)) => {
// Should sort by def path hash
Ordering::Equal
}
@ -283,8 +280,6 @@ impl<'db> std::hash::Hash for InternedClausesWrapper<'db> {
}
}
type InternedClauses<'db> = Interned<InternedClausesWrapper<'db>>;
#[salsa::interned(constructor = new_)]
pub struct Clauses<'db> {
#[returns(ref)]

View file

@ -1,10 +1,9 @@
//! Things related to regions.
use hir_def::LifetimeParamId;
use intern::{Interned, Symbol};
use intern::Symbol;
use rustc_type_ir::{
BoundVar, DebruijnIndex, Flags, INNERMOST, RegionVid, TypeFlags, TypeFoldable, TypeVisitable,
VisitorResult,
inherent::{IntoKind, PlaceholderLike, SliceLike},
relate::Relate,
};

View file

@ -1,29 +1,22 @@
//! Defining `SolverContext` for next-trait-solver.
use hir_def::{AssocItemId, GeneralConstId, TypeAliasId};
use hir_def::{AssocItemId, GeneralConstId};
use rustc_next_trait_solver::delegate::SolverDelegate;
use rustc_type_ir::GenericArgKind;
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::{
InferCtxtLike, Interner, PredicatePolarity, TypeFlags, TypeVisitableExt, UniverseIndex,
inherent::{IntoKind, SliceLike, Span as _, Term as _, Ty as _},
InferCtxtLike, Interner, PredicatePolarity, TypeFlags, TypeVisitableExt,
inherent::{IntoKind, Term as _, Ty as _},
solve::{Certainty, NoSolution},
};
use crate::next_solver::mapping::NextSolverToChalk;
use crate::next_solver::{CanonicalVarKind, ImplIdWrapper};
use crate::{
TraitRefExt,
db::HirDatabase,
next_solver::{
ClauseKind, CoercePredicate, PredicateKind, SubtypePredicate, mapping::ChalkToNextSolver,
util::sizedness_fast_path,
},
use crate::next_solver::{
ClauseKind, CoercePredicate, PredicateKind, SubtypePredicate, util::sizedness_fast_path,
};
use super::{
Canonical, CanonicalVarValues, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs,
ParamEnv, Predicate, SolverDefId, Span, Ty, UnevaluatedConst,
DbInterner, ErrorGuaranteed, GenericArg, SolverDefId, Span,
infer::{DbInternerInferExt, InferCtxt, canonical::instantiate::CanonicalExt},
};
@ -66,7 +59,7 @@ impl<'db> SolverDelegate for SolverContext<'db> {
(SolverContext(infcx), value, vars)
}
fn fresh_var_for_kind_with_span(&self, arg: GenericArg<'db>, span: Span) -> GenericArg<'db> {
fn fresh_var_for_kind_with_span(&self, arg: GenericArg<'db>, _span: Span) -> GenericArg<'db> {
match arg.kind() {
GenericArgKind::Lifetime(_) => self.next_region_var().into(),
GenericArgKind::Type(_) => self.next_ty_var().into(),
@ -76,15 +69,15 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn leak_check(
&self,
max_input_universe: rustc_type_ir::UniverseIndex,
_max_input_universe: rustc_type_ir::UniverseIndex,
) -> Result<(), NoSolution> {
Ok(())
}
fn well_formed_goals(
&self,
param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
arg: <Self::Interner as rustc_type_ir::Interner>::Term,
_param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
_arg: <Self::Interner as rustc_type_ir::Interner>::Term,
) -> Option<
Vec<
rustc_type_ir::solve::Goal<
@ -123,7 +116,7 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn instantiate_canonical_var(
&self,
kind: CanonicalVarKind<'db>,
span: <Self::Interner as Interner>::Span,
_span: <Self::Interner as Interner>::Span,
var_values: &[GenericArg<'db>],
universe_map: impl Fn(rustc_type_ir::UniverseIndex) -> rustc_type_ir::UniverseIndex,
) -> GenericArg<'db> {
@ -132,11 +125,11 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn add_item_bounds_for_hidden_type(
&self,
def_id: <Self::Interner as rustc_type_ir::Interner>::DefId,
args: <Self::Interner as rustc_type_ir::Interner>::GenericArgs,
param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
hidden_ty: <Self::Interner as rustc_type_ir::Interner>::Ty,
goals: &mut Vec<
_def_id: <Self::Interner as rustc_type_ir::Interner>::DefId,
_args: <Self::Interner as rustc_type_ir::Interner>::GenericArgs,
_param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
_hidden_ty: <Self::Interner as rustc_type_ir::Interner>::Ty,
_goals: &mut Vec<
rustc_type_ir::solve::Goal<
Self::Interner,
<Self::Interner as rustc_type_ir::Interner>::Predicate,
@ -148,21 +141,10 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn fetch_eligible_assoc_item(
&self,
goal_trait_ref: rustc_type_ir::TraitRef<Self::Interner>,
_goal_trait_ref: rustc_type_ir::TraitRef<Self::Interner>,
trait_assoc_def_id: SolverDefId,
impl_id: ImplIdWrapper,
) -> Result<Option<SolverDefId>, ErrorGuaranteed> {
let trait_ = self
.0
.interner
.db()
.impl_trait(impl_id.0)
// ImplIds for impls where the trait ref can't be resolved should never reach solver
.expect("invalid impl passed to next-solver")
.skip_binder()
.def_id
.0;
let trait_data = trait_.trait_items(self.0.interner.db());
let impl_items = impl_id.0.impl_items(self.0.interner.db());
let id = match trait_assoc_def_id {
SolverDefId::TypeAliasId(trait_assoc_id) => {
@ -208,16 +190,16 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn is_transmutable(
&self,
dst: <Self::Interner as rustc_type_ir::Interner>::Ty,
src: <Self::Interner as rustc_type_ir::Interner>::Ty,
assume: <Self::Interner as rustc_type_ir::Interner>::Const,
_dst: <Self::Interner as rustc_type_ir::Interner>::Ty,
_src: <Self::Interner as rustc_type_ir::Interner>::Ty,
_assume: <Self::Interner as rustc_type_ir::Interner>::Const,
) -> Result<Certainty, NoSolution> {
unimplemented!()
}
fn evaluate_const(
&self,
param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
_param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
uv: rustc_type_ir::UnevaluatedConst<Self::Interner>,
) -> Option<<Self::Interner as rustc_type_ir::Interner>::Const> {
let c = match uv.def {
@ -236,7 +218,7 @@ impl<'db> SolverDelegate for SolverContext<'db> {
Self::Interner,
<Self::Interner as rustc_type_ir::Interner>::Predicate,
>,
span: <Self::Interner as rustc_type_ir::Interner>::Span,
_span: <Self::Interner as rustc_type_ir::Interner>::Span,
) -> Option<Certainty> {
if let Some(trait_pred) = goal.predicate.as_trait_clause() {
if self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var()
@ -279,8 +261,8 @@ impl<'db> SolverDelegate for SolverContext<'db> {
let pred = goal.predicate.kind();
match pred.no_bound_vars()? {
PredicateKind::Clause(ClauseKind::RegionOutlives(outlives)) => Some(Certainty::Yes),
PredicateKind::Clause(ClauseKind::TypeOutlives(outlives)) => Some(Certainty::Yes),
PredicateKind::Clause(ClauseKind::RegionOutlives(_outlives)) => Some(Certainty::Yes),
PredicateKind::Clause(ClauseKind::TypeOutlives(_outlives)) => Some(Certainty::Yes),
PredicateKind::Subtype(SubtypePredicate { a, b, .. })
| PredicateKind::Coerce(CoercePredicate { a, b }) => {
if self.shallow_resolve(a).is_ty_var() && self.shallow_resolve(b).is_ty_var() {

View file

@ -1,34 +1,30 @@
//! Things related to tys in the next-trait-solver.
use std::iter;
use std::ops::ControlFlow;
use hir_def::{
AdtId, DefWithBodyId, GenericDefId, HasModule, TypeOrConstParamId, TypeParamId,
AdtId, HasModule, TypeParamId,
hir::generics::{TypeOrConstParamData, TypeParamProvenance},
lang_item::LangItem,
};
use hir_def::{TraitId, type_ref::Rawness};
use intern::{Interned, Symbol, sym};
use rustc_abi::{Float, Integer, Size};
use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult};
use rustc_type_ir::{
AliasTyKind, BoundVar, ClosureKind, CollectAndApply, FlagComputation, Flags, FloatTy, FloatVid,
InferTy, IntTy, IntVid, Interner, TyVid, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, WithCachedTypeInfo,
AliasTyKind, BoundVar, ClosureKind, FlagComputation, Flags, FloatTy, FloatVid, InferTy, IntTy,
IntVid, Interner, TyVid, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, UintTy, Upcast, WithCachedTypeInfo,
inherent::{
Abi, AdtDef as _, BoundExistentialPredicates, BoundVarLike, Const as _, GenericArgs as _,
AdtDef as _, BoundExistentialPredicates, BoundVarLike, Const as _, GenericArgs as _,
IntoKind, ParamLike, PlaceholderLike, Safety as _, SliceLike, Ty as _,
},
relate::Relate,
solve::SizedTraitKind,
walk::TypeWalker,
};
use salsa::plumbing::{AsId, FromId};
use smallvec::SmallVec;
use crate::{
FnAbi, ImplTraitId,
ImplTraitId,
db::HirDatabase,
interner::InternedWrapperNoDebug,
next_solver::{
@ -83,7 +79,7 @@ impl<'db> Ty<'db> {
Ty::new(interner, TyKind::Adt(AdtDef::new(adt_id, interner), args))
}
pub fn new_param(interner: DbInterner<'db>, id: TypeParamId, index: u32, name: Symbol) -> Self {
pub fn new_param(interner: DbInterner<'db>, id: TypeParamId, index: u32) -> Self {
Ty::new(interner, TyKind::Param(ParamTy { id, index }))
}
@ -404,7 +400,7 @@ impl<'db> Ty<'db> {
Some(interner.fn_sig(callable).instantiate(interner, args))
}
TyKind::FnPtr(sig, hdr) => Some(sig.with(hdr)),
TyKind::Closure(closure_id, closure_args) => closure_args
TyKind::Closure(_, closure_args) => closure_args
.split_closure_args_untupled()
.closure_sig_as_fn_ptr_ty
.callable_sig(interner),
@ -1222,7 +1218,7 @@ pub struct ParamTy {
impl ParamTy {
pub fn to_ty<'db>(self, interner: DbInterner<'db>) -> Ty<'db> {
Ty::new_param(interner, self.id, self.index, sym::MISSING_NAME.clone())
Ty::new_param(interner, self.id, self.index)
}
}
@ -1269,11 +1265,11 @@ impl<'db> TypeVisitable<DbInterner<'db>> for ErrorGuaranteed {
impl<'db> TypeFoldable<DbInterner<'db>> for ErrorGuaranteed {
fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
self,
folder: &mut F,
_folder: &mut F,
) -> Result<Self, F::Error> {
Ok(self)
}
fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, _folder: &mut F) -> Self {
self
}
}

View file

@ -5,20 +5,19 @@ use std::ops::{self, ControlFlow};
use base_db::Crate;
use hir_def::lang_item::LangItem;
use hir_def::{BlockId, HasModule, ItemContainerId, Lookup};
use hir_def::{BlockId, HasModule};
use intern::sym;
use la_arena::Idx;
use rustc_abi::{Float, HasDataLayout, Integer, IntegerType, Primitive, ReprOptions};
use rustc_type_ir::data_structures::IndexMap;
use rustc_type_ir::inherent::{
AdtDef, Const as _, GenericArg as _, GenericArgs as _, ParamEnv as _, Region as _, SliceLike,
Ty as _,
AdtDef, GenericArg as _, GenericArgs as _, ParamEnv as _, SliceLike, Ty as _,
};
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::{
BoundVar, Canonical, DebruijnIndex, GenericArgKind, INNERMOST, Interner, PredicatePolarity,
TypeFlags, TypeVisitable, TypeVisitableExt,
TypeVisitableExt,
};
use rustc_type_ir::{
ConstKind, CoroutineArgs, FloatTy, IntTy, RegionKind, TypeFolder, TypeSuperFoldable,
@ -29,17 +28,14 @@ use rustc_type_ir::{InferCtxtLike, TypeFoldable};
use crate::lower_nextsolver::{LifetimeElisionKind, TyLoweringContext};
use crate::next_solver::infer::InferCtxt;
use crate::next_solver::{
BoundConst, CanonicalVarKind, FxIndexMap, ParamEnv, Placeholder, PlaceholderConst,
PlaceholderRegion, TypingMode,
BoundConst, FxIndexMap, ParamEnv, Placeholder, PlaceholderConst, PlaceholderRegion,
};
use crate::{
db::HirDatabase,
from_foreign_def_id,
method_resolution::{TraitImpls, TyFingerprint},
};
use super::fold::{BoundVarReplacer, FnMutDelegate};
use super::generics::generics;
use super::{
AliasTerm, AliasTy, Binder, BoundRegion, BoundTy, BoundTyKind, BoundVarKind, BoundVarKinds,
CanonicalVars, Clause, ClauseKind, Clauses, Const, DbInterner, EarlyBinder, GenericArg,
@ -530,7 +526,7 @@ pub(crate) fn mini_canonicalize<'db, T: TypeFoldable<DbInterner<'db>>>(
max_universe: UniverseIndex::from_u32(1),
variables: CanonicalVars::new_from_iter(
context.cx(),
vars.iter().enumerate().map(|(idx, (k, v))| match (*k).kind() {
vars.iter().enumerate().map(|(idx, (k, _v))| match (*k).kind() {
GenericArgKind::Type(ty) => match ty.kind() {
TyKind::Int(..) | TyKind::Uint(..) => rustc_type_ir::CanonicalVarKind::Int,
TyKind::Float(..) => rustc_type_ir::CanonicalVarKind::Float,
@ -617,7 +613,7 @@ impl<'db> TypeFolder<DbInterner<'db>> for MiniCanonicalizer<'_, 'db> {
}
r
}
RegionKind::ReVar(vid) => {
RegionKind::ReVar(_vid) => {
let len = self.vars.len();
let var = *self.vars.entry(r.into()).or_insert(len);
Region::new(
@ -646,7 +642,7 @@ impl<'db> TypeFolder<DbInterner<'db>> for MiniCanonicalizer<'_, 'db> {
}
c
}
ConstKind::Infer(infer) => {
ConstKind::Infer(_infer) => {
let len = self.vars.len();
let var = *self.vars.entry(c.into()).or_insert(len);
Const::new(
@ -666,14 +662,8 @@ pub fn explicit_item_bounds<'db>(
let db = interner.db();
match def_id {
SolverDefId::TypeAliasId(type_alias) => {
let trait_ = match type_alias.lookup(db).container {
ItemContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"),
};
// Lower bounds -- we could/should maybe move this to a separate query in `lower`
let type_alias_data = db.type_alias_signature(type_alias);
let generic_params = generics(db, type_alias.into());
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db);
let mut ctx = TyLoweringContext::new(
db,
@ -805,7 +795,7 @@ pub fn explicit_item_bounds<'db>(
GenericArgs::new_from_iter(interner, [item_ty.into()]),
),
term: match out.kind() {
GenericArgKind::Lifetime(lt) => panic!(),
GenericArgKind::Lifetime(_lt) => panic!(),
GenericArgKind::Type(ty) => Term::Ty(ty),
GenericArgKind::Const(const_) => Term::Const(const_),
},
@ -993,26 +983,6 @@ impl<'db> TypeFolder<DbInterner<'db>> for PlaceholderReplacer<'_, 'db> {
}
}
pub(crate) fn needs_normalization<'db, T: TypeVisitable<DbInterner<'db>>>(
infcx: &InferCtxt<'db>,
value: &T,
) -> bool {
let mut flags = TypeFlags::HAS_ALIAS;
// Opaques are treated as rigid outside of `TypingMode::PostAnalysis`,
// so we can ignore those.
match infcx.typing_mode() {
// FIXME(#132279): We likely want to reveal opaques during post borrowck analysis
TypingMode::Coherence
| TypingMode::Analysis { .. }
| TypingMode::Borrowck { .. }
| TypingMode::PostBorrowckAnalysis { .. } => flags.remove(TypeFlags::HAS_TY_OPAQUE),
TypingMode::PostAnalysis => {}
}
value.has_type_flags(flags)
}
pub fn sizedness_fast_path<'db>(
tcx: DbInterner<'db>,
predicate: Predicate<'db>,

View file

@ -1,7 +1,7 @@
//! A few helper functions for dealing with primitives.
pub use chalk_ir::{FloatTy, IntTy, UintTy};
pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint};
pub use rustc_type_ir::{FloatTy, IntTy, UintTy};
pub fn int_ty_to_string(ty: IntTy) -> &'static str {
match ty {
@ -33,68 +33,3 @@ pub fn float_ty_to_string(ty: FloatTy) -> &'static str {
FloatTy::F128 => "f128",
}
}
pub fn int_ty_to_string_ns(ty: rustc_type_ir::IntTy) -> &'static str {
use rustc_type_ir::IntTy;
match ty {
IntTy::Isize => "isize",
IntTy::I8 => "i8",
IntTy::I16 => "i16",
IntTy::I32 => "i32",
IntTy::I64 => "i64",
IntTy::I128 => "i128",
}
}
pub fn uint_ty_to_string_ns(ty: rustc_type_ir::UintTy) -> &'static str {
use rustc_type_ir::UintTy;
match ty {
UintTy::Usize => "usize",
UintTy::U8 => "u8",
UintTy::U16 => "u16",
UintTy::U32 => "u32",
UintTy::U64 => "u64",
UintTy::U128 => "u128",
}
}
pub fn float_ty_to_string_ns(ty: rustc_type_ir::FloatTy) -> &'static str {
use rustc_type_ir::FloatTy;
match ty {
FloatTy::F16 => "f16",
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
FloatTy::F128 => "f128",
}
}
pub(super) fn int_ty_from_builtin(t: BuiltinInt) -> IntTy {
match t {
BuiltinInt::Isize => IntTy::Isize,
BuiltinInt::I8 => IntTy::I8,
BuiltinInt::I16 => IntTy::I16,
BuiltinInt::I32 => IntTy::I32,
BuiltinInt::I64 => IntTy::I64,
BuiltinInt::I128 => IntTy::I128,
}
}
pub(super) fn uint_ty_from_builtin(t: BuiltinUint) -> UintTy {
match t {
BuiltinUint::Usize => UintTy::Usize,
BuiltinUint::U8 => UintTy::U8,
BuiltinUint::U16 => UintTy::U16,
BuiltinUint::U32 => UintTy::U32,
BuiltinUint::U64 => UintTy::U64,
BuiltinUint::U128 => UintTy::U128,
}
}
pub(super) fn float_ty_from_builtin(t: BuiltinFloat) -> FloatTy {
match t {
BuiltinFloat::F16 => FloatTy::F16,
BuiltinFloat::F32 => FloatTy::F32,
BuiltinFloat::F64 => FloatTy::F64,
BuiltinFloat::F128 => FloatTy::F128,
}
}

View file

@ -1803,7 +1803,7 @@ impl Adt {
let env = db.trait_environment(self.into());
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
let adt_id = AdtId::from(self);
let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, _, id, _| {
let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, id, _| {
GenericArg::error_from_id(interner, id)
});
db.layout_of_adt(adt_id, args, env)
@ -4184,8 +4184,7 @@ impl TypeParam {
let resolver = self.id.parent().resolver(db);
let interner = DbInterner::new_with(db, None, None);
let index = hir_ty::param_idx(db, self.id.into()).unwrap();
let name = self.name(db).symbol().clone();
let ty = Ty::new_param(interner, self.id, index as u32, name);
let ty = Ty::new_param(interner, self.id, index as u32);
Type::new_with_resolver_inner(db, &resolver, ty)
}
@ -6438,7 +6437,7 @@ fn generic_args_from_tys<'db>(
args: impl IntoIterator<Item = Ty<'db>>,
) -> GenericArgs<'db> {
let mut args = args.into_iter();
GenericArgs::for_item(interner, def_id, |_, _, id, _| {
GenericArgs::for_item(interner, def_id, |_, id, _| {
if matches!(id, GenericParamId::TypeParamId(_))
&& let Some(arg) = args.next()
{

View file

@ -1657,14 +1657,11 @@ impl<'db> SemanticsImpl<'db> {
) -> Option<Function> {
let interner = DbInterner::new_with(self.db, None, None);
let mut subst = subst.into_iter();
let substs = hir_ty::next_solver::GenericArgs::for_item(
interner,
trait_.id.into(),
|_, _, id, _| {
let substs =
hir_ty::next_solver::GenericArgs::for_item(interner, trait_.id.into(), |_, id, _| {
assert!(matches!(id, hir_def::GenericParamId::TypeParamId(_)), "expected a type");
subst.next().expect("too few subst").ty.into()
},
);
});
assert!(subst.next().is_none(), "too many subst");
Some(self.db.lookup_impl_method(env.env, func.into(), substs).0.into())
}