Skip to main content

hir/
source_analyzer.rs

1//! Lookup hir elements using positions in the source code. This is a lossy
2//! transformation: in general, a single source might correspond to several
3//! modules, functions, etc, due to macros, cfgs and `#[path=]` attributes on
4//! modules.
5//!
6//! So, this modules should not be used during hir construction, it exists
7//! purely for "IDE needs".
8use std::{
9    cell::OnceCell,
10    iter::{self, once},
11};
12
13use either::Either;
14use hir_def::{
15    AdtId, AssocItemId, CallableDefId, ConstId, DefWithBodyId, ExpressionStoreOwnerId, FieldId,
16    FunctionId, GenericDefId, HasModule, LocalFieldId, LoweringMode, ModuleDefId, StructId,
17    VariantId,
18    expr_store::{
19        Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, HygieneId,
20        lower::{ExprCollector, lower_generic_params},
21        path::Path,
22        scope::{ExprScopes, ScopeId},
23    },
24    hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat, PatId, generics::GenericParams},
25    lang_item::LangItems,
26    nameres::MacroSubNs,
27    resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs, resolver_for_scope},
28    type_ref::{Mutability, TypeRefId},
29    visibility::Visibility,
30};
31use hir_expand::{
32    HirFileId, InFile,
33    mod_path::{ModPath, PathKind, path},
34    name::{AsName, Name},
35};
36use hir_ty::{
37    Adjustment, InferBodyId, InferenceResult, LifetimeElisionKind, LifetimeLoweringMode,
38    ParamEnvAndCrate, TyLoweringContext, TyLoweringInferVarsCtx,
39    diagnostics::{
40        InsideUnsafeBlock, record_literal_missing_fields, record_pattern_missing_fields,
41        unsafe_operations,
42    },
43    lang_items::lang_items_for_bin_op,
44    method_resolution::{self, CandidateId},
45    next_solver::{
46        AliasTy, DbInterner, DefaultAny, EarlyBinder, ErrorGuaranteed, GenericArgs, ParamEnv,
47        Region, Ty, TyKind, TypingMode, infer::DbInternerInferExt,
48    },
49    traits::{WherePredicateEvaluation, structurally_normalize_ty, where_predicate_must_hold},
50};
51use intern::sym;
52use itertools::Itertools;
53use rustc_hash::FxHashSet;
54use rustc_type_ir::{
55    AliasTyKind,
56    inherent::{IntoKind, Ty as _},
57};
58use smallvec::SmallVec;
59use stdx::never;
60use syntax::{
61    SyntaxKind, SyntaxNode, TextRange, TextSize,
62    ast::{self, AstNode, RangeItem, RangeOp},
63};
64
65use crate::{
66    Adt, AnyFunctionId, AssocItem, BindingMode, BuiltinAttr, BuiltinType, Callable, Const,
67    DeriveHelper, EnumVariant, Field, Function, GenericSubstitution, Local, Macro, ModuleDef,
68    PredicateEvaluationResult, SemanticsImpl, Static, Struct, ToolModule, Trait, TupleField, Type,
69    TypeAlias, TypeOwnerId,
70    db::HirDatabase,
71    semantics::{PathResolution, PathResolutionPerNs},
72};
73
74/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
75/// original source files. It should not be used inside the HIR itself.
76#[derive(Debug)]
77pub(crate) struct SourceAnalyzer<'db> {
78    pub(crate) file_id: HirFileId,
79    pub(crate) resolver: Resolver<'db>,
80    pub(crate) body_or_sig: Option<BodyOrSig<'db>>,
81    pub(crate) type_owner: TypeOwnerId<'db>,
82    pub(crate) infer_body: Option<InferBodyId<'db>>,
83}
84
85#[derive(Debug)]
86pub(crate) enum BodyOrSig<'db> {
87    Body {
88        def: DefWithBodyId,
89        body: &'db Body,
90        source_map: &'db BodySourceMap,
91        infer: Option<&'db InferenceResult<'db>>,
92    },
93    VariantFields {
94        def: VariantId,
95        store: &'db ExpressionStore,
96        source_map: &'db ExpressionStoreSourceMap,
97        infer: Option<&'db InferenceResult<'db>>,
98    },
99    Sig {
100        def: GenericDefId,
101        store: &'db ExpressionStore,
102        source_map: &'db ExpressionStoreSourceMap,
103        infer: Option<&'db InferenceResult<'db>>,
104        #[expect(dead_code)]
105        generics: &'db GenericParams,
106    },
107}
108
109impl<'db> SourceAnalyzer<'db> {
110    pub(crate) fn new_for_body(
111        db: &'db dyn HirDatabase,
112        def: DefWithBodyId,
113        node: InFile<&SyntaxNode>,
114        offset: Option<TextSize>,
115    ) -> SourceAnalyzer<'db> {
116        Self::new_for_body_(db, def, node, offset, Some(InferenceResult::of(db, def)))
117    }
118
119    pub(crate) fn new_for_body_no_infer(
120        db: &'db dyn HirDatabase,
121        def: DefWithBodyId,
122        node: InFile<&SyntaxNode>,
123        offset: Option<TextSize>,
124    ) -> SourceAnalyzer<'db> {
125        Self::new_for_body_(db, def, node, offset, None)
126    }
127
128    pub(crate) fn new_for_body_(
129        db: &'db dyn HirDatabase,
130        def: DefWithBodyId,
131        node @ InFile { file_id, .. }: InFile<&SyntaxNode>,
132        offset: Option<TextSize>,
133        infer: Option<&'db InferenceResult<'db>>,
134    ) -> SourceAnalyzer<'db> {
135        let (body, source_map) = Body::with_source_map(db, def);
136        let scopes = ExprScopes::of(db, def);
137        let scope = match offset {
138            None => scope_for(db, scopes, source_map, node),
139            Some(offset) => {
140                debug_assert!(
141                    node.text_range().contains_inclusive(offset),
142                    "{:?} not in {:?}",
143                    offset,
144                    node.text_range()
145                );
146                scope_for_offset(db, scopes, source_map, node.file_id, offset)
147            }
148        };
149        let (scope, _expr) = scope.unzip();
150        let resolver = resolver_for_scope(db, def, scope);
151        SourceAnalyzer {
152            resolver,
153            body_or_sig: Some(BodyOrSig::Body { def, body, source_map, infer }),
154            file_id,
155            type_owner: def.generic_def(db).into(),
156            infer_body: Some(def.into()),
157        }
158    }
159
160    pub(crate) fn new_generic_def(
161        db: &'db dyn HirDatabase,
162        sema: &SemanticsImpl<'db>,
163        def: GenericDefId,
164        node: InFile<&SyntaxNode>,
165        offset: Option<TextSize>,
166    ) -> SourceAnalyzer<'db> {
167        Self::new_generic_def_(db, sema, def, node, offset, true)
168    }
169
170    pub(crate) fn new_generic_def_no_infer(
171        db: &'db dyn HirDatabase,
172        sema: &SemanticsImpl<'db>,
173        def: GenericDefId,
174        node: InFile<&SyntaxNode>,
175        offset: Option<TextSize>,
176    ) -> SourceAnalyzer<'db> {
177        Self::new_generic_def_(db, sema, def, node, offset, false)
178    }
179
180    pub(crate) fn new_generic_def_(
181        db: &'db dyn HirDatabase,
182        sema: &SemanticsImpl<'db>,
183        def: GenericDefId,
184        node @ InFile { file_id, .. }: InFile<&SyntaxNode>,
185        offset: Option<TextSize>,
186        infer: bool,
187    ) -> SourceAnalyzer<'db> {
188        let (generics, store, source_map) = GenericParams::with_source_map(db, def);
189        let scopes = ExprScopes::of(db, def);
190        let scope = match offset {
191            None => scope_for(db, scopes, source_map, node),
192            Some(offset) => {
193                debug_assert!(
194                    node.text_range().contains_inclusive(offset),
195                    "{:?} not in {:?}",
196                    offset,
197                    node.text_range()
198                );
199                scope_for_offset(db, scopes, source_map, node.file_id, offset)
200            }
201        };
202        let (scope, expr) = scope.unzip();
203        let resolver = resolver_for_scope(db, def, scope);
204        let infer_body = expr.and_then(|expr| {
205            sema.infer_body_for_expr_or_pat(
206                ExpressionStoreOwnerId::Signature(def),
207                store,
208                expr.into(),
209            )
210        });
211        let infer = if infer && let Some(infer_body) = infer_body {
212            Some(InferenceResult::of(db, infer_body))
213        } else {
214            None
215        };
216        SourceAnalyzer {
217            resolver,
218            body_or_sig: Some(BodyOrSig::Sig { def, store, source_map, generics, infer }),
219            file_id,
220            type_owner: def.into(),
221            infer_body,
222        }
223    }
224
225    pub(crate) fn new_variant_body(
226        db: &'db dyn HirDatabase,
227        sema: &SemanticsImpl<'db>,
228        def: VariantId,
229        node @ InFile { file_id, .. }: InFile<&SyntaxNode>,
230        offset: Option<TextSize>,
231        infer: bool,
232    ) -> SourceAnalyzer<'db> {
233        let (fields, source_map) = def.fields_with_source_map(db);
234        let scopes = ExprScopes::of(db, def);
235        let scope = match offset {
236            None => scope_for(db, scopes, source_map, node),
237            Some(offset) => {
238                debug_assert!(
239                    node.text_range().contains_inclusive(offset),
240                    "{:?} not in {:?}",
241                    offset,
242                    node.text_range()
243                );
244                scope_for_offset(db, scopes, source_map, node.file_id, offset)
245            }
246        };
247        let (scope, expr) = scope.unzip();
248        let resolver = resolver_for_scope(db, def, scope);
249        let infer_body = expr.and_then(|expr| {
250            sema.infer_body_for_expr_or_pat(
251                ExpressionStoreOwnerId::VariantFields(def),
252                &fields.store,
253                expr.into(),
254            )
255        });
256        let infer = if infer && let Some(infer_body) = infer_body {
257            Some(InferenceResult::of(db, infer_body))
258        } else {
259            None
260        };
261        SourceAnalyzer {
262            resolver,
263            body_or_sig: Some(BodyOrSig::VariantFields {
264                def,
265                store: &fields.store,
266                source_map,
267                infer,
268            }),
269            file_id,
270            type_owner: GenericDefId::from(def.adt_id(db)).into(),
271            infer_body,
272        }
273    }
274
275    pub(crate) fn new_for_resolver(
276        resolver: Resolver<'db>,
277        node: InFile<&SyntaxNode>,
278    ) -> SourceAnalyzer<'db> {
279        SourceAnalyzer {
280            type_owner: resolver
281                .generic_def()
282                .map(Into::into)
283                .unwrap_or_else(|| TypeOwnerId::NoParams(resolver.krate())),
284            resolver,
285            body_or_sig: None,
286            file_id: node.file_id,
287            infer_body: None,
288        }
289    }
290
291    fn owner(&self) -> Option<ExpressionStoreOwnerId> {
292        self.body_or_sig.as_ref().map(|it| match *it {
293            BodyOrSig::VariantFields { def, .. } => def.into(),
294            BodyOrSig::Sig { def, .. } => def.into(),
295            BodyOrSig::Body { def, .. } => def.into(),
296        })
297    }
298
299    fn infer(&self) -> Option<&'db InferenceResult<'db>> {
300        self.body_or_sig.as_ref().and_then(|it| match *it {
301            BodyOrSig::VariantFields { infer, .. }
302            | BodyOrSig::Sig { infer, .. }
303            | BodyOrSig::Body { infer, .. } => infer,
304        })
305    }
306
307    pub(crate) fn ty(&self, ty: Ty<'db>) -> Type<'db> {
308        Type { owner: self.type_owner, ty: EarlyBinder::bind(ty) }
309    }
310
311    pub(crate) fn def(
312        &self,
313    ) -> Option<(
314        ExpressionStoreOwnerId,
315        &'db ExpressionStore,
316        &'db ExpressionStoreSourceMap,
317        Option<&'db InferenceResult<'db>>,
318    )> {
319        self.body_or_sig.as_ref().map(|it| match *it {
320            BodyOrSig::VariantFields { def, store, source_map, infer, .. } => {
321                (def.into(), store, source_map, infer)
322            }
323            BodyOrSig::Sig { def, store, source_map, infer, .. } => {
324                (def.into(), store, source_map, infer)
325            }
326            BodyOrSig::Body { def, body, source_map, infer, .. } => {
327                (def.into(), &body.store, &source_map.store, infer)
328            }
329        })
330    }
331
332    pub(crate) fn store(&self) -> Option<&'db ExpressionStore> {
333        self.body_or_sig.as_ref().map(|it| match *it {
334            BodyOrSig::Sig { store, .. } => store,
335            BodyOrSig::VariantFields { store, .. } => store,
336            BodyOrSig::Body { body, .. } => &body.store,
337        })
338    }
339
340    pub(crate) fn store_sm(&self) -> Option<&'db ExpressionStoreSourceMap> {
341        self.body_or_sig.as_ref().map(|it| match *it {
342            BodyOrSig::Sig { source_map, .. } => source_map,
343            BodyOrSig::VariantFields { source_map, .. } => source_map,
344            BodyOrSig::Body { source_map, .. } => &source_map.store,
345        })
346    }
347
348    fn param_and<'a>(&self, param_env: ParamEnv<'a>) -> ParamEnvAndCrate<'a> {
349        ParamEnvAndCrate { param_env, krate: self.resolver.krate() }
350    }
351
352    fn trait_environment(&self, db: &'db dyn HirDatabase) -> ParamEnvAndCrate<'db> {
353        self.param_and(self.body_or_sig.as_ref().map_or_else(
354            || ParamEnv::empty(DbInterner::new_no_crate(db)),
355            |body_or_sig| {
356                let def = match *body_or_sig {
357                    BodyOrSig::Body { def, .. } => def.generic_def(db),
358                    BodyOrSig::VariantFields { def, .. } => match def {
359                        VariantId::EnumVariantId(def) => def.loc(db).parent.into(),
360                        VariantId::StructId(def) => def.into(),
361                        VariantId::UnionId(def) => def.into(),
362                    },
363                    BodyOrSig::Sig { def, .. } => def,
364                };
365                db.trait_environment(def)
366            },
367        ))
368    }
369
370    pub(crate) fn evaluate_where_clause(
371        &self,
372        db: &'db dyn HirDatabase,
373        where_clause: ast::WhereClause,
374    ) -> PredicateEvaluationResult {
375        let Some(owner) = self.owner() else {
376            // FIXME
377            return PredicateEvaluationResult::unsupported(
378                "predicate evaluation is only supported inside an item",
379            );
380        };
381        let generic_def = owner.generic_def(db);
382        let module = generic_def.module(db);
383        let (store, params, _) = lower_generic_params(
384            db,
385            module,
386            generic_def,
387            self.file_id,
388            None,
389            Some(where_clause),
390            LoweringMode::Ide,
391        );
392        let predicates = params.where_predicates();
393        if predicates.is_empty() {
394            return PredicateEvaluationResult::holds("predicate does not impose any obligations");
395        }
396
397        let env = self.trait_environment(db);
398        for predicate in predicates {
399            match where_predicate_must_hold(
400                db,
401                &self.resolver,
402                &store,
403                owner,
404                generic_def,
405                env,
406                predicate,
407            ) {
408                WherePredicateEvaluation::Holds | WherePredicateEvaluation::NoObligations => {}
409                WherePredicateEvaluation::HasErrors => {
410                    return PredicateEvaluationResult::invalid(
411                        "predicate contains unresolved names or invalid type syntax",
412                    );
413                }
414                WherePredicateEvaluation::NotProven => {
415                    return PredicateEvaluationResult::not_proven("predicate is not known to hold");
416                }
417            }
418        }
419
420        PredicateEvaluationResult::holds("predicate holds")
421    }
422
423    pub(crate) fn expr_id(&self, expr: ast::Expr) -> Option<ExprOrPatId> {
424        let src = InFile { file_id: self.file_id, value: expr };
425        self.store_sm()?.node_expr(src.as_ref())
426    }
427
428    fn pat_id(&self, pat: &ast::Pat) -> Option<ExprOrPatId> {
429        let src = InFile { file_id: self.file_id, value: pat };
430        self.store_sm()?.node_pat(src)
431    }
432
433    fn type_id(&self, pat: &ast::Type) -> Option<TypeRefId> {
434        let src = InFile { file_id: self.file_id, value: pat };
435        self.store_sm()?.node_type(src)
436    }
437
438    fn binding_id_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingId> {
439        let pat_id = self.pat_id(&pat.clone().into())?;
440        if let Pat::Bind { id, .. } = self.store()?[pat_id.as_pat()?] { Some(id) } else { None }
441    }
442
443    pub(crate) fn expr_adjustments(&self, expr: &ast::Expr) -> Option<&[Adjustment]> {
444        // It is safe to omit destructuring assignments here because they have no adjustments (neither
445        // expressions nor patterns).
446        let expr_id = self.expr_id(expr.clone())?.as_expr()?;
447        let infer = self.infer()?;
448        infer.expr_adjustment(expr_id)
449    }
450
451    pub(crate) fn type_of_type(
452        &self,
453        db: &'db dyn HirDatabase,
454        ty: &ast::Type,
455    ) -> Option<Type<'db>> {
456        let interner = DbInterner::new_no_crate(db);
457
458        let type_ref = self.type_id(ty)?;
459
460        let generic_def = self.resolver.generic_def()?;
461        let generics = OnceCell::new();
462        let mut vars_cts = VarsCtx { types: interner.default_types(), infer: self.infer() };
463        let ty = TyLoweringContext::new(
464            db,
465            &self.resolver,
466            self.store()?,
467            generic_def.into(),
468            generic_def,
469            &generics,
470            // FIXME: Is this correct here? Anyway that should impact mostly diagnostics, which we don't emit here
471            // (this can impact the lifetimes generated, e.g. in `const` they won't be `'static`, but this seems like a
472            // small problem).
473            LifetimeElisionKind::Infer,
474            LifetimeLoweringMode::LateParam,
475        )
476        .with_infer_vars_behavior(Some(&mut vars_cts))
477        .lower_ty(type_ref);
478
479        struct VarsCtx<'a, 'db> {
480            types: &'a DefaultAny<'db>,
481            infer: Option<&'a InferenceResult<'db>>,
482        }
483
484        impl<'db> TyLoweringInferVarsCtx<'db> for VarsCtx<'_, 'db> {
485            fn next_ty_var(&mut self, span: hir_ty::Span) -> Ty<'db> {
486                if let hir_ty::Span::TypeRefId(type_ref) = span
487                    && let Some(ty) =
488                        self.infer.and_then(|infer| infer.type_of_type_placeholder(type_ref))
489                {
490                    ty
491                } else {
492                    self.types.types.error
493                }
494            }
495            fn next_const_var(&mut self, _span: hir_ty::Span) -> hir_ty::next_solver::Const<'db> {
496                self.types.consts.error
497            }
498            fn next_region_var(&mut self, _span: hir_ty::Span) -> Region<'db> {
499                self.types.regions.error
500            }
501        }
502
503        Some(self.ty(ty))
504    }
505
506    pub(crate) fn expr_is_diverging(
507        &self,
508        _db: &'db dyn HirDatabase,
509        expr: &ast::Expr,
510    ) -> Option<bool> {
511        let expr_id = self.expr_id(expr.clone())?;
512        let store = self.store()?;
513        let infer = self.infer()?;
514        Some(self.expr_id_is_diverging(store, infer, expr_id))
515    }
516
517    fn expr_id_is_diverging(
518        &self,
519        store: &ExpressionStore,
520        infer: &InferenceResult<'_>,
521        expr_id: ExprOrPatId,
522    ) -> bool {
523        // FIXME: This is an approximation, perhaps we need to store a set of diverging exprs in inference?
524        if infer.type_of_expr_or_pat(expr_id).is_some_and(|ty| ty.is_never()) {
525            true
526        } else if let ExprOrPatId::ExprId(expr_id) = expr_id
527            && let Expr::Block { tail: Some(tail), .. } = store[expr_id]
528        {
529            self.expr_id_is_diverging(store, infer, tail.into())
530        } else {
531            false
532        }
533    }
534
535    pub(crate) fn type_of_expr(
536        &self,
537        _db: &'db dyn HirDatabase,
538        expr: &ast::Expr,
539    ) -> Option<(Type<'db>, Option<Type<'db>>)> {
540        let expr_id = self.expr_id(expr.clone())?;
541        let infer = self.infer()?;
542        let coerced = expr_id
543            .as_expr()
544            .and_then(|expr_id| infer.expr_adjustment(expr_id))
545            .and_then(|adjusts| adjusts.last().map(|adjust| adjust.target.as_ref()));
546        let ty = infer.expr_or_pat_ty(expr_id);
547        let mk_ty = |ty: Ty<'db>| self.ty(ty);
548        Some((mk_ty(ty), coerced.map(mk_ty)))
549    }
550
551    pub(crate) fn type_of_pat(
552        &self,
553        _db: &'db dyn HirDatabase,
554        pat: &ast::Pat,
555    ) -> Option<(Type<'db>, Option<Type<'db>>)> {
556        let expr_or_pat_id = self.pat_id(pat)?;
557        let infer = self.infer()?;
558        let coerced = match expr_or_pat_id {
559            ExprOrPatId::ExprId(idx) => infer
560                .expr_adjustment(idx)
561                .and_then(|adjusts| adjusts.last())
562                .map(|adjust| adjust.target.as_ref()),
563            ExprOrPatId::PatId(idx) => infer
564                .pat_adjustment(idx)
565                .and_then(|adjusts| adjusts.last())
566                .map(|adjust| adjust.source.as_ref()),
567        };
568
569        let ty = infer.expr_or_pat_ty(expr_or_pat_id);
570        let mk_ty = |ty: Ty<'db>| self.ty(ty);
571        Some((mk_ty(ty), coerced.map(mk_ty)))
572    }
573
574    pub(crate) fn type_of_binding_in_pat(
575        &self,
576        _db: &'db dyn HirDatabase,
577        pat: &ast::IdentPat,
578    ) -> Option<Type<'db>> {
579        let binding_id = self.binding_id_of_pat(pat)?;
580        let infer = self.infer()?;
581        let ty = infer.binding_ty(binding_id);
582        let mk_ty = |ty: Ty<'db>| self.ty(ty);
583        Some(mk_ty(ty))
584    }
585
586    pub(crate) fn type_of_self(
587        &self,
588        _db: &'db dyn HirDatabase,
589        _param: &ast::SelfParam,
590    ) -> Option<Type<'db>> {
591        let binding = match self.body_or_sig.as_ref()? {
592            BodyOrSig::Sig { .. } | BodyOrSig::VariantFields { .. } => return None,
593            BodyOrSig::Body { body, .. } => body.self_param?.formal,
594        };
595        let ty = self.infer()?.binding_ty(binding);
596        Some(self.ty(ty))
597    }
598
599    pub(crate) fn binding_mode_of_pat(
600        &self,
601        _db: &'db dyn HirDatabase,
602        pat: &ast::IdentPat,
603    ) -> Option<BindingMode> {
604        let id = self.pat_id(&pat.clone().into())?;
605        let infer = self.infer()?;
606        Some(match infer.binding_mode(id.as_pat()?)? {
607            hir_ty::BindingMode(hir_ty::ByRef::No, _) => BindingMode::Move,
608            hir_ty::BindingMode(hir_ty::ByRef::Yes(hir_ty::next_solver::Mutability::Mut), _) => {
609                BindingMode::Ref(Mutability::Mut)
610            }
611            hir_ty::BindingMode(hir_ty::ByRef::Yes(hir_ty::next_solver::Mutability::Not), _) => {
612                BindingMode::Ref(Mutability::Shared)
613            }
614        })
615    }
616    pub(crate) fn pattern_adjustments(
617        &self,
618        _db: &'db dyn HirDatabase,
619        pat: &ast::Pat,
620    ) -> Option<SmallVec<[Type<'db>; 1]>> {
621        let pat_id = self.pat_id(pat)?;
622        let infer = self.infer()?;
623        Some(
624            infer
625                .pat_adjustment(pat_id.as_pat()?)?
626                .iter()
627                .map(|adjust| self.ty(adjust.source.as_ref()))
628                .collect(),
629        )
630    }
631
632    pub(crate) fn resolve_method_call_as_callable(
633        &self,
634        db: &'db dyn HirDatabase,
635        call: &ast::MethodCallExpr,
636    ) -> Option<Callable<'db>> {
637        let expr_id = self.expr_id(call.clone().into())?.as_expr()?;
638        let (func, args) = self.infer()?.method_resolution(expr_id)?;
639        let interner = DbInterner::new_no_crate(db);
640        let ty = db.value_ty(func.into())?.instantiate(interner, args).skip_norm_wip();
641        let ty = self.ty(ty);
642        let mut res = ty.as_callable(db)?;
643        res.is_bound_method = true;
644        Some(res)
645    }
646
647    pub(crate) fn resolve_method_call(
648        &self,
649        db: &'db dyn HirDatabase,
650        call: &ast::MethodCallExpr,
651    ) -> Option<Function> {
652        let expr_id = self.expr_id(call.clone().into())?.as_expr()?;
653        let (f_in_trait, substs) = self.infer()?.method_resolution(expr_id)?;
654
655        Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs))
656    }
657
658    pub(crate) fn resolve_method_call_fallback(
659        &self,
660        db: &'db dyn HirDatabase,
661        call: &ast::MethodCallExpr,
662    ) -> Option<(Either<Function, Field>, Option<GenericSubstitution<'db>>)> {
663        let expr_id = self.expr_id(call.clone().into())?.as_expr()?;
664        let inference_result = self.infer()?;
665        match inference_result.method_resolution(expr_id) {
666            Some((f_in_trait, substs)) => {
667                let (fn_, subst) =
668                    self.resolve_impl_method_or_trait_def_with_subst(db, f_in_trait, substs);
669                Some((
670                    Either::Left(fn_),
671                    GenericSubstitution::new_from_fn(fn_, subst, self.type_owner),
672                ))
673            }
674            None => {
675                inference_result.field_resolution(expr_id).and_then(Either::left).map(|field| {
676                    (Either::Right(field.into()), self.field_subst(expr_id, inference_result, db))
677                })
678            }
679        }
680    }
681
682    pub(crate) fn resolve_expr_as_callable(
683        &self,
684        db: &'db dyn HirDatabase,
685        call: &ast::Expr,
686    ) -> Option<Callable<'db>> {
687        let (orig, adjusted) = self.type_of_expr(db, &call.clone())?;
688        adjusted.unwrap_or(orig).as_callable(db)
689    }
690
691    pub(crate) fn resolve_field(
692        &self,
693        field: &ast::FieldExpr,
694    ) -> Option<Either<Field, TupleField<'db>>> {
695        let def = self.infer_body?;
696        let expr_id = self.expr_id(field.clone().into())?.as_expr()?;
697        self.infer()?.field_resolution(expr_id).map(|it| {
698            it.map_either(Into::into, |f| TupleField { owner: def, tuple: f.tuple, index: f.index })
699        })
700    }
701
702    fn field_subst(
703        &self,
704        field_expr: ExprId,
705        infer: &InferenceResult<'_>,
706        _db: &'db dyn HirDatabase,
707    ) -> Option<GenericSubstitution<'db>> {
708        let body = self.store()?;
709        if let Expr::Field { expr: object_expr, name: _ } = body[field_expr] {
710            let (adt, subst) = infer.type_of_expr_with_adjust(object_expr)?.as_adt()?;
711            return Some(GenericSubstitution::new(adt.into(), subst, self.type_owner));
712        }
713        None
714    }
715
716    pub(crate) fn resolve_field_fallback(
717        &self,
718        db: &'db dyn HirDatabase,
719        field: &ast::FieldExpr,
720    ) -> Option<(Either<Either<Field, TupleField<'db>>, Function>, Option<GenericSubstitution<'db>>)>
721    {
722        let def = self.infer_body?;
723        let expr_id = self.expr_id(field.clone().into())?.as_expr()?;
724        let inference_result = self.infer()?;
725        match inference_result.field_resolution(expr_id) {
726            Some(field) => match field {
727                Either::Left(field) => Some((
728                    Either::Left(Either::Left(field.into())),
729                    self.field_subst(expr_id, inference_result, db),
730                )),
731                Either::Right(field) => Some((
732                    Either::Left(Either::Right(TupleField {
733                        owner: def,
734                        tuple: field.tuple,
735                        index: field.index,
736                    })),
737                    None,
738                )),
739            },
740            None => inference_result.method_resolution(expr_id).map(|(f, substs)| {
741                let (f, subst) = self.resolve_impl_method_or_trait_def_with_subst(db, f, substs);
742                (Either::Right(f), GenericSubstitution::new_from_fn(f, subst, self.type_owner))
743            }),
744        }
745    }
746
747    pub(crate) fn resolve_range_pat(
748        &self,
749        db: &'db dyn HirDatabase,
750        range_pat: &ast::RangePat,
751    ) -> Option<StructId> {
752        self.resolve_range_struct(
753            db,
754            range_pat.op_kind()?,
755            range_pat.start().is_some(),
756            range_pat.end().is_some(),
757        )
758    }
759
760    pub(crate) fn resolve_range_expr(
761        &self,
762        db: &'db dyn HirDatabase,
763        range_expr: &ast::RangeExpr,
764    ) -> Option<StructId> {
765        self.resolve_range_struct(
766            db,
767            range_expr.op_kind()?,
768            range_expr.start().is_some(),
769            range_expr.end().is_some(),
770        )
771    }
772
773    fn resolve_range_struct(
774        &self,
775        db: &'db dyn HirDatabase,
776        op_kind: RangeOp,
777        has_start: bool,
778        has_end: bool,
779    ) -> Option<StructId> {
780        let has_new_range = self.resolver.top_level_def_map().features().new_range;
781        let lang_items = self.lang_items(db);
782        match (op_kind, has_start, has_end) {
783            (RangeOp::Exclusive, false, false) => lang_items.RangeFull,
784            (RangeOp::Exclusive, false, true) => lang_items.RangeTo,
785            (RangeOp::Exclusive, true, false) => {
786                if has_new_range {
787                    lang_items.RangeFromCopy
788                } else {
789                    lang_items.RangeFrom
790                }
791            }
792            (RangeOp::Exclusive, true, true) => {
793                if has_new_range {
794                    lang_items.RangeCopy
795                } else {
796                    lang_items.Range
797                }
798            }
799            (RangeOp::Inclusive, false, true) => {
800                if has_new_range {
801                    lang_items.RangeToInclusiveCopy
802                } else {
803                    lang_items.RangeToInclusive
804                }
805            }
806            (RangeOp::Inclusive, true, true) => {
807                if has_new_range {
808                    lang_items.RangeInclusiveCopy
809                } else {
810                    lang_items.RangeInclusiveStruct
811                }
812            }
813            // [E0586] inclusive ranges must be bounded at the end
814            (RangeOp::Inclusive, false, false) => None,
815            (RangeOp::Inclusive, true, false) => None,
816        }
817    }
818
819    pub(crate) fn resolve_await_to_poll(
820        &self,
821        db: &'db dyn HirDatabase,
822        await_expr: &ast::AwaitExpr,
823    ) -> Option<Function> {
824        let mut ty = self.ty_of_expr(await_expr.expr()?)?;
825
826        let into_future_trait = self
827            .resolver
828            .resolve_known_trait(db, &path![core::future::IntoFuture])
829            .map(Trait::from);
830
831        if let Some(into_future_trait) = into_future_trait {
832            let type_ = self.ty(ty);
833            if type_.impls_trait(db, into_future_trait, &[]) {
834                let items = into_future_trait.items(db);
835                let into_future_type = items.into_iter().find_map(|item| match item {
836                    AssocItem::TypeAlias(alias)
837                        if alias.name(db) == Name::new_symbol_root(sym::IntoFuture) =>
838                    {
839                        Some(alias)
840                    }
841                    _ => None,
842                })?;
843                let future_trait = type_.normalize_trait_assoc_type(db, &[], into_future_type)?;
844                ty = future_trait.ty.skip_binder();
845            }
846        }
847
848        let poll_fn = self.lang_items(db).FuturePoll?;
849        // HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
850        // doesn't have any generic parameters, so we skip building another subst for `poll()`.
851        let substs = GenericArgs::new_from_slice(&[ty.into()]);
852        Some(self.resolve_impl_method_or_trait_def(db, poll_fn, substs))
853    }
854
855    pub(crate) fn resolve_prefix_expr(
856        &self,
857        db: &'db dyn HirDatabase,
858        prefix_expr: &ast::PrefixExpr,
859    ) -> Option<Function> {
860        let lang_items = self.lang_items(db);
861        let (_op_trait, op_fn) = match prefix_expr.op_kind()? {
862            ast::UnaryOp::Deref => {
863                // This can be either `Deref::deref` or `DerefMut::deref_mut`.
864                // Since deref kind is inferenced and stored in `InferenceResult.method_resolution`,
865                // use that result to find out which one it is.
866                let (deref_trait, deref) = (lang_items.Deref?, lang_items.Deref_deref?);
867                self.infer()
868                    .and_then(|infer| {
869                        let expr = self.expr_id(prefix_expr.clone().into())?.as_expr()?;
870                        let (func, _) = infer.method_resolution(expr)?;
871                        let (deref_mut_trait, deref_mut) =
872                            (lang_items.DerefMut?, lang_items.DerefMut_deref_mut?);
873                        if func == deref_mut { Some((deref_mut_trait, deref_mut)) } else { None }
874                    })
875                    .unwrap_or((deref_trait, deref))
876            }
877            ast::UnaryOp::Not => (lang_items.Not?, lang_items.Not_not?),
878            ast::UnaryOp::Neg => (lang_items.Neg?, lang_items.Neg_neg?),
879        };
880
881        let ty = self.ty_of_expr(prefix_expr.expr()?)?;
882
883        // HACK: subst for all methods coincides with that for their trait because the methods
884        // don't have any generic parameters, so we skip building another subst for the methods.
885        let substs = GenericArgs::new_from_slice(&[ty.into()]);
886
887        Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
888    }
889
890    pub(crate) fn resolve_index_expr(
891        &self,
892        db: &'db dyn HirDatabase,
893        index_expr: &ast::IndexExpr,
894    ) -> Option<Function> {
895        let base_ty = self.ty_of_expr(index_expr.base()?)?;
896        let index_ty = self.ty_of_expr(index_expr.index()?)?;
897        let lang_items = self.lang_items(db);
898
899        let (_index_trait, index_fn) = (lang_items.Index?, lang_items.Index_index?);
900        let op_fn = self
901            .infer()
902            .and_then(|infer| {
903                let expr = self.expr_id(index_expr.clone().into())?.as_expr()?;
904                let (func, _) = infer.method_resolution(expr)?;
905                let (_index_mut_trait, index_mut_fn) =
906                    (lang_items.IndexMut_index_mut?, lang_items.IndexMut_index_mut?);
907                if func == index_mut_fn { Some(index_mut_fn) } else { None }
908            })
909            .unwrap_or(index_fn);
910        // HACK: subst for all methods coincides with that for their trait because the methods
911        // don't have any generic parameters, so we skip building another subst for the methods.
912        let substs = GenericArgs::new_from_slice(&[base_ty.into(), index_ty.into()]);
913        Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
914    }
915
916    pub(crate) fn resolve_bin_expr(
917        &self,
918        db: &'db dyn HirDatabase,
919        binop_expr: &ast::BinExpr,
920    ) -> Option<Function> {
921        let op = binop_expr.op_kind()?;
922        let lhs = self.ty_of_expr(binop_expr.lhs()?)?;
923        let rhs = self.ty_of_expr(binop_expr.rhs()?)?;
924
925        let (op_fn, _op_trait) = lang_items_for_bin_op(self.lang_items(db), op)
926            .and_then(|(method, trait_)| method.zip(trait_))?;
927        // HACK: subst for `index()` coincides with that for `Index` because `index()` itself
928        // doesn't have any generic parameters, so we skip building another subst for `index()`.
929        let substs = GenericArgs::new_from_slice(&[lhs.into(), rhs.into()]);
930
931        Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
932    }
933
934    pub(crate) fn resolve_try_expr(
935        &self,
936        db: &'db dyn HirDatabase,
937        try_expr: &ast::TryExpr,
938    ) -> Option<Function> {
939        let ty = self.ty_of_expr(try_expr.expr()?)?;
940
941        let op_fn = self.lang_items(db).TryTraitBranch?;
942        // HACK: subst for `branch()` coincides with that for `Try` because `branch()` itself
943        // doesn't have any generic parameters, so we skip building another subst for `branch()`.
944        let substs = GenericArgs::new_from_slice(&[ty.into()]);
945
946        Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
947    }
948
949    pub(crate) fn resolve_record_field(
950        &self,
951        db: &'db dyn HirDatabase,
952        field: &ast::RecordExprField,
953    ) -> Option<(Field, Option<Local<'db>>, Type<'db>, GenericSubstitution<'db>)> {
954        let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
955        let expr = ast::Expr::from(record_expr);
956        let expr_id = self.store_sm()?.node_expr(InFile::new(self.file_id, &expr))?;
957        let interner = DbInterner::new_no_crate(db);
958
959        let ast_name = field.field_name()?;
960        let local_name = ast_name.as_name();
961        let local = if field.name_ref().is_some() {
962            None
963        } else {
964            // Shorthand syntax, resolve to the local
965            let path = Path::from_known_path_with_no_generic(ModPath::from_segments(
966                PathKind::Plain,
967                once(local_name.clone()),
968            ));
969            match self.resolver.resolve_path_in_value_ns_fully(
970                db,
971                &path,
972                name_hygiene(db, InFile::new(self.file_id, ast_name.syntax())),
973            ) {
974                Some(ValueNs::LocalBinding(binding_id)) => Some(Local {
975                    binding_id,
976                    parent: self.owner()?,
977                    parent_infer: self.infer_body?,
978                }),
979                _ => None,
980            }
981        };
982        let (adt, subst) = self.infer()?.type_of_expr_or_pat(expr_id)?.as_adt()?;
983        let variant = self.infer()?.variant_resolution_for_expr_or_pat(expr_id)?;
984        let variant_data = variant.fields(db);
985        let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
986        let field_ty = (*db.field_types(variant).get(field.local_id)?)
987            .ty()
988            .instantiate(interner, subst)
989            .skip_norm_wip();
990        Some((
991            field.into(),
992            local,
993            self.ty(field_ty),
994            GenericSubstitution::new(adt.into(), subst, self.type_owner),
995        ))
996    }
997
998    pub(crate) fn resolve_record_pat_field(
999        &self,
1000        db: &'db dyn HirDatabase,
1001        field: &ast::RecordPatField,
1002    ) -> Option<(Field, Type<'db>, GenericSubstitution<'db>)> {
1003        let interner = DbInterner::new_no_crate(db);
1004        let field_name = field.field_name()?.as_name();
1005        let record_pat = ast::RecordPat::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
1006        let pat_id = self.pat_id(&record_pat.into())?;
1007        let variant = self.infer()?.variant_resolution_for_pat(pat_id.as_pat()?)?;
1008        let variant_data = variant.fields(db);
1009        let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? };
1010        let (adt, subst) = self.infer()?.pat_ty(pat_id.as_pat()?).as_adt()?;
1011        let field_ty = (*db.field_types(variant).get(field.local_id)?)
1012            .ty()
1013            .instantiate(interner, subst)
1014            .skip_norm_wip();
1015        Some((
1016            field.into(),
1017            self.ty(field_ty),
1018            GenericSubstitution::new(adt.into(), subst, self.type_owner),
1019        ))
1020    }
1021
1022    pub(crate) fn resolve_tuple_struct_pat_fields(
1023        &self,
1024        db: &'db dyn HirDatabase,
1025        tuple_struct_pat: &ast::TupleStructPat,
1026    ) -> Option<Vec<(Field, Type<'db>)>> {
1027        let interner = DbInterner::new_no_crate(db);
1028        let pat_id = self.pat_id(&tuple_struct_pat.clone().into())?;
1029        let variant_id = self.infer()?.variant_resolution_for_pat(pat_id.as_pat()?)?;
1030        let (_adt, substs) = self.infer()?.pat_ty(pat_id.as_pat()?).as_adt()?;
1031
1032        Some(
1033            db.field_types(variant_id)
1034                .iter()
1035                .map(|(local_id, field)| {
1036                    let def = Field { parent: variant_id.into(), id: local_id };
1037                    let ty = field.ty().instantiate(interner, substs).skip_norm_wip();
1038                    (def, self.ty(ty))
1039                })
1040                .collect(),
1041        )
1042    }
1043
1044    pub(crate) fn resolve_bind_pat_to_const(
1045        &self,
1046        db: &'db dyn HirDatabase,
1047        pat: &ast::IdentPat,
1048    ) -> Option<ModuleDef> {
1049        let expr_or_pat_id = self.pat_id(&pat.clone().into())?;
1050        let store = self.store()?;
1051
1052        let path = match expr_or_pat_id {
1053            ExprOrPatId::ExprId(idx) => match &store[idx] {
1054                Expr::Path(path) => path,
1055                _ => return None,
1056            },
1057            ExprOrPatId::PatId(idx) => match &store[idx] {
1058                Pat::Path(path) => path,
1059                _ => return None,
1060            },
1061        };
1062
1063        let store_owner = self.resolver.expression_store_owner();
1064        let (res, _) = resolve_hir_value_path(
1065            db,
1066            &self.resolver,
1067            store_owner,
1068            self.infer_body,
1069            path,
1070            HygieneId::ROOT,
1071        )?;
1072        match res {
1073            PathResolution::Def(def) => Some(def),
1074            _ => None,
1075        }
1076    }
1077
1078    pub(crate) fn resolve_use_type_arg(&self, name: &ast::NameRef) -> Option<crate::TypeParam> {
1079        let name = name.as_name();
1080        self.resolver
1081            .all_generic_params()
1082            .find_map(|(params, parent)| params.find_type_by_name(&name, parent))
1083            .map(crate::TypeParam::from)
1084    }
1085
1086    pub(crate) fn resolve_offset_of_field(
1087        &self,
1088        db: &'db dyn HirDatabase,
1089        name_ref: &ast::NameRef,
1090    ) -> Option<(Either<crate::EnumVariant, crate::Field>, GenericSubstitution<'db>)> {
1091        let offset_of_expr = ast::OffsetOfExpr::cast(name_ref.syntax().parent()?)?;
1092        let container = offset_of_expr.ty()?;
1093        let container = self.type_of_type(db, &container)?;
1094
1095        let env = self.trait_environment(db);
1096
1097        let interner = DbInterner::new_with(db, env.krate);
1098        let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
1099
1100        let mut container = Either::Right(container.ty.skip_binder());
1101        for field_name in offset_of_expr.fields() {
1102            if let Either::Right(container) = &mut container {
1103                *container = structurally_normalize_ty(&infcx, *container, env.param_env);
1104            }
1105            let handle_variants =
1106                |variant: VariantId, subst: GenericArgs<'db>, container: &mut _| {
1107                    let fields = variant.fields(db);
1108                    let field = fields.field(&field_name.as_name())?;
1109                    let field_types = db.field_types(variant);
1110                    *container = Either::Right(
1111                        field_types[field].ty().instantiate(interner, subst).skip_norm_wip(),
1112                    );
1113                    let generic_def = match variant {
1114                        VariantId::EnumVariantId(it) => it.loc(db).parent.into(),
1115                        VariantId::StructId(it) => it.into(),
1116                        VariantId::UnionId(it) => it.into(),
1117                    };
1118                    Some((
1119                        Either::Right(Field { parent: variant.into(), id: field }),
1120                        generic_def,
1121                        subst,
1122                    ))
1123                };
1124            let temp_ty = Ty::new_error(interner, ErrorGuaranteed);
1125            let (field_def, generic_def, subst) =
1126                match std::mem::replace(&mut container, Either::Right(temp_ty)) {
1127                    Either::Left((variant_id, subst)) => {
1128                        handle_variants(VariantId::from(variant_id), subst, &mut container)?
1129                    }
1130                    Either::Right(container_ty) => match container_ty.kind() {
1131                        TyKind::Adt(adt_def, subst) => match adt_def.def_id() {
1132                            AdtId::StructId(id) => {
1133                                handle_variants(id.into(), subst, &mut container)?
1134                            }
1135                            AdtId::UnionId(id) => {
1136                                handle_variants(id.into(), subst, &mut container)?
1137                            }
1138                            AdtId::EnumId(id) => {
1139                                let variants = id.enum_variants(db);
1140                                let variant = variants.variant(&field_name.as_name())?;
1141                                container = Either::Left((variant, subst));
1142                                (Either::Left(EnumVariant { id: variant }), id.into(), subst)
1143                            }
1144                        },
1145                        _ => return None,
1146                    },
1147                };
1148
1149            if field_name.syntax().text_range() == name_ref.syntax().text_range() {
1150                return Some((
1151                    field_def,
1152                    GenericSubstitution::new(generic_def, subst, self.type_owner),
1153                ));
1154            }
1155        }
1156        never!("the `NameRef` is a child of the `OffsetOfExpr`, we should've visited it");
1157        None
1158    }
1159
1160    pub(crate) fn resolve_path(
1161        &self,
1162        db: &'db dyn HirDatabase,
1163        path: &ast::Path,
1164    ) -> Option<(PathResolution<'db>, Option<GenericSubstitution<'db>>)> {
1165        let parent = path.syntax().parent();
1166        let parent = || parent.clone();
1167
1168        let mut prefer_value_ns = parent().and_then(ast::PathExpr::cast).is_some();
1169        let resolved = (|| {
1170            let infer = self.infer()?;
1171            if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
1172                let expr_id = self.expr_id(path_expr.into())?;
1173                if let Some((assoc, subs)) = infer.assoc_resolutions_for_expr_or_pat(expr_id) {
1174                    let (assoc, subst) = match assoc {
1175                        CandidateId::FunctionId(f_in_trait) => {
1176                            match infer.type_of_expr_or_pat(expr_id) {
1177                                None => {
1178                                    let subst = GenericSubstitution::new(
1179                                        f_in_trait.into(),
1180                                        subs,
1181                                        self.type_owner,
1182                                    );
1183                                    (AssocItem::Function(f_in_trait.into()), Some(subst))
1184                                }
1185                                Some(func_ty) => {
1186                                    if let TyKind::FnDef(_fn_def, subs) = func_ty.kind() {
1187                                        let (fn_, subst) = self
1188                                            .resolve_impl_method_or_trait_def_with_subst(
1189                                                db, f_in_trait, subs,
1190                                            );
1191                                        let subst = GenericSubstitution::new_from_fn(
1192                                            fn_,
1193                                            subst,
1194                                            self.type_owner,
1195                                        );
1196                                        (AssocItem::Function(fn_), subst)
1197                                    } else {
1198                                        let subst = GenericSubstitution::new(
1199                                            f_in_trait.into(),
1200                                            subs,
1201                                            self.type_owner,
1202                                        );
1203                                        (AssocItem::Function(f_in_trait.into()), Some(subst))
1204                                    }
1205                                }
1206                            }
1207                        }
1208                        CandidateId::ConstId(const_id) => {
1209                            let (konst, subst) =
1210                                self.resolve_impl_const_or_trait_def_with_subst(db, const_id, subs);
1211                            let subst =
1212                                GenericSubstitution::new(konst.into(), subst, self.type_owner);
1213                            (AssocItem::Const(konst.into()), Some(subst))
1214                        }
1215                    };
1216
1217                    return Some((PathResolution::Def(assoc.into()), subst));
1218                }
1219                if let Some(VariantId::EnumVariantId(variant)) =
1220                    infer.variant_resolution_for_expr_or_pat(expr_id)
1221                {
1222                    return Some((
1223                        PathResolution::Def(ModuleDef::EnumVariant(variant.into())),
1224                        None,
1225                    ));
1226                }
1227                prefer_value_ns = true;
1228            } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
1229                let expr_or_pat_id = self.pat_id(&path_pat.into())?;
1230                if let Some((assoc, subs)) = infer.assoc_resolutions_for_expr_or_pat(expr_or_pat_id)
1231                {
1232                    let (assoc, subst) = match assoc {
1233                        CandidateId::ConstId(const_id) => {
1234                            let (konst, subst) =
1235                                self.resolve_impl_const_or_trait_def_with_subst(db, const_id, subs);
1236                            let subst =
1237                                GenericSubstitution::new(konst.into(), subst, self.type_owner);
1238                            (AssocItemId::from(konst), subst)
1239                        }
1240                        CandidateId::FunctionId(function_id) => (
1241                            function_id.into(),
1242                            GenericSubstitution::new(function_id.into(), subs, self.type_owner),
1243                        ),
1244                    };
1245                    return Some((PathResolution::Def(AssocItem::from(assoc).into()), Some(subst)));
1246                }
1247                if let Some(VariantId::EnumVariantId(variant)) =
1248                    infer.variant_resolution_for_expr_or_pat(expr_or_pat_id)
1249                {
1250                    return Some((
1251                        PathResolution::Def(ModuleDef::EnumVariant(variant.into())),
1252                        None,
1253                    ));
1254                }
1255            } else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
1256                let expr_id = self.expr_id(rec_lit.into())?;
1257                if let Some(VariantId::EnumVariantId(variant)) =
1258                    infer.variant_resolution_for_expr_or_pat(expr_id)
1259                {
1260                    return Some((
1261                        PathResolution::Def(ModuleDef::EnumVariant(variant.into())),
1262                        None,
1263                    ));
1264                }
1265            } else {
1266                let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from);
1267                let tuple_struct_pat =
1268                    || parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
1269                if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
1270                    let pat_id = self.pat_id(&pat)?;
1271                    let variant_res_for_pat = infer.variant_resolution_for_pat(pat_id.as_pat()?);
1272                    if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
1273                        return Some((
1274                            PathResolution::Def(ModuleDef::EnumVariant(variant.into())),
1275                            None,
1276                        ));
1277                    }
1278                }
1279            }
1280            None
1281        })();
1282        if resolved.is_some() {
1283            return resolved;
1284        }
1285
1286        // FIXME: collectiong here shouldnt be necessary?
1287        let mut collector =
1288            ExprCollector::new(db, self.resolver.module(), self.file_id, LoweringMode::Ide);
1289        let hir_path =
1290            collector.lower_path(path.clone(), &mut ExprCollector::impl_trait_error_allocator)?;
1291        let parent_hir_path = path
1292            .parent_path()
1293            .and_then(|p| collector.lower_path(p, &mut ExprCollector::impl_trait_error_allocator));
1294        let (store, _) = collector.store.finish();
1295
1296        // Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are
1297        // trying to resolve foo::bar.
1298        if let Some(use_tree) = parent().and_then(ast::UseTree::cast)
1299            && use_tree.coloncolon_token().is_some()
1300        {
1301            return resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &store)
1302                .map(|it| (it, None));
1303        }
1304
1305        let meta_path = path
1306            .syntax()
1307            .ancestors()
1308            .take_while(|it| {
1309                let kind = it.kind();
1310                ast::Path::can_cast(kind) || ast::Meta::can_cast(kind)
1311            })
1312            .last()
1313            .and_then(ast::Meta::cast);
1314
1315        // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we are
1316        // trying to resolve foo::bar.
1317        if let Some(parent_hir_path) = parent_hir_path {
1318            return match resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &store) {
1319                None if meta_path.is_some() => path
1320                    .first_segment()
1321                    .and_then(|it| it.name_ref())
1322                    .and_then(|name_ref| {
1323                        ToolModule::by_name(db, self.resolver.krate().into(), name_ref.text())
1324                            .map(PathResolution::ToolModule)
1325                    })
1326                    .map(|it| (it, None)),
1327                // Case the type name conflict with use module,
1328                // e.g.
1329                // ```
1330                // use std::str;
1331                // fn main() {
1332                //     str::from_utf8();  // as module std::str
1333                //     str::len();        // as primitive type str
1334                //     str::no_exist_item(); // as primitive type str
1335                // }
1336                // ```
1337                Some(it) if matches!(it, PathResolution::Def(ModuleDef::BuiltinType(_))) => {
1338                    if let Some(mod_path) = hir_path.mod_path()
1339                        && let Some(ModuleDefId::ModuleId(id)) =
1340                            self.resolver.resolve_module_path_in_items(db, mod_path).take_types()
1341                    {
1342                        let parent_hir_name = parent_hir_path.segments().get(1).map(|it| it.name);
1343                        let module = crate::Module { id };
1344                        if module
1345                            .scope(db, None)
1346                            .into_iter()
1347                            .any(|(name, _)| Some(&name) == parent_hir_name)
1348                        {
1349                            return Some((PathResolution::Def(ModuleDef::Module(module)), None));
1350                        };
1351                    }
1352                    Some((it, None))
1353                }
1354                // FIXME: We do not show substitutions for parts of path, because this is really complex
1355                // due to the interactions with associated items of `impl`s and associated items of associated
1356                // types.
1357                res => res.map(|it| (it, None)),
1358            };
1359        } else if let Some(meta_path) = meta_path {
1360            // Case where we are resolving the final path segment of a path in an attribute
1361            // in this case we have to check for inert/builtin attributes and tools and prioritize
1362            // resolution of attributes over other namespaces
1363            if let Some(name_ref) = path.as_single_name_ref() {
1364                let builtin = BuiltinAttr::builtin(name_ref.text());
1365                if builtin.is_some() {
1366                    return builtin.map(|it| (PathResolution::BuiltinAttr(it), None));
1367                }
1368
1369                if let Some(attr) = meta_path.parent_attr() {
1370                    let adt =
1371                        attr.syntax().ancestors().find_map(ast::Item::cast).and_then(
1372                            |it| match it {
1373                                ast::Item::Struct(it) => Some(ast::Adt::Struct(it)),
1374                                ast::Item::Enum(it) => Some(ast::Adt::Enum(it)),
1375                                ast::Item::Union(it) => Some(ast::Adt::Union(it)),
1376                                _ => None,
1377                            },
1378                        );
1379                    if let Some(adt) = adt {
1380                        let ast_id = self.file_id.ast_id_map(db).ast_id(&adt);
1381                        if let Some(helpers) = self
1382                            .resolver
1383                            .def_map()
1384                            .derive_helpers_in_scope(InFile::new(self.file_id, ast_id))
1385                        {
1386                            // FIXME: Multiple derives can have the same helper
1387                            let name_ref = name_ref.as_name();
1388                            for (macro_id, mut helpers) in
1389                                helpers.iter().chunk_by(|(_, macro_id, ..)| macro_id).into_iter()
1390                            {
1391                                if let Some(idx) = helpers.position(|(name, ..)| *name == name_ref)
1392                                {
1393                                    return Some((
1394                                        PathResolution::DeriveHelper(DeriveHelper {
1395                                            derive: *macro_id,
1396                                            idx: idx as u32,
1397                                        }),
1398                                        None,
1399                                    ));
1400                                }
1401                            }
1402                        }
1403                    }
1404                }
1405            }
1406            return match resolve_hir_path_as_attr_macro(db, &self.resolver, &hir_path) {
1407                Some(m) => Some((PathResolution::Def(ModuleDef::Macro(m)), None)),
1408                // this labels any path that starts with a tool module as the tool itself, this is technically wrong
1409                // but there is no benefit in differentiating these two cases for the time being
1410                None => path
1411                    .first_segment()
1412                    .and_then(|it| it.name_ref())
1413                    .and_then(|name_ref| {
1414                        ToolModule::by_name(db, self.resolver.krate().into(), name_ref.text())
1415                            .map(PathResolution::ToolModule)
1416                    })
1417                    .map(|it| (it, None)),
1418            };
1419        }
1420        if parent().is_some_and(|it| ast::Visibility::can_cast(it.kind())) {
1421            // No substitution because only modules can be inside visibilities, and those have no generics.
1422            resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &store).map(|it| (it, None))
1423        } else {
1424            // Probably a type, no need to show substitutions for those.
1425            let res = resolve_hir_path_(
1426                db,
1427                &self.resolver,
1428                self.infer_body,
1429                &hir_path,
1430                prefer_value_ns,
1431                name_hygiene(db, InFile::new(self.file_id, path.syntax())),
1432                Some(&store),
1433                false,
1434            )
1435            .any()?;
1436            let subst = (|| {
1437                let parent = parent()?;
1438                let ty = if let Some(expr) = ast::Expr::cast(parent.clone()) {
1439                    let expr_id = self.expr_id(expr)?;
1440                    self.infer()?.type_of_expr_or_pat(expr_id)?
1441                } else {
1442                    let pat = ast::Pat::cast(parent)?;
1443                    let pat_id = self.pat_id(&pat)?;
1444                    self.infer()?.expr_or_pat_ty(pat_id)
1445                };
1446                let (subst, expected_resolution) = match ty.kind() {
1447                    TyKind::Adt(adt_def, subst) => {
1448                        let adt_id = adt_def.def_id();
1449                        (
1450                            GenericSubstitution::new(adt_id.into(), subst, self.type_owner),
1451                            PathResolution::Def(ModuleDef::Adt(adt_id.into())),
1452                        )
1453                    }
1454                    TyKind::Alias(AliasTy {
1455                        kind: AliasTyKind::Projection { def_id },
1456                        args,
1457                        ..
1458                    }) => {
1459                        let assoc_id = def_id.0;
1460                        (
1461                            GenericSubstitution::new(assoc_id.into(), args, self.type_owner),
1462                            PathResolution::Def(ModuleDef::TypeAlias(assoc_id.into())),
1463                        )
1464                    }
1465                    TyKind::FnDef(fn_id, subst) => {
1466                        let generic_def_id = match fn_id.0 {
1467                            CallableDefId::StructId(id) => id.into(),
1468                            CallableDefId::FunctionId(id) => id.into(),
1469                            CallableDefId::EnumVariantId(_) => return None,
1470                        };
1471                        (
1472                            GenericSubstitution::new(generic_def_id, subst, self.type_owner),
1473                            PathResolution::Def(ModuleDefId::from(fn_id.0).into()),
1474                        )
1475                    }
1476                    _ => return None,
1477                };
1478                if res != expected_resolution {
1479                    // The user will not understand where we're coming from. This can happen (I think) with type aliases.
1480                    return None;
1481                }
1482                Some(subst)
1483            })();
1484            Some((res, subst))
1485        }
1486    }
1487
1488    pub(crate) fn resolve_hir_path_per_ns(
1489        &self,
1490        db: &'db dyn HirDatabase,
1491        path: &ast::Path,
1492    ) -> Option<PathResolutionPerNs<'db>> {
1493        let mut collector =
1494            ExprCollector::new(db, self.resolver.module(), self.file_id, LoweringMode::Ide);
1495        let hir_path =
1496            collector.lower_path(path.clone(), &mut ExprCollector::impl_trait_error_allocator)?;
1497        let (store, _) = collector.store.finish();
1498        Some(resolve_hir_path_(
1499            db,
1500            &self.resolver,
1501            self.infer_body,
1502            &hir_path,
1503            false,
1504            name_hygiene(db, InFile::new(self.file_id, path.syntax())),
1505            Some(&store),
1506            true,
1507        ))
1508    }
1509
1510    pub(crate) fn record_literal_missing_fields(
1511        &self,
1512        db: &'db dyn HirDatabase,
1513        literal: &ast::RecordExpr,
1514    ) -> Option<Vec<(Field, Type<'db>)>> {
1515        let body = self.store()?;
1516        let infer = self.infer()?;
1517
1518        let expr_id = self.expr_id(literal.clone().into())?.as_expr()?;
1519        let substs = infer.expr_ty(expr_id).as_adt()?.1;
1520        let (variant, missing_fields) =
1521            record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?;
1522        let res = self.missing_fields(db, substs, variant, missing_fields);
1523        Some(res)
1524    }
1525
1526    pub(crate) fn record_literal_matched_fields(
1527        &self,
1528        db: &'db dyn HirDatabase,
1529        literal: &ast::RecordExpr,
1530    ) -> Option<Vec<(Field, Type<'db>)>> {
1531        let body = self.store()?;
1532        let infer = self.infer()?;
1533
1534        let expr_id = self.expr_id(literal.clone().into())?.as_expr()?;
1535        let substs = infer.expr_ty(expr_id).as_adt()?.1;
1536        let (variant, matched_fields) =
1537            record_literal_matched_fields(db, infer, expr_id, &body[expr_id])?;
1538
1539        let res = self.missing_fields(db, substs, variant, matched_fields);
1540        Some(res)
1541    }
1542
1543    pub(crate) fn record_pattern_missing_fields(
1544        &self,
1545        db: &'db dyn HirDatabase,
1546        pattern: &ast::RecordPat,
1547    ) -> Option<Vec<(Field, Type<'db>)>> {
1548        let body = self.store()?;
1549        let infer = self.infer()?;
1550
1551        let pat_id = self.pat_id(&pattern.clone().into())?.as_pat()?;
1552        let substs = infer.pat_ty(pat_id).as_adt()?.1;
1553
1554        let (variant, missing_fields) =
1555            record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?;
1556        let res = self.missing_fields(db, substs, variant, missing_fields);
1557        Some(res)
1558    }
1559
1560    pub(crate) fn record_pattern_matched_fields(
1561        &self,
1562        db: &'db dyn HirDatabase,
1563        pattern: &ast::RecordPat,
1564    ) -> Option<Vec<(Field, Type<'db>)>> {
1565        let body = self.store()?;
1566        let infer = self.infer()?;
1567
1568        let pat_id = self.pat_id(&pattern.clone().into())?.as_pat()?;
1569        let substs = infer.pat_ty(pat_id).as_adt()?.1;
1570
1571        let (variant, matched_fields) =
1572            record_pattern_matched_fields(db, infer, pat_id, &body[pat_id])?;
1573        let res = self.missing_fields(db, substs, variant, matched_fields);
1574        Some(res)
1575    }
1576
1577    fn missing_fields(
1578        &self,
1579        db: &'db dyn HirDatabase,
1580        substs: GenericArgs<'db>,
1581        variant: VariantId,
1582        missing_fields: Vec<LocalFieldId>,
1583    ) -> Vec<(Field, Type<'db>)> {
1584        let interner = DbInterner::new_no_crate(db);
1585        let field_types = db.field_types(variant);
1586
1587        missing_fields
1588            .into_iter()
1589            .map(|local_id| {
1590                let field = FieldId { parent: variant, local_id };
1591                let ty = field_types[local_id].ty().instantiate(interner, substs).skip_norm_wip();
1592                (field.into(), self.ty(ty))
1593            })
1594            .collect()
1595    }
1596
1597    pub(crate) fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> {
1598        let infer = self.infer()?;
1599        let expr_id = self.expr_id(record_lit.into())?;
1600        infer.variant_resolution_for_expr_or_pat(expr_id)
1601    }
1602
1603    pub(crate) fn is_unsafe_macro_call_expr(
1604        &self,
1605        db: &'db dyn HirDatabase,
1606        macro_expr: InFile<&ast::MacroExpr>,
1607    ) -> bool {
1608        if let Some((def, body, sm, Some(infer))) = self.def()
1609            && let Some(expanded_expr) = sm.macro_expansion_expr(macro_expr)
1610        {
1611            let mut is_unsafe = false;
1612            let mut walk_expr = |expr_id| {
1613                unsafe_operations(db, infer, def, body, expr_id, &mut |_, inside_unsafe_block| {
1614                    is_unsafe |= inside_unsafe_block == InsideUnsafeBlock::No
1615                })
1616            };
1617            match expanded_expr {
1618                ExprOrPatId::ExprId(expanded_expr) => walk_expr(expanded_expr),
1619                ExprOrPatId::PatId(expanded_pat) => body.walk_exprs_in_pat(expanded_pat, walk_expr),
1620            }
1621            return is_unsafe;
1622        }
1623        false
1624    }
1625
1626    /// Returns the range of the implicit template argument and its resolution at the given `offset`
1627    pub(crate) fn resolve_offset_in_format_args(
1628        &self,
1629        db: &'db dyn HirDatabase,
1630        format_args: InFile<&ast::FormatArgsExpr>,
1631        offset: TextSize,
1632    ) -> Option<(TextRange, Option<PathResolution<'db>>)> {
1633        let (hygiene, implicits) = self.store_sm()?.implicit_format_args(format_args)?;
1634        implicits.iter().find(|(range, _)| range.contains_inclusive(offset)).map(|(range, name)| {
1635            (
1636                *range,
1637                resolve_hir_value_path(
1638                    db,
1639                    &self.resolver,
1640                    self.resolver.expression_store_owner(),
1641                    self.infer_body,
1642                    &Path::from_known_path_with_no_generic(ModPath::from_segments(
1643                        PathKind::Plain,
1644                        Some(name.clone()),
1645                    )),
1646                    hygiene,
1647                )
1648                .map(|(it, _)| it),
1649            )
1650        })
1651    }
1652
1653    pub(crate) fn resolve_offset_in_asm_template(
1654        &self,
1655        asm: InFile<&ast::AsmExpr>,
1656        line: usize,
1657        offset: TextSize,
1658    ) -> Option<(ExpressionStoreOwnerId, (ExprId, TextRange, usize))> {
1659        let (def, _, sm, _) = self.def()?;
1660        let (expr, args) = sm.asm_template_args(asm)?;
1661        Some(def).zip(
1662            args.get(line)?
1663                .iter()
1664                .find(|(range, _)| range.contains_inclusive(offset))
1665                .map(|(range, idx)| (expr, *range, *idx)),
1666        )
1667    }
1668
1669    pub(crate) fn as_format_args_parts<'a>(
1670        &'a self,
1671        db: &'db dyn HirDatabase,
1672        format_args: InFile<&ast::FormatArgsExpr>,
1673    ) -> Option<impl Iterator<Item = (TextRange, Option<PathResolution<'db>>)> + 'a> {
1674        let (hygiene, names) = self.store_sm()?.implicit_format_args(format_args)?;
1675        Some(names.iter().map(move |(range, name)| {
1676            (
1677                *range,
1678                resolve_hir_value_path(
1679                    db,
1680                    &self.resolver,
1681                    self.resolver.expression_store_owner(),
1682                    self.infer_body,
1683                    &Path::from_known_path_with_no_generic(ModPath::from_segments(
1684                        PathKind::Plain,
1685                        Some(name.clone()),
1686                    )),
1687                    hygiene,
1688                )
1689                .map(|(it, _)| it),
1690            )
1691        }))
1692    }
1693
1694    pub(crate) fn as_asm_parts(
1695        &self,
1696        asm: InFile<&ast::AsmExpr>,
1697    ) -> Option<(ExpressionStoreOwnerId, (ExprId, &[Vec<(TextRange, usize)>]))> {
1698        let (def, _, sm, _) = self.def()?;
1699        Some(def).zip(sm.asm_template_args(asm))
1700    }
1701
1702    fn resolve_impl_method_or_trait_def(
1703        &self,
1704        db: &'db dyn HirDatabase,
1705        func: FunctionId,
1706        substs: GenericArgs<'db>,
1707    ) -> Function {
1708        self.resolve_impl_method_or_trait_def_with_subst(db, func, substs).0
1709    }
1710
1711    fn resolve_impl_method_or_trait_def_with_subst(
1712        &self,
1713        db: &'db dyn HirDatabase,
1714        func: FunctionId,
1715        substs: GenericArgs<'db>,
1716    ) -> (Function, GenericArgs<'db>) {
1717        let owner = match self.resolver.generic_def() {
1718            Some(it) => it,
1719            None => return (func.into(), substs),
1720        };
1721        let env = self.param_and(db.trait_environment(owner));
1722        let (func, args) = db.lookup_impl_method(env, func, substs);
1723        match func {
1724            Either::Left(func) => (func.into(), args),
1725            Either::Right((impl_, method)) => {
1726                (Function { id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } }, args)
1727            }
1728        }
1729    }
1730
1731    fn resolve_impl_const_or_trait_def_with_subst(
1732        &self,
1733        db: &'db dyn HirDatabase,
1734        const_id: ConstId,
1735        subs: GenericArgs<'db>,
1736    ) -> (ConstId, GenericArgs<'db>) {
1737        let owner = match self.resolver.generic_def() {
1738            Some(it) => it,
1739            None => return (const_id, subs),
1740        };
1741        let env = self.param_and(db.trait_environment(owner));
1742        let interner = DbInterner::new_with(db, env.krate);
1743        let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
1744        method_resolution::lookup_impl_const(&infcx, env.param_env, const_id, subs)
1745    }
1746
1747    fn lang_items<'a>(&self, db: &'a dyn HirDatabase) -> &'a LangItems {
1748        hir_def::lang_item::lang_items(db, self.resolver.krate())
1749    }
1750
1751    fn ty_of_expr(&self, expr: ast::Expr) -> Option<Ty<'db>> {
1752        self.infer()?.type_of_expr_or_pat(self.expr_id(expr)?)
1753    }
1754}
1755
1756// Note: the `ExprId` here does not need to be accurate, what's important is that it points at the same
1757// inference root.
1758fn scope_for(
1759    db: &dyn HirDatabase,
1760    scopes: &ExprScopes,
1761    source_map: &ExpressionStoreSourceMap,
1762    node: InFile<&SyntaxNode>,
1763) -> Option<(ScopeId, ExprId)> {
1764    node.ancestors_with_macros(db)
1765        .take_while(|it| {
1766            let kind = it.kind();
1767            !ast::Item::can_cast(kind)
1768                || ast::MacroCall::can_cast(kind)
1769                || ast::Use::can_cast(kind)
1770                || ast::AsmExpr::can_cast(kind)
1771        })
1772        .filter_map(|it| it.map(ast::Expr::cast).transpose())
1773        .filter_map(|it| source_map.node_expr(it.as_ref())?.as_expr())
1774        .find_map(|expr| scopes.scope_for(expr).map(|scope| (scope, expr)))
1775}
1776
1777fn scope_for_offset(
1778    db: &dyn HirDatabase,
1779    scopes: &ExprScopes,
1780    source_map: &ExpressionStoreSourceMap,
1781    from_file: HirFileId,
1782    offset: TextSize,
1783) -> Option<(ScopeId, ExprId)> {
1784    scopes
1785        .scope_by_expr()
1786        .iter()
1787        .filter_map(|(id, scope)| {
1788            let InFile { file_id, value } = source_map.expr_syntax(id).ok()?;
1789            if from_file == file_id {
1790                return Some((value.text_range(), scope, id));
1791            }
1792
1793            // FIXME handle attribute expansion
1794            let source = iter::successors(file_id.macro_file().map(|it| it.call_node(db)), |it| {
1795                Some(it.file_id.macro_file()?.call_node(db))
1796            })
1797            .find(|it| it.file_id == from_file)
1798            .filter(|it| it.kind() == SyntaxKind::MACRO_CALL)?;
1799            Some((source.text_range(), scope, id))
1800        })
1801        .filter(|(expr_range, _scope, _expr)| {
1802            expr_range.start() <= offset && offset <= expr_range.end()
1803        })
1804        // find containing scope
1805        .min_by_key(|(expr_range, _scope, _expr)| expr_range.len())
1806        .map(|(expr_range, scope, expr)| {
1807            adjust(db, scopes, source_map, expr_range, from_file, offset).unwrap_or((*scope, expr))
1808        })
1809}
1810
1811// XXX: during completion, cursor might be outside of any particular
1812// expression. Try to figure out the correct scope...
1813fn adjust(
1814    db: &dyn HirDatabase,
1815    scopes: &ExprScopes,
1816    source_map: &ExpressionStoreSourceMap,
1817    expr_range: TextRange,
1818    from_file: HirFileId,
1819    offset: TextSize,
1820) -> Option<(ScopeId, ExprId)> {
1821    let child_scopes = scopes
1822        .scope_by_expr()
1823        .iter()
1824        .filter_map(|(id, scope)| {
1825            let source = source_map.expr_syntax(id).ok()?;
1826            // FIXME: correctly handle macro expansion
1827            if source.file_id != from_file {
1828                return None;
1829            }
1830            let root = source.file_syntax(db);
1831            let node = source.value.to_node(&root);
1832            Some((node.syntax().text_range(), scope, id))
1833        })
1834        .filter(|&(range, _, _)| {
1835            range.start() <= offset && expr_range.contains_range(range) && range != expr_range
1836        });
1837
1838    child_scopes
1839        .max_by(|&(r1, _, _), &(r2, _, _)| {
1840            if r1.contains_range(r2) {
1841                std::cmp::Ordering::Greater
1842            } else if r2.contains_range(r1) {
1843                std::cmp::Ordering::Less
1844            } else {
1845                r1.start().cmp(&r2.start())
1846            }
1847        })
1848        .map(|(_ptr, scope, expr)| (*scope, expr))
1849}
1850
1851#[inline]
1852pub(crate) fn resolve_hir_path<'db>(
1853    db: &'db dyn HirDatabase,
1854    resolver: &Resolver<'db>,
1855    infer_body: Option<InferBodyId<'db>>,
1856    path: &Path,
1857    hygiene: HygieneId,
1858    store: Option<&ExpressionStore>,
1859) -> Option<PathResolution<'db>> {
1860    resolve_hir_path_(db, resolver, infer_body, path, false, hygiene, store, false).any()
1861}
1862
1863#[inline]
1864pub(crate) fn resolve_hir_path_as_attr_macro(
1865    db: &dyn HirDatabase,
1866    resolver: &Resolver<'_>,
1867    path: &Path,
1868) -> Option<Macro> {
1869    resolver
1870        .resolve_path_as_macro(db, path.mod_path()?, Some(MacroSubNs::Attr))
1871        .map(|it| it.def)
1872        .map(Into::into)
1873}
1874
1875fn resolve_hir_path_<'db>(
1876    db: &'db dyn HirDatabase,
1877    resolver: &Resolver<'db>,
1878    infer_body: Option<InferBodyId<'db>>,
1879    path: &Path,
1880    prefer_value_ns: bool,
1881    hygiene: HygieneId,
1882    store: Option<&ExpressionStore>,
1883    resolve_per_ns: bool,
1884) -> PathResolutionPerNs<'db> {
1885    let types = || {
1886        let (ty, unresolved, ty_is_visible) = match path.type_anchor() {
1887            Some(type_ref) => resolver.generic_def().and_then(|def| {
1888                let generics = OnceCell::new();
1889                let (_, res) = TyLoweringContext::new(
1890                    db,
1891                    resolver,
1892                    store?,
1893                    def.into(),
1894                    def,
1895                    &generics,
1896                    LifetimeElisionKind::Infer,
1897                    LifetimeLoweringMode::LateParam,
1898                )
1899                .lower_ty_ext(type_ref);
1900                res.map(|ty_ns| (ty_ns, path.segments().first(), Visibility::Public))
1901            }),
1902            None => {
1903                let (ty, remaining_idx, _, _, vis) =
1904                    resolver.resolve_path_in_type_ns_with_prefix_info(db, path)?;
1905                match remaining_idx {
1906                    Some(remaining_idx) => {
1907                        if remaining_idx + 1 == path.segments().len() {
1908                            Some((ty, path.segments().last(), vis))
1909                        } else {
1910                            None
1911                        }
1912                    }
1913                    None => Some((ty, None, vis)),
1914                }
1915            }
1916        }?;
1917
1918        // If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
1919        // within the trait's associated types.
1920        if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty)
1921            && let Some(type_alias_id) =
1922                trait_id.trait_items(db).associated_type_by_name(unresolved.name)
1923        {
1924            return Some((
1925                PathResolution::Def(ModuleDefId::from(type_alias_id).into()),
1926                ty_is_visible,
1927            ));
1928        }
1929
1930        let res = match ty {
1931            TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
1932            TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
1933            TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
1934                PathResolution::Def(Adt::from(it).into())
1935            }
1936            TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
1937            TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
1938            TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
1939            TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
1940            TypeNs::ModuleId(it) => PathResolution::Def(ModuleDef::Module(it.into())),
1941        };
1942        match unresolved {
1943            Some(unresolved) => resolver
1944                .generic_def()
1945                .and_then(|def| {
1946                    hir_ty::associated_type_shorthand_candidates(
1947                        db,
1948                        def,
1949                        res.in_type_ns()?,
1950                        |name, _| name == unresolved.name,
1951                    )
1952                })
1953                .map(TypeAlias::from)
1954                .map(Into::into)
1955                .map(|def| (PathResolution::Def(def), ty_is_visible)),
1956            None => Some((res, ty_is_visible)),
1957        }
1958    };
1959
1960    let body_owner = resolver.expression_store_owner();
1961    let values = || resolve_hir_value_path(db, resolver, body_owner, infer_body, path, hygiene);
1962
1963    let items = || {
1964        resolver
1965            .resolve_module_path_in_items(db, path.mod_path()?)
1966            .take_types_full()
1967            .map(|it| (PathResolution::Def(it.def.into()), it.vis))
1968    };
1969
1970    let macros = || {
1971        resolver
1972            .resolve_path_as_macro(db, path.mod_path()?, None)
1973            .map(|res| (PathResolution::Def(ModuleDef::Macro(res.def.into())), res.vis))
1974    };
1975
1976    let mut types_ns: Option<Option<_>> = None;
1977    let mut values_ns: Option<Option<_>> = None;
1978
1979    let mut types_is_visible: Option<bool> = None;
1980    let mut values_is_visible: Option<bool> = None;
1981
1982    if !resolve_per_ns {
1983        if prefer_value_ns {
1984            values_ns = Some(values().inspect(|(_, vis)| {
1985                values_is_visible = Some(resolver.is_visible(db, *vis));
1986            }));
1987
1988            if let Some(Some((res, _))) = values_ns
1989                && values_is_visible.unwrap_or_default()
1990            {
1991                return PathResolutionPerNs::new(None, Some(res), None);
1992            }
1993        } else {
1994            types_ns = Some(types().or_else(items).inspect(|(_, vis)| {
1995                types_is_visible = Some(resolver.is_visible(db, *vis));
1996            }));
1997
1998            if let Some(Some((res, _))) = types_ns
1999                && types_is_visible.unwrap_or_default()
2000            {
2001                return PathResolutionPerNs::new(Some(res), None, None);
2002            }
2003        }
2004    }
2005
2006    let mut macros_is_visible = false;
2007
2008    let mut types = types_ns.unwrap_or_else(|| types().or_else(items)).map(|(res, vis)| {
2009        types_is_visible = Some(types_is_visible.unwrap_or_else(|| resolver.is_visible(db, vis)));
2010        res
2011    });
2012    let mut values = values_ns.unwrap_or_else(values).map(|(res, vis)| {
2013        values_is_visible = Some(values_is_visible.unwrap_or_else(|| resolver.is_visible(db, vis)));
2014        res
2015    });
2016    let mut macros = macros().map(|(res, vis)| {
2017        macros_is_visible = resolver.is_visible(db, vis);
2018        res
2019    });
2020
2021    let types_is_visible = types_is_visible.unwrap_or_default();
2022    let values_is_visible = values_is_visible.unwrap_or_default();
2023
2024    // If there is a visible resolution and an invisible one, we only want to include the visible one. But if all are
2025    // invisible, we want to include them all.
2026    if types_is_visible || values_is_visible || macros_is_visible {
2027        if !types_is_visible {
2028            types = None;
2029        }
2030        if !values_is_visible {
2031            values = None;
2032        }
2033        if !macros_is_visible {
2034            macros = None;
2035        }
2036    }
2037
2038    PathResolutionPerNs { type_ns: types, value_ns: values, macro_ns: macros }
2039}
2040
2041fn resolve_hir_value_path<'db>(
2042    db: &'db dyn HirDatabase,
2043    resolver: &Resolver<'db>,
2044    store_owner: Option<ExpressionStoreOwnerId>,
2045    infer_body: Option<InferBodyId<'db>>,
2046    path: &Path,
2047    hygiene: HygieneId,
2048) -> Option<(PathResolution<'db>, Visibility)> {
2049    resolver.resolve_path_in_value_ns_with_prefix_info(db, path, hygiene).and_then(
2050        |(val, _, vis)| {
2051            let ResolveValueResult::ValueNs(val) = val else { return None };
2052            let res = match val {
2053                ValueNs::LocalBinding(binding_id) => {
2054                    let var = Local { parent: store_owner?, parent_infer: infer_body?, binding_id };
2055                    PathResolution::Local(var)
2056                }
2057                ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
2058                ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
2059                ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
2060                ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
2061                ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
2062                ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()),
2063                ValueNs::GenericParam(id) => PathResolution::ConstParam(id.into()),
2064            };
2065            Some((res, vis))
2066        },
2067    )
2068}
2069
2070/// Resolves a path where we know it is a qualifier of another path.
2071///
2072/// For example, if we have:
2073/// ```
2074/// mod my {
2075///     pub mod foo {
2076///         struct Bar;
2077///     }
2078///
2079///     pub fn foo() {}
2080/// }
2081/// ```
2082/// then we know that `foo` in `my::foo::Bar` refers to the module, not the function.
2083fn resolve_hir_path_qualifier<'db>(
2084    db: &'db dyn HirDatabase,
2085    resolver: &Resolver<'db>,
2086    path: &Path,
2087    store: &ExpressionStore,
2088) -> Option<PathResolution<'db>> {
2089    (|| {
2090        let (ty, unresolved) = match path.type_anchor() {
2091            Some(type_ref) => resolver.generic_def().and_then(|def| {
2092                let generics = OnceCell::new();
2093                let (_, res) = TyLoweringContext::new(
2094                    db,
2095                    resolver,
2096                    store,
2097                    def.into(),
2098                    def,
2099                    &generics,
2100                    LifetimeElisionKind::Infer,
2101                    LifetimeLoweringMode::LateParam,
2102                )
2103                .lower_ty_ext(type_ref);
2104                res.map(|ty_ns| (ty_ns, path.segments().first()))
2105            }),
2106            None => {
2107                let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db, path)?;
2108                match remaining_idx {
2109                    Some(remaining_idx) => {
2110                        if remaining_idx + 1 == path.segments().len() {
2111                            Some((ty, path.segments().last()))
2112                        } else {
2113                            None
2114                        }
2115                    }
2116                    None => Some((ty, None)),
2117                }
2118            }
2119        }?;
2120
2121        // If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
2122        // within the trait's associated types.
2123        if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty)
2124            && let Some(type_alias_id) =
2125                trait_id.trait_items(db).associated_type_by_name(unresolved.name)
2126        {
2127            return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
2128        }
2129
2130        let res = match ty {
2131            TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
2132            TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
2133            TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
2134                PathResolution::Def(Adt::from(it).into())
2135            }
2136            TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
2137            TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
2138            TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
2139            TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
2140            TypeNs::ModuleId(it) => PathResolution::Def(ModuleDef::Module(it.into())),
2141        };
2142        match unresolved {
2143            Some(unresolved) => resolver
2144                .generic_def()
2145                .and_then(|def| {
2146                    hir_ty::associated_type_shorthand_candidates(
2147                        db,
2148                        def,
2149                        res.in_type_ns()?,
2150                        |name, _| name == unresolved.name,
2151                    )
2152                })
2153                .map(TypeAlias::from)
2154                .map(Into::into)
2155                .map(PathResolution::Def),
2156            None => Some(res),
2157        }
2158    })()
2159    .or_else(|| {
2160        resolver
2161            .resolve_module_path_in_items(db, path.mod_path()?)
2162            .take_types()
2163            .map(|it| PathResolution::Def(it.into()))
2164    })
2165}
2166
2167pub(crate) fn name_hygiene(db: &dyn HirDatabase, name: InFile<&SyntaxNode>) -> HygieneId {
2168    let Some(macro_file) = name.file_id.macro_file() else {
2169        return HygieneId::ROOT;
2170    };
2171    let span_map = macro_file.expansion_span_map(db);
2172    let ctx = span_map.span_at(name.value.text_range().start()).ctx;
2173    HygieneId::new(ctx.opaque_and_semiopaque(db))
2174}
2175
2176fn record_literal_matched_fields(
2177    db: &dyn HirDatabase,
2178    infer: &InferenceResult<'_>,
2179    id: ExprId,
2180    expr: &Expr,
2181) -> Option<(VariantId, Vec<LocalFieldId>)> {
2182    let (fields, _spread) = match expr {
2183        Expr::RecordLit { fields, spread, .. } => (fields, spread),
2184        _ => return None,
2185    };
2186
2187    let variant_def = infer.variant_resolution_for_expr(id)?;
2188    if let VariantId::UnionId(_) = variant_def {
2189        return None;
2190    }
2191
2192    let variant_data = variant_def.fields(db);
2193
2194    let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
2195    // suggest fields if:
2196    // - not in code
2197    let matched_fields: Vec<LocalFieldId> = variant_data
2198        .fields()
2199        .iter()
2200        .filter_map(|(f, d)| (!specified_fields.contains(&d.name)).then_some(f))
2201        .collect();
2202    if matched_fields.is_empty() {
2203        return None;
2204    }
2205    Some((variant_def, matched_fields))
2206}
2207
2208fn record_pattern_matched_fields(
2209    db: &dyn HirDatabase,
2210    infer: &InferenceResult<'_>,
2211    id: PatId,
2212    pat: &Pat,
2213) -> Option<(VariantId, Vec<LocalFieldId>)> {
2214    let (fields, _ellipsis) = match pat {
2215        Pat::Record { path: _, args, ellipsis } => (args, *ellipsis),
2216        _ => return None,
2217    };
2218
2219    let variant_def = infer.variant_resolution_for_pat(id)?;
2220    if let VariantId::UnionId(_) = variant_def {
2221        return None;
2222    }
2223
2224    let variant_data = variant_def.fields(db);
2225
2226    let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
2227    // suggest fields if:
2228    // - not in code
2229    let matched_fields: Vec<LocalFieldId> = variant_data
2230        .fields()
2231        .iter()
2232        .filter_map(|(f, d)| if !specified_fields.contains(&d.name) { Some(f) } else { None })
2233        .collect();
2234    if matched_fields.is_empty() {
2235        return None;
2236    }
2237    Some((variant_def, matched_fields))
2238}