Inner implementation of [`resolve_target_classes_expr`] without chain caching. The outer function handles cache lookup/store.
(
expr: &SubjectExpr,
access_kind: AccessKind,
ctx: &ResolutionCtx<'_>,
)
| 417 | /// Inner implementation of [`resolve_target_classes_expr`] without |
| 418 | /// chain caching. The outer function handles cache lookup/store. |
| 419 | fn resolve_target_classes_expr_inner( |
| 420 | expr: &SubjectExpr, |
| 421 | access_kind: AccessKind, |
| 422 | ctx: &ResolutionCtx<'_>, |
| 423 | ) -> Vec<ResolvedType> { |
| 424 | thread_local! { |
| 425 | static RESOLVE_DEPTH: std::cell::Cell<u32> = const { std::cell::Cell::new(0) }; |
| 426 | } |
| 427 | let depth = RESOLVE_DEPTH.with(|d| { |
| 428 | let v = d.get() + 1; |
| 429 | d.set(v); |
| 430 | v |
| 431 | }); |
| 432 | // Maximum nesting depth for `resolve_target_classes_expr_inner`. |
| 433 | // Breaks infinite recursion between subject resolution, call-return |
| 434 | // resolution, and variable resolution that can occur on files with |
| 435 | // deeply intertwined class hierarchies and virtual members. |
| 436 | const MAX_RESOLVE_TARGET_DEPTH: u32 = 60; |
| 437 | if depth > MAX_RESOLVE_TARGET_DEPTH { |
| 438 | RESOLVE_DEPTH.with(|d| d.set(depth - 1)); |
| 439 | return vec![]; |
| 440 | } |
| 441 | let result = resolve_target_classes_expr_inner_impl(expr, access_kind, ctx); |
| 442 | RESOLVE_DEPTH.with(|d| d.set(depth - 1)); |
| 443 | result |
| 444 | } |
| 445 | |
| 446 | fn resolve_target_classes_expr_inner_impl( |
| 447 | expr: &SubjectExpr, |
no test coverage detected