Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/consts.rs')
| -rw-r--r-- | crates/hir-ty/src/next_solver/consts.rs | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/crates/hir-ty/src/next_solver/consts.rs b/crates/hir-ty/src/next_solver/consts.rs index 23789b06e8..0b3582051b 100644 --- a/crates/hir-ty/src/next_solver/consts.rs +++ b/crates/hir-ty/src/next_solver/consts.rs @@ -4,16 +4,19 @@ use std::hash::Hash; use hir_def::{ConstParamId, TypeOrConstParamId}; use intern::{Interned, Symbol}; -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; +use rustc_ast_ir::{try_visit, visit::VisitorResult}; use rustc_type_ir::{ BoundVar, FlagComputation, Flags, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, - TypeVisitable, WithCachedTypeInfo, - inherent::{IntoKind, PlaceholderLike}, + TypeVisitable, TypeVisitableExt, WithCachedTypeInfo, + inherent::{IntoKind, ParamEnv as _, PlaceholderLike, SliceLike}, relate::Relate, }; -use crate::{ConstScalar, MemoryMap, interner::InternedWrapperNoDebug}; +use crate::{ + ConstScalar, MemoryMap, + interner::InternedWrapperNoDebug, + next_solver::{ClauseKind, ParamEnv}, +}; use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder, Ty}; @@ -96,6 +99,40 @@ impl std::fmt::Debug for ParamConst { } } +impl ParamConst { + pub fn find_const_ty_from_env<'db>(self, env: ParamEnv<'db>) -> Ty<'db> { + let mut candidates = env.caller_bounds().iter().filter_map(|clause| { + // `ConstArgHasType` are never desugared to be higher ranked. + match clause.kind().skip_binder() { + ClauseKind::ConstArgHasType(param_ct, ty) => { + assert!(!(param_ct, ty).has_escaping_bound_vars()); + + match param_ct.kind() { + ConstKind::Param(param_ct) if param_ct.index == self.index => Some(ty), + _ => None, + } + } + _ => None, + } + }); + + // N.B. it may be tempting to fix ICEs by making this function return + // `Option<Ty<'db>>` instead of `Ty<'db>`; however, this is generally + // considered to be a bandaid solution, since it hides more important + // underlying issues with how we construct generics and predicates of + // items. It's advised to fix the underlying issue rather than trying + // to modify this function. + let ty = candidates.next().unwrap_or_else(|| { + panic!("cannot find `{self:?}` in param-env: {env:#?}"); + }); + assert!( + candidates.next().is_none(), + "did not expect duplicate `ConstParamHasTy` for `{self:?}` in param-env: {env:#?}" + ); + ty + } +} + /// A type-level constant value. /// /// Represents a typed, fully evaluated constant. |