Skip to main content

hir/
source_analyzer.rs

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