pub trait QueryDatabase: TypeDatabase + TypeResolver {
Show 39 methods
// Required methods
fn as_type_database(&self) -> &dyn TypeDatabase;
fn resolve_property_access(
&self,
object_type: TypeId,
prop_name: &str,
) -> PropertyAccessResult;
fn resolve_property_access_with_options(
&self,
object_type: TypeId,
prop_name: &str,
no_unchecked_indexed_access: bool,
) -> PropertyAccessResult;
fn get_index_signatures(&self, type_id: TypeId) -> IndexInfo;
fn is_nullish_type(&self, type_id: TypeId) -> bool;
fn remove_nullish(&self, type_id: TypeId) -> TypeId;
fn canonical_id(&self, type_id: TypeId) -> TypeId;
fn is_assignable_to_with_flags(
&self,
source: TypeId,
target: TypeId,
flags: u16,
) -> bool;
fn get_type_param_variance(&self, def_id: DefId) -> Option<Arc<[Variance]>>;
// Provided methods
fn factory(&self) -> TypeFactory<'_> { ... }
fn register_array_base_type(
&self,
_type_id: TypeId,
_type_params: Vec<TypeParamInfo>,
) { ... }
fn register_boxed_type(&self, _kind: IntrinsicKind, _type_id: TypeId) { ... }
fn evaluate_conditional(&self, cond: &ConditionalType) -> TypeId { ... }
fn evaluate_index_access(
&self,
object_type: TypeId,
index_type: TypeId,
) -> TypeId { ... }
fn evaluate_index_access_with_options(
&self,
object_type: TypeId,
index_type: TypeId,
no_unchecked_indexed_access: bool,
) -> TypeId { ... }
fn evaluate_type(&self, type_id: TypeId) -> TypeId { ... }
fn evaluate_type_with_options(
&self,
type_id: TypeId,
no_unchecked_indexed_access: bool,
) -> TypeId { ... }
fn evaluate_mapped(&self, mapped: &MappedType) -> TypeId { ... }
fn lookup_application_eval_cache(
&self,
_def_id: DefId,
_args: &[TypeId],
_no_unchecked_indexed_access: bool,
) -> Option<TypeId> { ... }
fn insert_application_eval_cache(
&self,
_def_id: DefId,
_args: &[TypeId],
_no_unchecked_indexed_access: bool,
_result: TypeId,
) { ... }
fn evaluate_keyof(&self, operand: TypeId) -> TypeId { ... }
fn narrow(&self, type_id: TypeId, narrower: TypeId) -> TypeId
where Self: Sized { ... }
fn property_access_type(
&self,
object_type: TypeId,
prop_name: &str,
) -> PropertyAccessResult { ... }
fn no_unchecked_indexed_access(&self) -> bool { ... }
fn set_no_unchecked_indexed_access(&self, _enabled: bool) { ... }
fn contextual_property_type(
&self,
expected: TypeId,
prop_name: &str,
) -> Option<TypeId> { ... }
fn is_property_readonly(&self, object_type: TypeId, prop_name: &str) -> bool { ... }
fn is_readonly_index_signature(
&self,
object_type: TypeId,
wants_string: bool,
wants_number: bool,
) -> bool { ... }
fn resolve_element_access(
&self,
object_type: TypeId,
index_type: TypeId,
literal_index: Option<usize>,
) -> ElementAccessResult { ... }
fn resolve_element_access_type(
&self,
object_type: TypeId,
index_type: TypeId,
literal_index: Option<usize>,
) -> TypeId { ... }
fn collect_object_spread_properties(
&self,
spread_type: TypeId,
) -> Vec<PropertyInfo> { ... }
fn is_subtype_of(&self, source: TypeId, target: TypeId) -> bool { ... }
fn is_subtype_of_with_flags(
&self,
source: TypeId,
target: TypeId,
flags: u16,
) -> bool { ... }
fn is_assignable_to(&self, source: TypeId, target: TypeId) -> bool { ... }
fn lookup_subtype_cache(&self, _key: RelationCacheKey) -> Option<bool> { ... }
fn insert_subtype_cache(&self, _key: RelationCacheKey, _result: bool) { ... }
fn lookup_assignability_cache(&self, _key: RelationCacheKey) -> Option<bool> { ... }
fn insert_assignability_cache(&self, _key: RelationCacheKey, _result: bool) { ... }
fn new_inference_context(&self) -> InferenceContext<'_> { ... }
}Expand description
Query layer for higher-level solver operations.
This is the incremental boundary where caching and (future) salsa hooks live.
Inherits from TypeResolver to enable Lazy/Ref type resolution through evaluate_type().
Required Methods§
Sourcefn as_type_database(&self) -> &dyn TypeDatabase
fn as_type_database(&self) -> &dyn TypeDatabase
Expose the underlying TypeDatabase view for legacy entry points.
fn resolve_property_access( &self, object_type: TypeId, prop_name: &str, ) -> PropertyAccessResult
fn resolve_property_access_with_options( &self, object_type: TypeId, prop_name: &str, no_unchecked_indexed_access: bool, ) -> PropertyAccessResult
Sourcefn get_index_signatures(&self, type_id: TypeId) -> IndexInfo
fn get_index_signatures(&self, type_id: TypeId) -> IndexInfo
Get index signatures for a type
Sourcefn is_nullish_type(&self, type_id: TypeId) -> bool
fn is_nullish_type(&self, type_id: TypeId) -> bool
Check if a type contains null or undefined
Sourcefn remove_nullish(&self, type_id: TypeId) -> TypeId
fn remove_nullish(&self, type_id: TypeId) -> TypeId
Remove null and undefined from a type
Sourcefn canonical_id(&self, type_id: TypeId) -> TypeId
fn canonical_id(&self, type_id: TypeId) -> TypeId
Get the canonical TypeId for a type, achieving O(1) structural identity checks.
This memoizes the Canonicalizer output so that structurally identical types
(e.g., type A = Box<Box<string>> and type B = Box<Box<string>>) return
the same canonical TypeId.
The implementation must:
- Use a fresh Canonicalizer with empty stacks (for absolute De Bruijn indices)
- Only expand
TypeAlias(DefKind::TypeAlias), preserving nominal types - Cache the result for O(1) subsequent lookups
Task #49: Global Canonical Mapping
Provided Methods§
Sourcefn factory(&self) -> TypeFactory<'_>
fn factory(&self) -> TypeFactory<'_>
Expose the checked construction surface for type constructors.
Sourcefn register_array_base_type(
&self,
_type_id: TypeId,
_type_params: Vec<TypeParamInfo>,
)
fn register_array_base_type( &self, _type_id: TypeId, _type_params: Vec<TypeParamInfo>, )
Register the canonical Array<T> base type used by property access resolution.
Some call paths resolve properties through a TypeInterner-backed database,
while others use a TypeEnvironment-backed resolver. Implementations should
store this in whichever backing stores they use so T[] methods/properties
(e.g. push, length) resolve consistently.
Sourcefn register_boxed_type(&self, _kind: IntrinsicKind, _type_id: TypeId)
fn register_boxed_type(&self, _kind: IntrinsicKind, _type_id: TypeId)
Register a boxed interface type for a primitive intrinsic kind.
Similar to register_array_base_type, this ensures that property access
resolution can find the correct interface type (e.g., String, Number) for
primitive types, regardless of which database backend is used.
fn evaluate_conditional(&self, cond: &ConditionalType) -> TypeId
fn evaluate_index_access( &self, object_type: TypeId, index_type: TypeId, ) -> TypeId
fn evaluate_index_access_with_options( &self, object_type: TypeId, index_type: TypeId, no_unchecked_indexed_access: bool, ) -> TypeId
fn evaluate_type(&self, type_id: TypeId) -> TypeId
fn evaluate_type_with_options( &self, type_id: TypeId, no_unchecked_indexed_access: bool, ) -> TypeId
fn evaluate_mapped(&self, mapped: &MappedType) -> TypeId
Sourcefn lookup_application_eval_cache(
&self,
_def_id: DefId,
_args: &[TypeId],
_no_unchecked_indexed_access: bool,
) -> Option<TypeId>
fn lookup_application_eval_cache( &self, _def_id: DefId, _args: &[TypeId], _no_unchecked_indexed_access: bool, ) -> Option<TypeId>
Look up a shared cache entry for evaluated generic applications.
Sourcefn insert_application_eval_cache(
&self,
_def_id: DefId,
_args: &[TypeId],
_no_unchecked_indexed_access: bool,
_result: TypeId,
)
fn insert_application_eval_cache( &self, _def_id: DefId, _args: &[TypeId], _no_unchecked_indexed_access: bool, _result: TypeId, )
Store an evaluated generic application result in the shared cache.
fn evaluate_keyof(&self, operand: TypeId) -> TypeId
fn narrow(&self, type_id: TypeId, narrower: TypeId) -> TypeIdwhere
Self: Sized,
fn property_access_type( &self, object_type: TypeId, prop_name: &str, ) -> PropertyAccessResult
fn no_unchecked_indexed_access(&self) -> bool
fn set_no_unchecked_indexed_access(&self, _enabled: bool)
fn contextual_property_type( &self, expected: TypeId, prop_name: &str, ) -> Option<TypeId>
fn is_property_readonly(&self, object_type: TypeId, prop_name: &str) -> bool
fn is_readonly_index_signature( &self, object_type: TypeId, wants_string: bool, wants_number: bool, ) -> bool
Sourcefn resolve_element_access(
&self,
object_type: TypeId,
index_type: TypeId,
literal_index: Option<usize>,
) -> ElementAccessResult
fn resolve_element_access( &self, object_type: TypeId, index_type: TypeId, literal_index: Option<usize>, ) -> ElementAccessResult
Resolve element access (array/tuple indexing) with detailed error reporting
Sourcefn resolve_element_access_type(
&self,
object_type: TypeId,
index_type: TypeId,
literal_index: Option<usize>,
) -> TypeId
fn resolve_element_access_type( &self, object_type: TypeId, index_type: TypeId, literal_index: Option<usize>, ) -> TypeId
Resolve element access type with cache-friendly error normalization.
Sourcefn collect_object_spread_properties(
&self,
spread_type: TypeId,
) -> Vec<PropertyInfo>
fn collect_object_spread_properties( &self, spread_type: TypeId, ) -> Vec<PropertyInfo>
Collect properties that can be spread into object literals.
Sourcefn is_subtype_of(&self, source: TypeId, target: TypeId) -> bool
fn is_subtype_of(&self, source: TypeId, target: TypeId) -> bool
Subtype check with compiler flags.
The flags parameter is a packed u16 bitmask matching RelationCacheKey.flags:
- bit 0:
strict_null_checks - bit 1:
strict_function_types - bit 2:
exact_optional_property_types - bit 3:
no_unchecked_indexed_access - bit 4:
disable_method_bivariance - bit 5:
allow_void_return - bit 6:
allow_bivariant_rest - bit 7:
allow_bivariant_param_count
Sourcefn is_subtype_of_with_flags(
&self,
source: TypeId,
target: TypeId,
flags: u16,
) -> bool
fn is_subtype_of_with_flags( &self, source: TypeId, target: TypeId, flags: u16, ) -> bool
Subtype check with explicit compiler flags.
The flags parameter is a packed u16 bitmask matching RelationCacheKey.flags.
Sourcefn is_assignable_to(&self, source: TypeId, target: TypeId) -> bool
fn is_assignable_to(&self, source: TypeId, target: TypeId) -> bool
TypeScript assignability check with full compatibility rules (The Lawyer).
This is distinct from is_subtype_of:
is_subtype_of= Strict structural subtyping (The Judge) - for internal solver useis_assignable_to= Loose with TS rules (The Lawyer) - for Checker diagnostics
The Lawyer handles:
- Any type propagation (any is assignable to/from everything)
- Legacy null/undefined assignability (without strictNullChecks)
- Weak type detection (excess property checking)
- Empty object accepts any non-nullish value
- Function bivariance (when not in strictFunctionTypes mode)
Uses separate cache from is_subtype_of to prevent cache poisoning.
Sourcefn lookup_subtype_cache(&self, _key: RelationCacheKey) -> Option<bool>
fn lookup_subtype_cache(&self, _key: RelationCacheKey) -> Option<bool>
Look up a cached subtype result for the given key.
Returns None if the result is not cached.
Default implementation returns None (no caching).
Sourcefn insert_subtype_cache(&self, _key: RelationCacheKey, _result: bool)
fn insert_subtype_cache(&self, _key: RelationCacheKey, _result: bool)
Cache a subtype result for the given key. Default implementation is a no-op.
Sourcefn lookup_assignability_cache(&self, _key: RelationCacheKey) -> Option<bool>
fn lookup_assignability_cache(&self, _key: RelationCacheKey) -> Option<bool>
Look up a cached assignability result for the given key.
Returns None if the result is not cached.
Default implementation returns None (no caching).
Sourcefn insert_assignability_cache(&self, _key: RelationCacheKey, _result: bool)
fn insert_assignability_cache(&self, _key: RelationCacheKey, _result: bool)
Cache an assignability result for the given key. Default implementation is a no-op.