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