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