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