ide/
goto_definition.rs

1use std::{iter, mem::discriminant};
2
3use crate::Analysis;
4use crate::{
5    FilePosition, NavigationTarget, RangeInfo, TryToNav, UpmappingResult,
6    doc_links::token_as_doc_comment,
7    navigation_target::{self, ToNav},
8};
9use hir::{
10    AsAssocItem, AssocItem, CallableKind, FileRange, HasCrate, InFile, ModuleDef, Semantics, sym,
11};
12use ide_db::{MiniCore, ra_fixture::UpmapFromRaFixture};
13use ide_db::{
14    RootDatabase, SymbolKind,
15    base_db::{AnchoredPath, SourceDatabase},
16    defs::{Definition, IdentClass},
17    famous_defs::FamousDefs,
18    helpers::pick_best_token,
19    syntax_helpers::node_ext::find_loops,
20};
21use itertools::Itertools;
22use span::FileId;
23use syntax::{
24    AstNode, AstToken, SyntaxKind::*, SyntaxNode, SyntaxToken, T, TextRange, ast, match_ast,
25};
26
27#[derive(Debug)]
28pub struct GotoDefinitionConfig<'a> {
29    pub minicore: MiniCore<'a>,
30}
31
32// Feature: Go to Definition
33//
34// Navigates to the definition of an identifier.
35//
36// For outline modules, this will navigate to the source file of the module.
37//
38// | Editor  | Shortcut |
39// |---------|----------|
40// | VS Code | <kbd>F12</kbd> |
41//
42// ![Go to Definition](https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif)
43pub(crate) fn goto_definition(
44    db: &RootDatabase,
45    FilePosition { file_id, offset }: FilePosition,
46    config: &GotoDefinitionConfig<'_>,
47) -> Option<RangeInfo<Vec<NavigationTarget>>> {
48    let sema = &Semantics::new(db);
49    let file = sema.parse_guess_edition(file_id).syntax().clone();
50    let edition = sema.attach_first_edition(file_id).edition(db);
51    let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
52        IDENT
53        | INT_NUMBER
54        | LIFETIME_IDENT
55        | T![self]
56        | T![super]
57        | T![crate]
58        | T![Self]
59        | COMMENT => 4,
60        // index and prefix ops
61        T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
62        kind if kind.is_keyword(edition) => 2,
63        T!['('] | T![')'] => 2,
64        kind if kind.is_trivia() => 0,
65        _ => 1,
66    })?;
67    if let Some(doc_comment) = token_as_doc_comment(&original_token) {
68        return doc_comment.get_definition_with_descend_at(sema, offset, |def, _, link_range| {
69            let nav = def.try_to_nav(sema)?;
70            Some(RangeInfo::new(link_range, nav.collect()))
71        });
72    }
73
74    if let Some((range, _, _, resolution)) =
75        sema.check_for_format_args_template(original_token.clone(), offset)
76    {
77        return Some(RangeInfo::new(
78            range,
79            match resolution {
80                Some(res) => def_to_nav(sema, Definition::from(res)),
81                None => vec![],
82            },
83        ));
84    }
85
86    if let Some(navs) = handle_control_flow_keywords(sema, &original_token) {
87        return Some(RangeInfo::new(original_token.text_range(), navs));
88    }
89
90    let tokens = sema.descend_into_macros_no_opaque(original_token.clone(), false);
91    let mut navs = Vec::new();
92    for token in tokens {
93        if let Some(n) = find_definition_for_known_blanket_dual_impls(sema, &token.value) {
94            navs.extend(n);
95            continue;
96        }
97
98        let parent = token.value.parent()?;
99
100        if let Some(question_mark_conversion) = goto_question_mark_conversions(sema, &parent) {
101            navs.extend(def_to_nav(sema, question_mark_conversion.into()));
102            continue;
103        }
104
105        if let Some(token) = ast::String::cast(token.value.clone())
106            && let Some(original_token) = ast::String::cast(original_token.clone())
107            && let Some((analysis, fixture_analysis)) =
108                Analysis::from_ra_fixture(sema, original_token, &token, config.minicore)
109            && let Some((virtual_file_id, file_offset)) = fixture_analysis.map_offset_down(offset)
110        {
111            return hir::attach_db_allow_change(&analysis.db, || {
112                goto_definition(
113                    &analysis.db,
114                    FilePosition { file_id: virtual_file_id, offset: file_offset },
115                    config,
116                )
117            })
118            .and_then(|navs| {
119                navs.upmap_from_ra_fixture(&fixture_analysis, virtual_file_id, file_id).ok()
120            });
121        }
122
123        let token_file_id = token.file_id;
124        if let Some(token) = ast::String::cast(token.value.clone())
125            && let Some(x) =
126                try_lookup_include_path(sema, InFile::new(token_file_id, token), file_id)
127        {
128            navs.push(x);
129            continue;
130        }
131
132        if ast::TokenTree::can_cast(parent.kind())
133            && let Some(x) = try_lookup_macro_def_in_macro_use(sema, token.value)
134        {
135            navs.push(x);
136            continue;
137        }
138
139        let Some(ident_class) = IdentClass::classify_node(sema, &parent) else { continue };
140        navs.extend(ident_class.definitions().into_iter().flat_map(|(def, _)| {
141            if let Definition::ExternCrateDecl(crate_def) = def {
142                return crate_def
143                    .resolved_crate(db)
144                    .map(|it| it.root_module(db).to_nav(db))
145                    .into_iter()
146                    .flatten()
147                    .collect();
148            }
149            try_filter_trait_item_definition(sema, &def).unwrap_or_else(|| def_to_nav(sema, def))
150        }));
151    }
152    let navs = navs.into_iter().unique().collect();
153
154    Some(RangeInfo::new(original_token.text_range(), navs))
155}
156
157/// When the `?` operator is used on `Result`, go to the `From` impl if it exists as this provides more value.
158fn goto_question_mark_conversions(
159    sema: &Semantics<'_, RootDatabase>,
160    node: &SyntaxNode,
161) -> Option<hir::Function> {
162    let node = ast::TryExpr::cast(node.clone())?;
163    let try_expr_ty = sema.type_of_expr(&node.expr()?)?.adjusted();
164
165    let fd = FamousDefs(sema, try_expr_ty.krate(sema.db));
166    let result_enum = fd.core_result_Result()?.into();
167
168    let (try_expr_ty_adt, try_expr_ty_args) = try_expr_ty.as_adt_with_args()?;
169    if try_expr_ty_adt != result_enum {
170        // FIXME: Support `Poll<Result>`.
171        return None;
172    }
173    let original_err_ty = try_expr_ty_args.get(1)?.clone()?;
174
175    let returned_ty = sema.try_expr_returned_type(&node)?;
176    let (returned_adt, returned_ty_args) = returned_ty.as_adt_with_args()?;
177    if returned_adt != result_enum {
178        return None;
179    }
180    let returned_err_ty = returned_ty_args.get(1)?.clone()?;
181
182    if returned_err_ty.could_unify_with_deeply(sema.db, &original_err_ty) {
183        return None;
184    }
185
186    let from_trait = fd.core_convert_From()?;
187    let from_fn = from_trait.function(sema.db, sym::from)?;
188    sema.resolve_trait_impl_method(
189        returned_err_ty.clone(),
190        from_trait,
191        from_fn,
192        [returned_err_ty, original_err_ty],
193    )
194}
195
196// If the token is into(), try_into(), search the definition of From, TryFrom.
197fn find_definition_for_known_blanket_dual_impls(
198    sema: &Semantics<'_, RootDatabase>,
199    original_token: &SyntaxToken,
200) -> Option<Vec<NavigationTarget>> {
201    let method_call = ast::MethodCallExpr::cast(original_token.parent()?.parent()?)?;
202    let callable = sema.resolve_method_call_as_callable(&method_call)?;
203    let CallableKind::Function(f) = callable.kind() else { return None };
204    let assoc = f.as_assoc_item(sema.db)?;
205
206    let return_type = callable.return_type();
207    let fd = FamousDefs(sema, return_type.krate(sema.db));
208
209    let t = match assoc.container(sema.db) {
210        hir::AssocItemContainer::Trait(t) => t,
211        hir::AssocItemContainer::Impl(impl_)
212            if impl_.self_ty(sema.db).is_str() && f.name(sema.db) == sym::parse =>
213        {
214            let t = fd.core_convert_FromStr()?;
215            let t_f = t.function(sema.db, &sym::from_str)?;
216            return sema
217                .resolve_trait_impl_method(
218                    return_type.clone(),
219                    t,
220                    t_f,
221                    [return_type.type_arguments().next()?],
222                )
223                .map(|f| def_to_nav(sema, f.into()));
224        }
225        hir::AssocItemContainer::Impl(_) => return None,
226    };
227
228    let fn_name = f.name(sema.db);
229    let f = if fn_name == sym::into && fd.core_convert_Into() == Some(t) {
230        let dual = fd.core_convert_From()?;
231        let dual_f = dual.function(sema.db, &sym::from)?;
232        sema.resolve_trait_impl_method(
233            return_type.clone(),
234            dual,
235            dual_f,
236            [return_type, callable.receiver_param(sema.db)?.1],
237        )?
238    } else if fn_name == sym::try_into && fd.core_convert_TryInto() == Some(t) {
239        let dual = fd.core_convert_TryFrom()?;
240        let dual_f = dual.function(sema.db, &sym::try_from)?;
241        sema.resolve_trait_impl_method(
242            return_type.clone(),
243            dual,
244            dual_f,
245            // Extract the `T` from `Result<T, ..>`
246            [return_type.type_arguments().next()?, callable.receiver_param(sema.db)?.1],
247        )?
248    } else if fn_name == sym::to_string && fd.alloc_string_ToString() == Some(t) {
249        let dual = fd.core_fmt_Display()?;
250        let dual_f = dual.function(sema.db, &sym::fmt)?;
251        sema.resolve_trait_impl_method(
252            return_type.clone(),
253            dual,
254            dual_f,
255            [callable.receiver_param(sema.db)?.1.strip_reference()],
256        )?
257    } else {
258        return None;
259    };
260    // Assert that we got a trait impl function, if we are back in a trait definition we didn't
261    // succeed
262    let _t = f.as_assoc_item(sema.db)?.implemented_trait(sema.db)?;
263    let def = Definition::from(f);
264    Some(def_to_nav(sema, def))
265}
266
267fn try_lookup_include_path(
268    sema: &Semantics<'_, RootDatabase>,
269    token: InFile<ast::String>,
270    file_id: FileId,
271) -> Option<NavigationTarget> {
272    let file = token.file_id.macro_file()?;
273
274    // Check that we are in the eager argument expansion of an include macro
275    // that is we are the string input of it
276    if !iter::successors(Some(file), |file| file.parent(sema.db).macro_file())
277        .any(|file| file.is_include_like_macro(sema.db) && file.eager_arg(sema.db).is_none())
278    {
279        return None;
280    }
281    let path = token.value.value().ok()?;
282
283    let file_id = sema.db.resolve_path(AnchoredPath { anchor: file_id, path: &path })?;
284    let size = sema.db.file_text(file_id).text(sema.db).len().try_into().ok()?;
285    Some(NavigationTarget {
286        file_id,
287        full_range: TextRange::new(0.into(), size),
288        name: hir::Symbol::intern(&path),
289        alias: None,
290        focus_range: None,
291        kind: None,
292        container_name: None,
293        description: None,
294        docs: None,
295    })
296}
297
298fn try_lookup_macro_def_in_macro_use(
299    sema: &Semantics<'_, RootDatabase>,
300    token: SyntaxToken,
301) -> Option<NavigationTarget> {
302    let extern_crate = token.parent()?.ancestors().find_map(ast::ExternCrate::cast)?;
303    let extern_crate = sema.to_def(&extern_crate)?;
304    let krate = extern_crate.resolved_crate(sema.db)?;
305
306    for mod_def in krate.root_module(sema.db).declarations(sema.db) {
307        if let ModuleDef::Macro(mac) = mod_def
308            && mac.name(sema.db).as_str() == token.text()
309            && let Some(nav) = mac.try_to_nav(sema)
310        {
311            return Some(nav.call_site);
312        }
313    }
314
315    None
316}
317
318/// finds the trait definition of an impl'd item, except function
319/// e.g.
320/// ```rust
321/// trait A { type a; }
322/// struct S;
323/// impl A for S { type a = i32; } // <-- on this associate type, will get the location of a in the trait
324/// ```
325fn try_filter_trait_item_definition(
326    sema: &Semantics<'_, RootDatabase>,
327    def: &Definition,
328) -> Option<Vec<NavigationTarget>> {
329    let db = sema.db;
330    let assoc = def.as_assoc_item(db)?;
331    match assoc {
332        AssocItem::Function(..) => None,
333        AssocItem::Const(..) | AssocItem::TypeAlias(..) => {
334            let trait_ = assoc.implemented_trait(db)?;
335            let name = def.name(db)?;
336            let discriminant_value = discriminant(&assoc);
337            trait_
338                .items(db)
339                .iter()
340                .filter(|itm| discriminant(*itm) == discriminant_value)
341                .find_map(|itm| (itm.name(db)? == name).then(|| itm.try_to_nav(sema)).flatten())
342                .map(|it| it.collect())
343        }
344    }
345}
346
347fn handle_control_flow_keywords(
348    sema: &Semantics<'_, RootDatabase>,
349    token: &SyntaxToken,
350) -> Option<Vec<NavigationTarget>> {
351    match token.kind() {
352        // For `fn` / `loop` / `while` / `for` / `async` / `match`, return the keyword it self,
353        // so that VSCode will find the references when using `ctrl + click`
354        T![fn] | T![async] | T![try] | T![return] => nav_for_exit_points(sema, token),
355        T![loop] | T![while] | T![break] | T![continue] => nav_for_break_points(sema, token),
356        T![for] if token.parent().and_then(ast::ForExpr::cast).is_some() => {
357            nav_for_break_points(sema, token)
358        }
359        T![match] | T![=>] | T![if] => nav_for_branch_exit_points(sema, token),
360        _ => None,
361    }
362}
363
364pub(crate) fn find_fn_or_blocks(
365    sema: &Semantics<'_, RootDatabase>,
366    token: &SyntaxToken,
367) -> Vec<SyntaxNode> {
368    let find_ancestors = |token: SyntaxToken| {
369        let token_kind = token.kind();
370
371        for anc in sema.token_ancestors_with_macros(token) {
372            let node = match_ast! {
373                match anc {
374                    ast::Fn(fn_) => fn_.syntax().clone(),
375                    ast::ClosureExpr(c) => c.syntax().clone(),
376                    ast::BlockExpr(blk) => {
377                        match blk.modifier() {
378                            Some(ast::BlockModifier::Async(_)) => blk.syntax().clone(),
379                            Some(ast::BlockModifier::Try { .. }) if token_kind != T![return] => blk.syntax().clone(),
380                            _ => continue,
381                        }
382                    },
383                    _ => continue,
384                }
385            };
386
387            return Some(node);
388        }
389        None
390    };
391
392    sema.descend_into_macros(token.clone()).into_iter().filter_map(find_ancestors).collect_vec()
393}
394
395fn nav_for_exit_points(
396    sema: &Semantics<'_, RootDatabase>,
397    token: &SyntaxToken,
398) -> Option<Vec<NavigationTarget>> {
399    let db = sema.db;
400    let token_kind = token.kind();
401
402    let navs = find_fn_or_blocks(sema, token)
403        .into_iter()
404        .filter_map(|node| {
405            let file_id = sema.hir_file_for(&node);
406
407            match_ast! {
408                match node {
409                    ast::Fn(fn_) => {
410                        let mut nav = sema.to_def(&fn_)?.try_to_nav(sema)?;
411                        // For async token, we navigate to itself, which triggers
412                        // VSCode to find the references
413                        let focus_token = if matches!(token_kind, T![async]) {
414                            fn_.async_token()?
415                        } else {
416                            fn_.fn_token()?
417                        };
418
419                        let focus_frange = InFile::new(file_id, focus_token.text_range())
420                            .original_node_file_range_opt(db)
421                            .map(|(frange, _)| frange);
422
423                        if let Some(FileRange { file_id, range }) = focus_frange {
424                            let contains_frange = |nav: &NavigationTarget| {
425                                nav.file_id == file_id.file_id(db) && nav.full_range.contains_range(range)
426                            };
427
428                            if let Some(def_site) = nav.def_site.as_mut() {
429                                if contains_frange(def_site) {
430                                    def_site.focus_range = Some(range);
431                                }
432                            } else if contains_frange(&nav.call_site) {
433                                nav.call_site.focus_range = Some(range);
434                            }
435                        }
436
437                        Some(nav)
438                    },
439                    ast::ClosureExpr(c) => {
440                        let pipe_tok = c.param_list().and_then(|it| it.pipe_token())?.text_range();
441                        let closure_in_file = InFile::new(file_id, c.into());
442                        Some(expr_to_nav(db, closure_in_file, Some(pipe_tok)))
443                    },
444                    ast::BlockExpr(blk) => {
445                        match blk.modifier() {
446                            Some(ast::BlockModifier::Async(_)) => {
447                                let async_tok = blk.async_token()?.text_range();
448                                let blk_in_file = InFile::new(file_id, blk.into());
449                                Some(expr_to_nav(db, blk_in_file, Some(async_tok)))
450                            },
451                            Some(ast::BlockModifier::Try { .. }) if token_kind != T![return] => {
452                                let try_tok = blk.try_block_modifier()?.try_token()?.text_range();
453                                let blk_in_file = InFile::new(file_id, blk.into());
454                                Some(expr_to_nav(db, blk_in_file, Some(try_tok)))
455                            },
456                            _ => None,
457                        }
458                    },
459                    _ => None,
460                }
461            }
462        })
463        .flatten()
464        .collect_vec();
465
466    Some(navs)
467}
468
469pub(crate) fn find_branch_root(
470    sema: &Semantics<'_, RootDatabase>,
471    token: &SyntaxToken,
472) -> Vec<SyntaxNode> {
473    let find_nodes = |node_filter: fn(SyntaxNode) -> Option<SyntaxNode>| {
474        sema.descend_into_macros(token.clone())
475            .into_iter()
476            .filter_map(|token| node_filter(token.parent()?))
477            .collect_vec()
478    };
479
480    match token.kind() {
481        T![match] => find_nodes(|node| Some(ast::MatchExpr::cast(node)?.syntax().clone())),
482        T![=>] => find_nodes(|node| Some(ast::MatchArm::cast(node)?.syntax().clone())),
483        T![if] => find_nodes(|node| {
484            let if_expr = ast::IfExpr::cast(node)?;
485
486            let root_if = iter::successors(Some(if_expr.clone()), |if_expr| {
487                let parent_if = if_expr.syntax().parent().and_then(ast::IfExpr::cast)?;
488                let ast::ElseBranch::IfExpr(else_branch) = parent_if.else_branch()? else {
489                    return None;
490                };
491
492                (else_branch.syntax() == if_expr.syntax()).then_some(parent_if)
493            })
494            .last()?;
495
496            Some(root_if.syntax().clone())
497        }),
498        _ => vec![],
499    }
500}
501
502fn nav_for_branch_exit_points(
503    sema: &Semantics<'_, RootDatabase>,
504    token: &SyntaxToken,
505) -> Option<Vec<NavigationTarget>> {
506    let db = sema.db;
507
508    let navs = match token.kind() {
509        T![match] => find_branch_root(sema, token)
510            .into_iter()
511            .filter_map(|node| {
512                let file_id = sema.hir_file_for(&node);
513                let match_expr = ast::MatchExpr::cast(node)?;
514                let focus_range = match_expr.match_token()?.text_range();
515                let match_expr_in_file = InFile::new(file_id, match_expr.into());
516                Some(expr_to_nav(db, match_expr_in_file, Some(focus_range)))
517            })
518            .flatten()
519            .collect_vec(),
520
521        T![=>] => find_branch_root(sema, token)
522            .into_iter()
523            .filter_map(|node| {
524                let match_arm = ast::MatchArm::cast(node)?;
525                let match_expr = sema
526                    .ancestors_with_macros(match_arm.syntax().clone())
527                    .find_map(ast::MatchExpr::cast)?;
528                let file_id = sema.hir_file_for(match_expr.syntax());
529                let focus_range = match_arm.fat_arrow_token()?.text_range();
530                let match_expr_in_file = InFile::new(file_id, match_expr.into());
531                Some(expr_to_nav(db, match_expr_in_file, Some(focus_range)))
532            })
533            .flatten()
534            .collect_vec(),
535
536        T![if] => find_branch_root(sema, token)
537            .into_iter()
538            .filter_map(|node| {
539                let file_id = sema.hir_file_for(&node);
540                let if_expr = ast::IfExpr::cast(node)?;
541                let focus_range = if_expr.if_token()?.text_range();
542                let if_expr_in_file = InFile::new(file_id, if_expr.into());
543                Some(expr_to_nav(db, if_expr_in_file, Some(focus_range)))
544            })
545            .flatten()
546            .collect_vec(),
547
548        _ => return Some(Vec::new()),
549    };
550
551    Some(navs)
552}
553
554fn nav_for_break_points(
555    sema: &Semantics<'_, RootDatabase>,
556    token: &SyntaxToken,
557) -> Option<Vec<NavigationTarget>> {
558    let db = sema.db;
559
560    let navs = find_loops(sema, token)?
561        .filter_map(|expr| {
562            let file_id = sema.hir_file_for(expr.syntax());
563            let expr_in_file = InFile::new(file_id, expr.clone());
564            let focus_range = match expr {
565                ast::Expr::LoopExpr(loop_) => loop_.loop_token()?.text_range(),
566                ast::Expr::WhileExpr(while_) => while_.while_token()?.text_range(),
567                ast::Expr::ForExpr(for_) => for_.for_token()?.text_range(),
568                // We guarantee that the label exists
569                ast::Expr::BlockExpr(blk) => blk.label().unwrap().syntax().text_range(),
570                _ => return None,
571            };
572            let nav = expr_to_nav(db, expr_in_file, Some(focus_range));
573            Some(nav)
574        })
575        .flatten()
576        .collect_vec();
577
578    Some(navs)
579}
580
581fn def_to_nav(sema: &Semantics<'_, RootDatabase>, def: Definition) -> Vec<NavigationTarget> {
582    def.try_to_nav(sema).map(|it| it.collect()).unwrap_or_default()
583}
584
585fn expr_to_nav(
586    db: &RootDatabase,
587    InFile { file_id, value }: InFile<ast::Expr>,
588    focus_range: Option<TextRange>,
589) -> UpmappingResult<NavigationTarget> {
590    let kind = SymbolKind::Label;
591
592    let value_range = value.syntax().text_range();
593    let navs = navigation_target::orig_range_with_focus_r(db, file_id, value_range, focus_range);
594    navs.map(|(hir::FileRangeWrapper { file_id, range }, focus_range)| {
595        NavigationTarget::from_syntax(
596            file_id,
597            hir::Symbol::intern("<expr>"),
598            focus_range,
599            range,
600            kind,
601        )
602    })
603}
604
605#[cfg(test)]
606mod tests {
607    use crate::{GotoDefinitionConfig, fixture};
608    use ide_db::{FileRange, MiniCore};
609    use itertools::Itertools;
610
611    const TEST_CONFIG: GotoDefinitionConfig<'_> =
612        GotoDefinitionConfig { minicore: MiniCore::default() };
613
614    #[track_caller]
615    fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
616        let (analysis, position, expected) = fixture::annotations(ra_fixture);
617        let navs = analysis
618            .goto_definition(position, &TEST_CONFIG)
619            .unwrap()
620            .expect("no definition found")
621            .info;
622
623        let cmp = |&FileRange { file_id, range }: &_| (file_id, range.start());
624        let navs = navs
625            .into_iter()
626            .map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() })
627            .sorted_by_key(cmp)
628            .collect::<Vec<_>>();
629        let expected = expected
630            .into_iter()
631            .map(|(FileRange { file_id, range }, _)| FileRange { file_id, range })
632            .sorted_by_key(cmp)
633            .collect::<Vec<_>>();
634
635        assert_eq!(expected, navs);
636    }
637
638    fn check_unresolved(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
639        let (analysis, position) = fixture::position(ra_fixture);
640        let navs = analysis
641            .goto_definition(position, &TEST_CONFIG)
642            .unwrap()
643            .expect("no definition found")
644            .info;
645
646        assert!(navs.is_empty(), "didn't expect this to resolve anywhere: {navs:?}")
647    }
648
649    fn check_name(expected_name: &str, #[rust_analyzer::rust_fixture] ra_fixture: &str) {
650        let (analysis, position, _) = fixture::annotations(ra_fixture);
651        let navs = analysis
652            .goto_definition(position, &TEST_CONFIG)
653            .unwrap()
654            .expect("no definition found")
655            .info;
656        assert!(navs.len() < 2, "expected single navigation target but encountered {}", navs.len());
657        let Some(target) = navs.into_iter().next() else {
658            panic!("expected single navigation target but encountered none");
659        };
660        assert_eq!(target.name, hir::Symbol::intern(expected_name));
661    }
662
663    #[test]
664    fn goto_def_pat_range_to_inclusive() {
665        check_name(
666            "RangeToInclusive",
667            r#"
668//- minicore: range
669fn f(ch: char) -> bool {
670    match ch {
671        ..$0='z' => true,
672        _ => false
673    }
674}
675"#,
676        );
677    }
678
679    #[test]
680    fn goto_def_pat_range_to() {
681        check_name(
682            "RangeTo",
683            r#"
684//- minicore: range
685fn f(ch: char) -> bool {
686    match ch {
687        .$0.'z' => true,
688        _ => false
689    }
690}
691"#,
692        );
693    }
694
695    #[test]
696    fn goto_def_pat_range() {
697        check_name(
698            "Range",
699            r#"
700//- minicore: range
701fn f(ch: char) -> bool {
702    match ch {
703        'a'.$0.'z' => true,
704        _ => false
705    }
706}
707"#,
708        );
709    }
710
711    #[test]
712    fn goto_def_pat_range_inclusive() {
713        check_name(
714            "RangeInclusive",
715            r#"
716//- minicore: range
717fn f(ch: char) -> bool {
718    match ch {
719        'a'..$0='z' => true,
720        _ => false
721    }
722}
723"#,
724        );
725    }
726
727    #[test]
728    fn goto_def_pat_range_from() {
729        check_name(
730            "RangeFrom",
731            r#"
732//- minicore: range
733fn f(ch: char) -> bool {
734    match ch {
735        'a'..$0 => true,
736        _ => false
737    }
738}
739"#,
740        );
741    }
742
743    #[test]
744    fn goto_def_expr_range() {
745        check_name(
746            "Range",
747            r#"
748//- minicore: range
749let x = 0.$0.1;
750"#,
751        );
752    }
753
754    #[test]
755    fn goto_def_expr_range_from() {
756        check_name(
757            "RangeFrom",
758            r#"
759//- minicore: range
760fn f(arr: &[i32]) -> &[i32] {
761    &arr[0.$0.]
762}
763"#,
764        );
765    }
766
767    #[test]
768    fn goto_def_expr_range_inclusive() {
769        check_name(
770            "RangeInclusive",
771            r#"
772//- minicore: range
773let x = 0.$0.=1;
774"#,
775        );
776    }
777
778    #[test]
779    fn goto_def_expr_range_full() {
780        check_name(
781            "RangeFull",
782            r#"
783//- minicore: range
784fn f(arr: &[i32]) -> &[i32] {
785    &arr[.$0.]
786}
787"#,
788        );
789    }
790
791    #[test]
792    fn goto_def_expr_range_to() {
793        check_name(
794            "RangeTo",
795            r#"
796//- minicore: range
797fn f(arr: &[i32]) -> &[i32] {
798    &arr[.$0.10]
799}
800"#,
801        );
802    }
803
804    #[test]
805    fn goto_def_expr_range_to_inclusive() {
806        check_name(
807            "RangeToInclusive",
808            r#"
809//- minicore: range
810fn f(arr: &[i32]) -> &[i32] {
811    &arr[.$0.=10]
812}
813"#,
814        );
815    }
816
817    #[test]
818    fn goto_def_in_included_file() {
819        check(
820            r#"
821//- minicore:include
822//- /main.rs
823
824include!("a.rs");
825
826fn main() {
827    foo();
828}
829
830//- /a.rs
831fn func_in_include() {
832 //^^^^^^^^^^^^^^^
833}
834
835fn foo() {
836    func_in_include$0();
837}
838"#,
839        );
840    }
841
842    #[test]
843    fn goto_def_in_included_file_nested() {
844        check(
845            r#"
846//- minicore:include
847//- /main.rs
848
849macro_rules! passthrough {
850    ($($tt:tt)*) => { $($tt)* }
851}
852
853passthrough!(include!("a.rs"));
854
855fn main() {
856    foo();
857}
858
859//- /a.rs
860fn func_in_include() {
861 //^^^^^^^^^^^^^^^
862}
863
864fn foo() {
865    func_in_include$0();
866}
867"#,
868        );
869    }
870
871    #[test]
872    fn goto_def_in_included_file_inside_mod() {
873        check(
874            r#"
875//- minicore:include
876//- /main.rs
877mod a {
878    include!("b.rs");
879}
880//- /b.rs
881fn func_in_include() {
882 //^^^^^^^^^^^^^^^
883}
884fn foo() {
885    func_in_include$0();
886}
887"#,
888        );
889
890        check(
891            r#"
892//- minicore:include
893//- /main.rs
894mod a {
895    include!("a.rs");
896}
897//- /a.rs
898fn func_in_include() {
899 //^^^^^^^^^^^^^^^
900}
901
902fn foo() {
903    func_in_include$0();
904}
905"#,
906        );
907    }
908
909    #[test]
910    fn goto_def_if_items_same_name() {
911        check(
912            r#"
913trait Trait {
914    type A;
915    const A: i32;
916        //^
917}
918
919struct T;
920impl Trait for T {
921    type A = i32;
922    const A$0: i32 = -9;
923}"#,
924        );
925    }
926    #[test]
927    fn goto_def_in_mac_call_in_attr_invoc() {
928        check(
929            r#"
930//- proc_macros: identity
931pub struct Struct {
932        // ^^^^^^
933    field: i32,
934}
935
936macro_rules! identity {
937    ($($tt:tt)*) => {$($tt)*};
938}
939
940#[proc_macros::identity]
941fn function() {
942    identity!(Struct$0 { field: 0 });
943}
944
945"#,
946        )
947    }
948
949    #[test]
950    fn goto_def_for_extern_crate() {
951        check(
952            r#"
953//- /main.rs crate:main deps:std
954extern crate std$0;
955//- /std/lib.rs crate:std
956// empty
957//^file
958"#,
959        )
960    }
961
962    #[test]
963    fn goto_def_for_renamed_extern_crate() {
964        check(
965            r#"
966//- /main.rs crate:main deps:std
967extern crate std as abc$0;
968//- /std/lib.rs crate:std
969// empty
970//^file
971"#,
972        )
973    }
974
975    #[test]
976    fn goto_def_in_items() {
977        check(
978            r#"
979struct Foo;
980     //^^^
981enum E { X(Foo$0) }
982"#,
983        );
984    }
985
986    #[test]
987    fn goto_def_at_start_of_item() {
988        check(
989            r#"
990struct Foo;
991     //^^^
992enum E { X($0Foo) }
993"#,
994        );
995    }
996
997    #[test]
998    fn goto_definition_resolves_correct_name() {
999        check(
1000            r#"
1001//- /lib.rs
1002use a::Foo;
1003mod a;
1004mod b;
1005enum E { X(Foo$0) }
1006
1007//- /a.rs
1008pub struct Foo;
1009         //^^^
1010//- /b.rs
1011pub struct Foo;
1012"#,
1013        );
1014    }
1015
1016    #[test]
1017    fn goto_def_for_module_declaration() {
1018        check(
1019            r#"
1020//- /lib.rs
1021mod $0foo;
1022
1023//- /foo.rs
1024// empty
1025//^file
1026"#,
1027        );
1028
1029        check(
1030            r#"
1031//- /lib.rs
1032mod $0foo;
1033
1034//- /foo/mod.rs
1035// empty
1036//^file
1037"#,
1038        );
1039    }
1040
1041    #[test]
1042    fn goto_def_for_macros() {
1043        check(
1044            r#"
1045macro_rules! foo { () => { () } }
1046           //^^^
1047fn bar() {
1048    $0foo!();
1049}
1050"#,
1051        );
1052    }
1053
1054    #[test]
1055    fn goto_def_for_macros_from_other_crates() {
1056        check(
1057            r#"
1058//- /lib.rs crate:main deps:foo
1059use foo::foo;
1060fn bar() {
1061    $0foo!();
1062}
1063
1064//- /foo/lib.rs crate:foo
1065#[macro_export]
1066macro_rules! foo { () => { () } }
1067           //^^^
1068"#,
1069        );
1070    }
1071
1072    #[test]
1073    fn goto_def_for_macros_in_use_tree() {
1074        check(
1075            r#"
1076//- /lib.rs crate:main deps:foo
1077use foo::foo$0;
1078
1079//- /foo/lib.rs crate:foo
1080#[macro_export]
1081macro_rules! foo { () => { () } }
1082           //^^^
1083"#,
1084        );
1085    }
1086
1087    #[test]
1088    fn goto_def_for_macro_defined_fn_with_arg() {
1089        check(
1090            r#"
1091//- /lib.rs
1092macro_rules! define_fn {
1093    ($name:ident) => (fn $name() {})
1094}
1095
1096define_fn!(foo);
1097         //^^^
1098
1099fn bar() {
1100   $0foo();
1101}
1102"#,
1103        );
1104    }
1105
1106    #[test]
1107    fn goto_def_for_macro_defined_fn_no_arg() {
1108        check(
1109            r#"
1110//- /lib.rs
1111macro_rules! define_fn {
1112    () => (fn foo() {})
1113            //^^^
1114}
1115
1116  define_fn!();
1117//^^^^^^^^^^
1118fn bar() {
1119   $0foo();
1120}
1121"#,
1122        );
1123    }
1124
1125    #[test]
1126    fn goto_definition_works_for_macro_inside_pattern() {
1127        check(
1128            r#"
1129//- /lib.rs
1130macro_rules! foo {() => {0}}
1131           //^^^
1132
1133fn bar() {
1134    match (0,1) {
1135        ($0foo!(), _) => {}
1136    }
1137}
1138"#,
1139        );
1140    }
1141
1142    #[test]
1143    fn goto_definition_works_for_macro_inside_match_arm_lhs() {
1144        check(
1145            r#"
1146//- /lib.rs
1147macro_rules! foo {() => {0}}
1148           //^^^
1149fn bar() {
1150    match 0 {
1151        $0foo!() => {}
1152    }
1153}
1154"#,
1155        );
1156    }
1157
1158    #[test]
1159    fn goto_definition_works_for_consts_inside_range_pattern() {
1160        check(
1161            r#"
1162//- /lib.rs
1163const A: u32 = 0;
1164    //^
1165
1166fn bar(v: u32) {
1167    match v {
1168        0..=$0A => {}
1169        _ => {}
1170    }
1171}
1172"#,
1173        );
1174    }
1175
1176    #[test]
1177    fn goto_def_for_use_alias() {
1178        check(
1179            r#"
1180//- /lib.rs crate:main deps:foo
1181use foo as bar$0;
1182
1183//- /foo/lib.rs crate:foo
1184// empty
1185//^file
1186"#,
1187        );
1188    }
1189
1190    #[test]
1191    fn goto_def_for_use_alias_foo_macro() {
1192        check(
1193            r#"
1194//- /lib.rs crate:main deps:foo
1195use foo::foo as bar$0;
1196
1197//- /foo/lib.rs crate:foo
1198#[macro_export]
1199macro_rules! foo { () => { () } }
1200           //^^^
1201"#,
1202        );
1203    }
1204
1205    #[test]
1206    fn goto_def_for_methods() {
1207        check(
1208            r#"
1209struct Foo;
1210impl Foo {
1211    fn frobnicate(&self) { }
1212     //^^^^^^^^^^
1213}
1214
1215fn bar(foo: &Foo) {
1216    foo.frobnicate$0();
1217}
1218"#,
1219        );
1220    }
1221
1222    #[test]
1223    fn goto_def_for_fields() {
1224        check(
1225            r#"
1226struct Foo {
1227    spam: u32,
1228} //^^^^
1229
1230fn bar(foo: &Foo) {
1231    foo.spam$0;
1232}
1233"#,
1234        );
1235    }
1236
1237    #[test]
1238    fn goto_def_for_record_fields() {
1239        check(
1240            r#"
1241//- /lib.rs
1242struct Foo {
1243    spam: u32,
1244} //^^^^
1245
1246fn bar() -> Foo {
1247    Foo {
1248        spam$0: 0,
1249    }
1250}
1251"#,
1252        );
1253    }
1254
1255    #[test]
1256    fn goto_def_for_record_pat_fields() {
1257        check(
1258            r#"
1259//- /lib.rs
1260struct Foo {
1261    spam: u32,
1262} //^^^^
1263
1264fn bar(foo: Foo) -> Foo {
1265    let Foo { spam$0: _, } = foo
1266}
1267"#,
1268        );
1269    }
1270
1271    #[test]
1272    fn goto_def_for_record_fields_macros() {
1273        check(
1274            r"
1275macro_rules! m { () => { 92 };}
1276struct Foo { spam: u32 }
1277           //^^^^
1278
1279fn bar() -> Foo {
1280    Foo { spam$0: m!() }
1281}
1282",
1283        );
1284    }
1285
1286    #[test]
1287    fn goto_for_tuple_fields() {
1288        check(
1289            r#"
1290struct Foo(u32);
1291         //^^^
1292
1293fn bar() {
1294    let foo = Foo(0);
1295    foo.$00;
1296}
1297"#,
1298        );
1299    }
1300
1301    #[test]
1302    fn goto_def_for_ufcs_inherent_methods() {
1303        check(
1304            r#"
1305struct Foo;
1306impl Foo {
1307    fn frobnicate() { }
1308}    //^^^^^^^^^^
1309
1310fn bar(foo: &Foo) {
1311    Foo::frobnicate$0();
1312}
1313"#,
1314        );
1315    }
1316
1317    #[test]
1318    fn goto_def_for_ufcs_trait_methods_through_traits() {
1319        check(
1320            r#"
1321trait Foo {
1322    fn frobnicate();
1323}    //^^^^^^^^^^
1324
1325fn bar() {
1326    Foo::frobnicate$0();
1327}
1328"#,
1329        );
1330    }
1331
1332    #[test]
1333    fn goto_def_for_ufcs_trait_methods_through_self() {
1334        check(
1335            r#"
1336struct Foo;
1337trait Trait {
1338    fn frobnicate();
1339}    //^^^^^^^^^^
1340impl Trait for Foo {}
1341
1342fn bar() {
1343    Foo::frobnicate$0();
1344}
1345"#,
1346        );
1347    }
1348
1349    #[test]
1350    fn goto_definition_on_self() {
1351        check(
1352            r#"
1353struct Foo;
1354impl Foo {
1355   //^^^
1356    pub fn new() -> Self {
1357        Self$0 {}
1358    }
1359}
1360"#,
1361        );
1362        check(
1363            r#"
1364struct Foo;
1365impl Foo {
1366   //^^^
1367    pub fn new() -> Self$0 {
1368        Self {}
1369    }
1370}
1371"#,
1372        );
1373
1374        check(
1375            r#"
1376enum Foo { A }
1377impl Foo {
1378   //^^^
1379    pub fn new() -> Self$0 {
1380        Foo::A
1381    }
1382}
1383"#,
1384        );
1385
1386        check(
1387            r#"
1388enum Foo { A }
1389impl Foo {
1390   //^^^
1391    pub fn thing(a: &Self$0) {
1392    }
1393}
1394"#,
1395        );
1396    }
1397
1398    #[test]
1399    fn goto_definition_on_self_in_trait_impl() {
1400        check(
1401            r#"
1402struct Foo;
1403trait Make {
1404    fn new() -> Self;
1405}
1406impl Make for Foo {
1407            //^^^
1408    fn new() -> Self {
1409        Self$0 {}
1410    }
1411}
1412"#,
1413        );
1414
1415        check(
1416            r#"
1417struct Foo;
1418trait Make {
1419    fn new() -> Self;
1420}
1421impl Make for Foo {
1422            //^^^
1423    fn new() -> Self$0 {
1424        Self {}
1425    }
1426}
1427"#,
1428        );
1429    }
1430
1431    #[test]
1432    fn goto_def_when_used_on_definition_name_itself() {
1433        check(
1434            r#"
1435struct Foo$0 { value: u32 }
1436     //^^^
1437            "#,
1438        );
1439
1440        check(
1441            r#"
1442struct Foo {
1443    field$0: string,
1444} //^^^^^
1445"#,
1446        );
1447
1448        check(
1449            r#"
1450fn foo_test$0() { }
1451 //^^^^^^^^
1452"#,
1453        );
1454
1455        check(
1456            r#"
1457enum Foo$0 { Variant }
1458   //^^^
1459"#,
1460        );
1461
1462        check(
1463            r#"
1464enum Foo {
1465    Variant1,
1466    Variant2$0,
1467  //^^^^^^^^
1468    Variant3,
1469}
1470"#,
1471        );
1472
1473        check(
1474            r#"
1475static INNER$0: &str = "";
1476     //^^^^^
1477"#,
1478        );
1479
1480        check(
1481            r#"
1482const INNER$0: &str = "";
1483    //^^^^^
1484"#,
1485        );
1486
1487        check(
1488            r#"
1489type Thing$0 = Option<()>;
1490   //^^^^^
1491"#,
1492        );
1493
1494        check(
1495            r#"
1496trait Foo$0 { }
1497    //^^^
1498"#,
1499        );
1500
1501        check(
1502            r#"
1503trait Foo$0 = ;
1504    //^^^
1505"#,
1506        );
1507
1508        check(
1509            r#"
1510mod bar$0 { }
1511  //^^^
1512"#,
1513        );
1514    }
1515
1516    #[test]
1517    fn goto_from_macro() {
1518        check(
1519            r#"
1520macro_rules! id {
1521    ($($tt:tt)*) => { $($tt)* }
1522}
1523fn foo() {}
1524 //^^^
1525id! {
1526    fn bar() {
1527        fo$0o();
1528    }
1529}
1530mod confuse_index { fn foo(); }
1531"#,
1532        );
1533    }
1534
1535    #[test]
1536    fn goto_through_format() {
1537        check(
1538            r#"
1539//- minicore: fmt
1540#[macro_export]
1541macro_rules! format {
1542    ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*)))
1543}
1544pub mod __export {
1545    pub use core::format_args;
1546    fn foo() {} // for index confusion
1547}
1548fn foo() -> i8 {}
1549 //^^^
1550fn test() {
1551    format!("{}", fo$0o())
1552}
1553"#,
1554        );
1555    }
1556
1557    #[test]
1558    fn goto_through_included_file() {
1559        check(
1560            r#"
1561//- /main.rs
1562#[rustc_builtin_macro]
1563macro_rules! include {}
1564
1565include!("foo.rs");
1566
1567fn f() {
1568    foo$0();
1569}
1570
1571mod confuse_index {
1572    pub fn foo() {}
1573}
1574
1575//- /foo.rs
1576fn foo() {}
1577 //^^^
1578        "#,
1579        );
1580    }
1581
1582    #[test]
1583    fn goto_through_included_file_struct_with_doc_comment() {
1584        check(
1585            r#"
1586//- /main.rs
1587#[rustc_builtin_macro]
1588macro_rules! include {}
1589
1590include!("foo.rs");
1591
1592fn f() {
1593    let x = Foo$0;
1594}
1595
1596mod confuse_index {
1597    pub struct Foo;
1598}
1599
1600//- /foo.rs
1601/// This is a doc comment
1602pub struct Foo;
1603         //^^^
1604        "#,
1605        );
1606    }
1607
1608    #[test]
1609    fn goto_for_type_param() {
1610        check(
1611            r#"
1612struct Foo<T: Clone> { t: $0T }
1613         //^
1614"#,
1615        );
1616    }
1617
1618    #[test]
1619    fn goto_within_macro() {
1620        check(
1621            r#"
1622macro_rules! id {
1623    ($($tt:tt)*) => ($($tt)*)
1624}
1625
1626fn foo() {
1627    let x = 1;
1628      //^
1629    id!({
1630        let y = $0x;
1631        let z = y;
1632    });
1633}
1634"#,
1635        );
1636
1637        check(
1638            r#"
1639macro_rules! id {
1640    ($($tt:tt)*) => ($($tt)*)
1641}
1642
1643fn foo() {
1644    let x = 1;
1645    id!({
1646        let y = x;
1647          //^
1648        let z = $0y;
1649    });
1650}
1651"#,
1652        );
1653    }
1654
1655    #[test]
1656    fn goto_def_in_local_fn() {
1657        check(
1658            r#"
1659fn main() {
1660    fn foo() {
1661        let x = 92;
1662          //^
1663        $0x;
1664    }
1665}
1666"#,
1667        );
1668    }
1669
1670    #[test]
1671    fn goto_def_in_local_macro() {
1672        check(
1673            r#"
1674fn bar() {
1675    macro_rules! foo { () => { () } }
1676               //^^^
1677    $0foo!();
1678}
1679"#,
1680        );
1681    }
1682
1683    #[test]
1684    fn goto_def_for_field_init_shorthand() {
1685        check(
1686            r#"
1687struct Foo { x: i32 }
1688           //^
1689fn main() {
1690    let x = 92;
1691      //^
1692    Foo { x$0 };
1693}
1694"#,
1695        )
1696    }
1697
1698    #[test]
1699    fn goto_def_for_enum_variant_field() {
1700        check(
1701            r#"
1702enum Foo {
1703    Bar { x: i32 }
1704        //^
1705}
1706fn baz(foo: Foo) {
1707    match foo {
1708        Foo::Bar { x$0 } => x
1709                 //^
1710    };
1711}
1712"#,
1713        );
1714    }
1715
1716    #[test]
1717    fn goto_def_for_enum_variant_self_pattern_const() {
1718        check(
1719            r#"
1720enum Foo { Bar }
1721         //^^^
1722impl Foo {
1723    fn baz(self) {
1724        match self { Self::Bar$0 => {} }
1725    }
1726}
1727"#,
1728        );
1729    }
1730
1731    #[test]
1732    fn goto_def_for_enum_variant_self_pattern_record() {
1733        check(
1734            r#"
1735enum Foo { Bar { val: i32 } }
1736         //^^^
1737impl Foo {
1738    fn baz(self) -> i32 {
1739        match self { Self::Bar$0 { val } => {} }
1740    }
1741}
1742"#,
1743        );
1744    }
1745
1746    #[test]
1747    fn goto_def_for_enum_variant_self_expr_const() {
1748        check(
1749            r#"
1750enum Foo { Bar }
1751         //^^^
1752impl Foo {
1753    fn baz(self) { Self::Bar$0; }
1754}
1755"#,
1756        );
1757    }
1758
1759    #[test]
1760    fn goto_def_for_enum_variant_self_expr_record() {
1761        check(
1762            r#"
1763enum Foo { Bar { val: i32 } }
1764         //^^^
1765impl Foo {
1766    fn baz(self) { Self::Bar$0 {val: 4}; }
1767}
1768"#,
1769        );
1770    }
1771
1772    #[test]
1773    fn goto_def_for_type_alias_generic_parameter() {
1774        check(
1775            r#"
1776type Alias<T> = T$0;
1777         //^
1778"#,
1779        )
1780    }
1781
1782    #[test]
1783    fn goto_def_for_macro_container() {
1784        check(
1785            r#"
1786//- /lib.rs crate:main deps:foo
1787foo::module$0::mac!();
1788
1789//- /foo/lib.rs crate:foo
1790pub mod module {
1791      //^^^^^^
1792    #[macro_export]
1793    macro_rules! _mac { () => { () } }
1794    pub use crate::_mac as mac;
1795}
1796"#,
1797        );
1798    }
1799
1800    #[test]
1801    fn goto_def_for_assoc_ty_in_path() {
1802        check(
1803            r#"
1804trait Iterator {
1805    type Item;
1806       //^^^^
1807}
1808
1809fn f() -> impl Iterator<Item$0 = u8> {}
1810"#,
1811        );
1812    }
1813
1814    #[test]
1815    fn goto_def_for_super_assoc_ty_in_path() {
1816        check(
1817            r#"
1818trait Super {
1819    type Item;
1820       //^^^^
1821}
1822
1823trait Sub: Super {}
1824
1825fn f() -> impl Sub<Item$0 = u8> {}
1826"#,
1827        );
1828    }
1829
1830    #[test]
1831    fn goto_def_for_module_declaration_in_path_if_types_and_values_same_name() {
1832        check(
1833            r#"
1834mod bar {
1835    pub struct Foo {}
1836             //^^^
1837    pub fn Foo() {}
1838}
1839
1840fn baz() {
1841    let _foo_enum: bar::Foo$0 = bar::Foo {};
1842}
1843        "#,
1844        )
1845    }
1846
1847    #[test]
1848    fn unknown_assoc_ty() {
1849        check_unresolved(
1850            r#"
1851trait Iterator { type Item; }
1852fn f() -> impl Iterator<Invalid$0 = u8> {}
1853"#,
1854        )
1855    }
1856
1857    #[test]
1858    fn goto_def_for_assoc_ty_in_path_multiple() {
1859        check(
1860            r#"
1861trait Iterator {
1862    type A;
1863       //^
1864    type B;
1865}
1866
1867fn f() -> impl Iterator<A$0 = u8, B = ()> {}
1868"#,
1869        );
1870        check(
1871            r#"
1872trait Iterator {
1873    type A;
1874    type B;
1875       //^
1876}
1877
1878fn f() -> impl Iterator<A = u8, B$0 = ()> {}
1879"#,
1880        );
1881    }
1882
1883    #[test]
1884    fn goto_def_for_assoc_ty_ufcs() {
1885        check(
1886            r#"
1887trait Iterator {
1888    type Item;
1889       //^^^^
1890}
1891
1892fn g() -> <() as Iterator<Item$0 = ()>>::Item {}
1893"#,
1894        );
1895    }
1896
1897    #[test]
1898    fn goto_def_for_assoc_ty_ufcs_multiple() {
1899        check(
1900            r#"
1901trait Iterator {
1902    type A;
1903       //^
1904    type B;
1905}
1906
1907fn g() -> <() as Iterator<A$0 = (), B = u8>>::B {}
1908"#,
1909        );
1910        check(
1911            r#"
1912trait Iterator {
1913    type A;
1914    type B;
1915       //^
1916}
1917
1918fn g() -> <() as Iterator<A = (), B$0 = u8>>::A {}
1919"#,
1920        );
1921    }
1922
1923    #[test]
1924    fn goto_self_param_ty_specified() {
1925        check(
1926            r#"
1927struct Foo {}
1928
1929impl Foo {
1930    fn bar(self: &Foo) {
1931         //^^^^
1932        let foo = sel$0f;
1933    }
1934}"#,
1935        )
1936    }
1937
1938    #[test]
1939    fn goto_self_param_on_decl() {
1940        check(
1941            r#"
1942struct Foo {}
1943
1944impl Foo {
1945    fn bar(&self$0) {
1946          //^^^^
1947    }
1948}"#,
1949        )
1950    }
1951
1952    #[test]
1953    fn goto_lifetime_param_on_decl() {
1954        check(
1955            r#"
1956fn foo<'foobar$0>(_: &'foobar ()) {
1957     //^^^^^^^
1958}"#,
1959        )
1960    }
1961
1962    #[test]
1963    fn goto_lifetime_param_decl() {
1964        check(
1965            r#"
1966fn foo<'foobar>(_: &'foobar$0 ()) {
1967     //^^^^^^^
1968}"#,
1969        )
1970    }
1971
1972    #[test]
1973    fn goto_lifetime_param_decl_nested() {
1974        check(
1975            r#"
1976fn foo<'foobar>(_: &'foobar ()) {
1977    fn foo<'foobar>(_: &'foobar$0 ()) {}
1978         //^^^^^^^
1979}"#,
1980        )
1981    }
1982
1983    #[test]
1984    fn goto_lifetime_hrtb() {
1985        // FIXME: requires the HIR to somehow track these hrtb lifetimes
1986        check_unresolved(
1987            r#"
1988trait Foo<T> {}
1989fn foo<T>() where for<'a> T: Foo<&'a$0 (u8, u16)>, {}
1990                    //^^
1991"#,
1992        );
1993        check_unresolved(
1994            r#"
1995trait Foo<T> {}
1996fn foo<T>() where for<'a$0> T: Foo<&'a (u8, u16)>, {}
1997                    //^^
1998"#,
1999        );
2000    }
2001
2002    #[test]
2003    fn goto_lifetime_hrtb_for_type() {
2004        // FIXME: requires ForTypes to be implemented
2005        check_unresolved(
2006            r#"trait Foo<T> {}
2007fn foo<T>() where T: for<'a> Foo<&'a$0 (u8, u16)>, {}
2008                       //^^
2009"#,
2010        );
2011    }
2012
2013    #[test]
2014    fn goto_label() {
2015        check(
2016            r#"
2017fn foo<'foo>(_: &'foo ()) {
2018    'foo: {
2019  //^^^^
2020        'bar: loop {
2021            break 'foo$0;
2022        }
2023    }
2024}"#,
2025        )
2026    }
2027
2028    #[test]
2029    fn goto_def_for_intra_doc_link_same_file() {
2030        check(
2031            r#"
2032/// Blah, [`bar`](bar) .. [`foo`](foo$0) has [`bar`](bar)
2033pub fn bar() { }
2034
2035/// You might want to see [`std::fs::read()`] too.
2036pub fn foo() { }
2037     //^^^
2038
2039}"#,
2040        )
2041    }
2042
2043    #[test]
2044    fn goto_def_for_intra_doc_link_outer_same_file() {
2045        check(
2046            r#"
2047/// [`S$0`]
2048mod m {
2049    //! [`super::S`]
2050}
2051struct S;
2052     //^
2053            "#,
2054        );
2055
2056        check(
2057            r#"
2058/// [`S$0`]
2059mod m {}
2060struct S;
2061     //^
2062            "#,
2063        );
2064
2065        check(
2066            r#"
2067/// [`S$0`]
2068fn f() {
2069    //! [`S`]
2070}
2071struct S;
2072     //^
2073            "#,
2074        );
2075    }
2076
2077    #[test]
2078    fn goto_def_for_intra_doc_link_inner_same_file() {
2079        check(
2080            r#"
2081/// [`S`]
2082mod m {
2083    //! [`super::S$0`]
2084}
2085struct S;
2086     //^
2087            "#,
2088        );
2089
2090        check(
2091            r#"
2092mod m {
2093    //! [`super::S$0`]
2094}
2095struct S;
2096     //^
2097            "#,
2098        );
2099
2100        check(
2101            r#"
2102fn f() {
2103    //! [`S$0`]
2104}
2105struct S;
2106     //^
2107            "#,
2108        );
2109    }
2110
2111    #[test]
2112    fn goto_def_for_intra_doc_link_inner() {
2113        check(
2114            r#"
2115//- /main.rs
2116mod m;
2117struct S;
2118     //^
2119
2120//- /m.rs
2121//! [`super::S$0`]
2122"#,
2123        )
2124    }
2125
2126    #[test]
2127    fn goto_incomplete_field() {
2128        check(
2129            r#"
2130struct A { a: u32 }
2131         //^
2132fn foo() { A { a$0: }; }
2133"#,
2134        )
2135    }
2136
2137    #[test]
2138    fn goto_proc_macro() {
2139        check(
2140            r#"
2141//- /main.rs crate:main deps:mac
2142use mac::fn_macro;
2143
2144fn_macro$0!();
2145
2146//- /mac.rs crate:mac
2147#![crate_type="proc-macro"]
2148#[proc_macro]
2149fn fn_macro() {}
2150 //^^^^^^^^
2151            "#,
2152        )
2153    }
2154
2155    #[test]
2156    fn goto_intra_doc_links() {
2157        check(
2158            r#"
2159
2160pub mod theitem {
2161    /// This is the item. Cool!
2162    pub struct TheItem;
2163             //^^^^^^^
2164}
2165
2166/// Gives you a [`TheItem$0`].
2167///
2168/// [`TheItem`]: theitem::TheItem
2169pub fn gimme() -> theitem::TheItem {
2170    theitem::TheItem
2171}
2172"#,
2173        );
2174    }
2175
2176    #[test]
2177    fn goto_ident_from_pat_macro() {
2178        check(
2179            r#"
2180macro_rules! pat {
2181    ($name:ident) => { Enum::Variant1($name) }
2182}
2183
2184enum Enum {
2185    Variant1(u8),
2186    Variant2,
2187}
2188
2189fn f(e: Enum) {
2190    match e {
2191        pat!(bind) => {
2192           //^^^^
2193            bind$0
2194        }
2195        Enum::Variant2 => {}
2196    }
2197}
2198"#,
2199        );
2200    }
2201
2202    #[test]
2203    fn goto_include() {
2204        check(
2205            r#"
2206//- /main.rs
2207
2208#[rustc_builtin_macro]
2209macro_rules! include_str {}
2210
2211fn main() {
2212    let str = include_str!("foo.txt$0");
2213}
2214//- /foo.txt
2215// empty
2216//^file
2217"#,
2218        );
2219    }
2220
2221    #[test]
2222    fn goto_include_has_eager_input() {
2223        check(
2224            r#"
2225//- /main.rs
2226#[rustc_builtin_macro]
2227macro_rules! include_str {}
2228#[rustc_builtin_macro]
2229macro_rules! concat {}
2230
2231fn main() {
2232    let str = include_str!(concat!("foo", ".tx$0t"));
2233}
2234//- /foo.txt
2235// empty
2236//^file
2237"#,
2238        );
2239    }
2240
2241    // macros in this position are not yet supported
2242    #[test]
2243    // FIXME
2244    #[should_panic]
2245    fn goto_doc_include_str() {
2246        check(
2247            r#"
2248//- /main.rs
2249#[rustc_builtin_macro]
2250macro_rules! include_str {}
2251
2252#[doc = include_str!("docs.md$0")]
2253struct Item;
2254
2255//- /docs.md
2256// docs
2257//^file
2258"#,
2259        );
2260    }
2261
2262    #[test]
2263    fn goto_shadow_include() {
2264        check(
2265            r#"
2266//- /main.rs
2267macro_rules! include {
2268    ("included.rs") => {}
2269}
2270
2271include!("included.rs$0");
2272
2273//- /included.rs
2274// empty
2275"#,
2276        );
2277    }
2278
2279    mod goto_impl_of_trait_fn {
2280        use super::check;
2281        #[test]
2282        fn cursor_on_impl() {
2283            check(
2284                r#"
2285trait Twait {
2286    fn a();
2287}
2288
2289struct Stwuct;
2290
2291impl Twait for Stwuct {
2292    fn a$0();
2293     //^
2294}
2295        "#,
2296            );
2297        }
2298        #[test]
2299        fn method_call() {
2300            check(
2301                r#"
2302trait Twait {
2303    fn a(&self);
2304}
2305
2306struct Stwuct;
2307
2308impl Twait for Stwuct {
2309    fn a(&self){};
2310     //^
2311}
2312fn f() {
2313    let s = Stwuct;
2314    s.a$0();
2315}
2316        "#,
2317            );
2318        }
2319        #[test]
2320        fn method_call_inside_block() {
2321            check(
2322                r#"
2323trait Twait {
2324    fn a(&self);
2325}
2326
2327fn outer() {
2328    struct Stwuct;
2329
2330    impl Twait for Stwuct {
2331        fn a(&self){}
2332         //^
2333    }
2334    fn f() {
2335        let s = Stwuct;
2336        s.a$0();
2337    }
2338}
2339        "#,
2340            );
2341        }
2342        #[test]
2343        fn path_call() {
2344            check(
2345                r#"
2346trait Twait {
2347    fn a(&self);
2348}
2349
2350struct Stwuct;
2351
2352impl Twait for Stwuct {
2353    fn a(&self){};
2354     //^
2355}
2356fn f() {
2357    let s = Stwuct;
2358    Stwuct::a$0(&s);
2359}
2360        "#,
2361            );
2362        }
2363        #[test]
2364        fn where_clause_can_work() {
2365            check(
2366                r#"
2367trait G {
2368    fn g(&self);
2369}
2370trait Bound{}
2371trait EA{}
2372struct Gen<T>(T);
2373impl <T:EA> G for Gen<T> {
2374    fn g(&self) {
2375    }
2376}
2377impl <T> G for Gen<T>
2378where T : Bound
2379{
2380    fn g(&self){
2381     //^
2382    }
2383}
2384struct A;
2385impl Bound for A{}
2386fn f() {
2387    let g = Gen::<A>(A);
2388    g.g$0();
2389}
2390                "#,
2391            );
2392        }
2393        #[test]
2394        fn wc_case_is_ok() {
2395            check(
2396                r#"
2397trait G {
2398    fn g(&self);
2399}
2400trait BParent{}
2401trait Bound: BParent{}
2402struct Gen<T>(T);
2403impl <T> G for Gen<T>
2404where T : Bound
2405{
2406    fn g(&self){
2407     //^
2408    }
2409}
2410struct A;
2411impl Bound for A{}
2412fn f() {
2413    let g = Gen::<A>(A);
2414    g.g$0();
2415}
2416"#,
2417            );
2418        }
2419
2420        #[test]
2421        fn method_call_defaulted() {
2422            check(
2423                r#"
2424trait Twait {
2425    fn a(&self) {}
2426     //^
2427}
2428
2429struct Stwuct;
2430
2431impl Twait for Stwuct {
2432}
2433fn f() {
2434    let s = Stwuct;
2435    s.a$0();
2436}
2437        "#,
2438            );
2439        }
2440
2441        #[test]
2442        fn method_call_on_generic() {
2443            check(
2444                r#"
2445trait Twait {
2446    fn a(&self) {}
2447     //^
2448}
2449
2450fn f<T: Twait>(s: T) {
2451    s.a$0();
2452}
2453        "#,
2454            );
2455        }
2456    }
2457
2458    #[test]
2459    fn goto_def_of_trait_impl_const() {
2460        check(
2461            r#"
2462trait Twait {
2463    const NOMS: bool;
2464       // ^^^^
2465}
2466
2467struct Stwuct;
2468
2469impl Twait for Stwuct {
2470    const NOMS$0: bool = true;
2471}
2472"#,
2473        );
2474    }
2475
2476    #[test]
2477    fn goto_def_of_trait_impl_type_alias() {
2478        check(
2479            r#"
2480trait Twait {
2481    type IsBad;
2482      // ^^^^^
2483}
2484
2485struct Stwuct;
2486
2487impl Twait for Stwuct {
2488    type IsBad$0 = !;
2489}
2490"#,
2491        );
2492    }
2493
2494    #[test]
2495    fn goto_def_derive_input() {
2496        check(
2497            r#"
2498        //- minicore:derive
2499        #[rustc_builtin_macro]
2500        pub macro Copy {}
2501               // ^^^^
2502        #[derive(Copy$0)]
2503        struct Foo;
2504                    "#,
2505        );
2506        check(
2507            r#"
2508//- minicore:derive
2509#[rustc_builtin_macro]
2510pub macro Copy {}
2511       // ^^^^
2512#[cfg_attr(feature = "false", derive)]
2513#[derive(Copy$0)]
2514struct Foo;
2515            "#,
2516        );
2517        check(
2518            r#"
2519//- minicore:derive
2520mod foo {
2521    #[rustc_builtin_macro]
2522    pub macro Copy {}
2523           // ^^^^
2524}
2525#[derive(foo::Copy$0)]
2526struct Foo;
2527            "#,
2528        );
2529        check(
2530            r#"
2531//- minicore:derive
2532mod foo {
2533 // ^^^
2534    #[rustc_builtin_macro]
2535    pub macro Copy {}
2536}
2537#[derive(foo$0::Copy)]
2538struct Foo;
2539            "#,
2540        );
2541    }
2542
2543    #[test]
2544    fn goto_def_in_macro_multi() {
2545        check(
2546            r#"
2547struct Foo {
2548    foo: ()
2549  //^^^
2550}
2551macro_rules! foo {
2552    ($ident:ident) => {
2553        fn $ident(Foo { $ident }: Foo) {}
2554    }
2555}
2556  foo!(foo$0);
2557     //^^^
2558     //^^^
2559"#,
2560        );
2561        check(
2562            r#"
2563fn bar() {}
2564 //^^^
2565struct bar;
2566     //^^^
2567macro_rules! foo {
2568    ($ident:ident) => {
2569        fn foo() {
2570            let _: $ident = $ident;
2571        }
2572    }
2573}
2574
2575foo!(bar$0);
2576"#,
2577        );
2578    }
2579
2580    #[test]
2581    fn goto_await_poll() {
2582        check(
2583            r#"
2584//- minicore: future
2585
2586struct MyFut;
2587
2588impl core::future::Future for MyFut {
2589    type Output = ();
2590
2591    fn poll(
2592     //^^^^
2593        self: std::pin::Pin<&mut Self>,
2594        cx: &mut std::task::Context<'_>
2595    ) -> std::task::Poll<Self::Output>
2596    {
2597        ()
2598    }
2599}
2600
2601fn f() {
2602    MyFut.await$0;
2603}
2604"#,
2605        );
2606    }
2607
2608    #[test]
2609    fn goto_await_into_future_poll() {
2610        check(
2611            r#"
2612//- minicore: future
2613
2614struct Futurable;
2615
2616impl core::future::IntoFuture for Futurable {
2617    type IntoFuture = MyFut;
2618}
2619
2620struct MyFut;
2621
2622impl core::future::Future for MyFut {
2623    type Output = ();
2624
2625    fn poll(
2626     //^^^^
2627        self: std::pin::Pin<&mut Self>,
2628        cx: &mut std::task::Context<'_>
2629    ) -> std::task::Poll<Self::Output>
2630    {
2631        ()
2632    }
2633}
2634
2635fn f() {
2636    Futurable.await$0;
2637}
2638"#,
2639        );
2640    }
2641
2642    #[test]
2643    fn goto_try_op() {
2644        check(
2645            r#"
2646//- minicore: try
2647
2648struct Struct;
2649
2650impl core::ops::Try for Struct {
2651    fn branch(
2652     //^^^^^^
2653        self
2654    ) {}
2655}
2656
2657fn f() {
2658    Struct?$0;
2659}
2660"#,
2661        );
2662    }
2663
2664    #[test]
2665    fn goto_index_op() {
2666        check(
2667            r#"
2668//- minicore: index
2669
2670struct Struct;
2671
2672impl core::ops::Index<usize> for Struct {
2673    fn index(
2674     //^^^^^
2675        self
2676    ) {}
2677}
2678
2679fn f() {
2680    Struct[0]$0;
2681}
2682"#,
2683        );
2684    }
2685
2686    #[test]
2687    fn goto_index_mut_op() {
2688        check(
2689            r#"
2690//- minicore: index
2691
2692struct Foo;
2693struct Bar;
2694
2695impl core::ops::Index<usize> for Foo {
2696    type Output = Bar;
2697
2698    fn index(&self, index: usize) -> &Self::Output {}
2699}
2700
2701impl core::ops::IndexMut<usize> for Foo {
2702    fn index_mut(&mut self, index: usize) -> &mut Self::Output {}
2703     //^^^^^^^^^
2704}
2705
2706fn f() {
2707    let mut foo = Foo;
2708    foo[0]$0 = Bar;
2709}
2710"#,
2711        );
2712    }
2713
2714    #[test]
2715    fn goto_prefix_op() {
2716        check(
2717            r#"
2718//- minicore: deref
2719
2720struct Struct;
2721
2722impl core::ops::Deref for Struct {
2723    fn deref(
2724     //^^^^^
2725        self
2726    ) {}
2727}
2728
2729fn f() {
2730    $0*Struct;
2731}
2732"#,
2733        );
2734    }
2735
2736    #[test]
2737    fn goto_deref_mut() {
2738        check(
2739            r#"
2740//- minicore: deref, deref_mut
2741
2742struct Foo;
2743struct Bar;
2744
2745impl core::ops::Deref for Foo {
2746    type Target = Bar;
2747    fn deref(&self) -> &Self::Target {}
2748}
2749
2750impl core::ops::DerefMut for Foo {
2751    fn deref_mut(&mut self) -> &mut Self::Target {}
2752     //^^^^^^^^^
2753}
2754
2755fn f() {
2756    let a = Foo;
2757    $0*a = Bar;
2758}
2759"#,
2760        );
2761    }
2762
2763    #[test]
2764    fn goto_bin_op() {
2765        check(
2766            r#"
2767//- minicore: add
2768
2769struct Struct;
2770
2771impl core::ops::Add for Struct {
2772    fn add(
2773     //^^^
2774        self
2775    ) {}
2776}
2777
2778fn f() {
2779    Struct +$0 Struct;
2780}
2781"#,
2782        );
2783    }
2784
2785    #[test]
2786    fn goto_bin_op_multiple_impl() {
2787        check(
2788            r#"
2789//- minicore: add
2790struct S;
2791impl core::ops::Add for S {
2792    fn add(
2793     //^^^
2794    ) {}
2795}
2796impl core::ops::Add<usize> for S {
2797    fn add(
2798    ) {}
2799}
2800
2801fn f() {
2802    S +$0 S
2803}
2804"#,
2805        );
2806
2807        check(
2808            r#"
2809//- minicore: add
2810struct S;
2811impl core::ops::Add for S {
2812    fn add(
2813    ) {}
2814}
2815impl core::ops::Add<usize> for S {
2816    fn add(
2817     //^^^
2818    ) {}
2819}
2820
2821fn f() {
2822    S +$0 0usize
2823}
2824"#,
2825        );
2826    }
2827
2828    #[test]
2829    fn path_call_multiple_trait_impl() {
2830        check(
2831            r#"
2832trait Trait<T> {
2833    fn f(_: T);
2834}
2835impl Trait<i32> for usize {
2836    fn f(_: i32) {}
2837     //^
2838}
2839impl Trait<i64> for usize {
2840    fn f(_: i64) {}
2841}
2842fn main() {
2843    usize::f$0(0i32);
2844}
2845"#,
2846        );
2847
2848        check(
2849            r#"
2850trait Trait<T> {
2851    fn f(_: T);
2852}
2853impl Trait<i32> for usize {
2854    fn f(_: i32) {}
2855}
2856impl Trait<i64> for usize {
2857    fn f(_: i64) {}
2858     //^
2859}
2860fn main() {
2861    usize::f$0(0i64);
2862}
2863"#,
2864        )
2865    }
2866
2867    #[test]
2868    fn query_impls_in_nearest_block() {
2869        check(
2870            r#"
2871struct S1;
2872impl S1 {
2873    fn e() -> () {}
2874}
2875fn f1() {
2876    struct S1;
2877    impl S1 {
2878        fn e() -> () {}
2879         //^
2880    }
2881    fn f2() {
2882        fn f3() {
2883            S1::e$0();
2884        }
2885    }
2886}
2887"#,
2888        );
2889
2890        check(
2891            r#"
2892struct S1;
2893impl S1 {
2894    fn e() -> () {}
2895}
2896fn f1() {
2897    struct S1;
2898    impl S1 {
2899        fn e() -> () {}
2900         //^
2901    }
2902    fn f2() {
2903        struct S2;
2904        S1::e$0();
2905    }
2906}
2907fn f12() {
2908    struct S1;
2909    impl S1 {
2910        fn e() -> () {}
2911    }
2912}
2913"#,
2914        );
2915
2916        check(
2917            r#"
2918struct S1;
2919impl S1 {
2920    fn e() -> () {}
2921     //^
2922}
2923fn f2() {
2924    struct S2;
2925    S1::e$0();
2926}
2927"#,
2928        );
2929    }
2930
2931    #[test]
2932    fn implicit_format_args() {
2933        check(
2934            r#"
2935//- minicore: fmt
2936fn test() {
2937    let a = "world";
2938     // ^
2939    format_args!("hello {a$0}");
2940}
2941"#,
2942        );
2943    }
2944
2945    #[test]
2946    fn goto_macro_def_from_macro_use() {
2947        check(
2948            r#"
2949//- /main.rs crate:main deps:mac
2950#[macro_use(foo$0)]
2951extern crate mac;
2952
2953//- /mac.rs crate:mac
2954#[macro_export]
2955macro_rules! foo {
2956           //^^^
2957    () => {};
2958}
2959            "#,
2960        );
2961
2962        check(
2963            r#"
2964//- /main.rs crate:main deps:mac
2965#[macro_use(foo, bar$0, baz)]
2966extern crate mac;
2967
2968//- /mac.rs crate:mac
2969#[macro_export]
2970macro_rules! foo {
2971    () => {};
2972}
2973
2974#[macro_export]
2975macro_rules! bar {
2976           //^^^
2977    () => {};
2978}
2979
2980#[macro_export]
2981macro_rules! baz {
2982    () => {};
2983}
2984            "#,
2985        );
2986    }
2987
2988    #[test]
2989    fn goto_shadowed_preludes_in_block_module() {
2990        check(
2991            r#"
2992//- /main.rs crate:main edition:2021 deps:core
2993pub struct S;
2994         //^
2995
2996fn main() {
2997    fn f() -> S$0 {
2998        fn inner() {} // forces a block def map
2999        return S;
3000    }
3001}
3002//- /core.rs crate:core
3003pub mod prelude {
3004    pub mod rust_2021 {
3005        pub enum S;
3006    }
3007}
3008        "#,
3009        );
3010    }
3011
3012    #[test]
3013    fn goto_def_on_return_kw() {
3014        check(
3015            r#"
3016macro_rules! N {
3017    ($i:ident, $x:expr, $blk:expr) => {
3018        for $i in 0..$x {
3019            $blk
3020        }
3021    };
3022}
3023
3024fn main() {
3025    fn f() {
3026 // ^^
3027        N!(i, 5, {
3028            println!("{}", i);
3029            return$0;
3030        });
3031
3032        for i in 1..5 {
3033            return;
3034        }
3035       (|| {
3036            return;
3037        })();
3038    }
3039}
3040"#,
3041        )
3042    }
3043
3044    #[test]
3045    fn goto_def_on_return_kw_in_closure() {
3046        check(
3047            r#"
3048macro_rules! N {
3049    ($i:ident, $x:expr, $blk:expr) => {
3050        for $i in 0..$x {
3051            $blk
3052        }
3053    };
3054}
3055
3056fn main() {
3057    fn f() {
3058        N!(i, 5, {
3059            println!("{}", i);
3060            return;
3061        });
3062
3063        for i in 1..5 {
3064            return;
3065        }
3066       (|| {
3067     // ^
3068            return$0;
3069        })();
3070    }
3071}
3072"#,
3073        )
3074    }
3075
3076    #[test]
3077    fn goto_def_on_break_kw() {
3078        check(
3079            r#"
3080fn main() {
3081    for i in 1..5 {
3082 // ^^^
3083        break$0;
3084    }
3085}
3086"#,
3087        )
3088    }
3089
3090    #[test]
3091    fn goto_def_on_continue_kw() {
3092        check(
3093            r#"
3094fn main() {
3095    for i in 1..5 {
3096 // ^^^
3097        continue$0;
3098    }
3099}
3100"#,
3101        )
3102    }
3103
3104    #[test]
3105    fn goto_def_on_break_kw_for_block() {
3106        check(
3107            r#"
3108fn main() {
3109    'a:{
3110 // ^^^
3111        break$0 'a;
3112    }
3113}
3114"#,
3115        )
3116    }
3117
3118    #[test]
3119    fn goto_def_on_break_with_label() {
3120        check(
3121            r#"
3122fn foo() {
3123    'outer: loop {
3124         // ^^^^
3125         'inner: loop {
3126            'innermost: loop {
3127            }
3128            break$0 'outer;
3129        }
3130    }
3131}
3132"#,
3133        );
3134    }
3135
3136    #[test]
3137    fn label_inside_macro() {
3138        check(
3139            r#"
3140macro_rules! m {
3141    ($s:stmt) => { $s };
3142}
3143
3144fn foo() {
3145    'label: loop {
3146 // ^^^^^^
3147        m!(continue 'label$0);
3148    }
3149}
3150"#,
3151        );
3152    }
3153
3154    #[test]
3155    fn goto_def_on_return_in_try() {
3156        check(
3157            r#"
3158fn main() {
3159    fn f() {
3160 // ^^
3161        try {
3162            return$0;
3163        }
3164
3165        return;
3166    }
3167}
3168"#,
3169        )
3170    }
3171
3172    #[test]
3173    fn goto_def_on_break_in_try() {
3174        check(
3175            r#"
3176fn main() {
3177    for i in 1..100 {
3178 // ^^^
3179        let x: Result<(), ()> = try {
3180            break$0;
3181        };
3182    }
3183}
3184"#,
3185        )
3186    }
3187
3188    #[test]
3189    fn goto_def_on_return_in_async_block() {
3190        check(
3191            r#"
3192fn main() {
3193    async {
3194 // ^^^^^
3195        return$0;
3196    }
3197}
3198"#,
3199        )
3200    }
3201
3202    #[test]
3203    fn goto_def_on_for_kw() {
3204        check(
3205            r#"
3206fn main() {
3207    for$0 i in 1..5 {}
3208 // ^^^
3209}
3210"#,
3211        )
3212    }
3213
3214    #[test]
3215    fn goto_def_on_fn_kw() {
3216        check(
3217            r#"
3218fn main() {
3219    fn$0 foo() {}
3220 // ^^
3221}
3222"#,
3223        )
3224    }
3225
3226    #[test]
3227    fn shadow_builtin_macro() {
3228        check(
3229            r#"
3230//- minicore: column
3231//- /a.rs crate:a
3232#[macro_export]
3233macro_rules! column { () => {} }
3234          // ^^^^^^
3235
3236//- /b.rs crate:b deps:a
3237use a::column;
3238fn foo() {
3239    $0column!();
3240}
3241        "#,
3242        );
3243    }
3244
3245    #[test]
3246    fn issue_18138() {
3247        check(
3248            r#"
3249mod foo {
3250    macro_rules! x {
3251        () => {
3252            pub struct Foo;
3253                    // ^^^
3254        };
3255    }
3256    pub(crate) use x as m;
3257}
3258
3259mod bar {
3260    use crate::m;
3261
3262    m!();
3263 // ^^
3264
3265    fn qux() {
3266        Foo$0;
3267    }
3268}
3269
3270mod m {}
3271
3272use foo::m;
3273"#,
3274        );
3275    }
3276
3277    #[test]
3278    fn macro_label_hygiene() {
3279        check(
3280            r#"
3281macro_rules! m {
3282    ($x:stmt) => {
3283        'bar: loop { $x }
3284    };
3285}
3286
3287fn foo() {
3288    'bar: loop {
3289 // ^^^^
3290        m!(continue 'bar$0);
3291    }
3292}
3293"#,
3294        );
3295    }
3296    #[test]
3297    fn into_call_to_from_definition() {
3298        check(
3299            r#"
3300//- minicore: from
3301struct A;
3302
3303struct B;
3304
3305impl From<A> for B {
3306    fn from(value: A) -> Self {
3307     //^^^^
3308        B
3309    }
3310}
3311
3312fn f() {
3313    let a = A;
3314    let b: B = a.into$0();
3315}
3316        "#,
3317        );
3318    }
3319
3320    #[test]
3321    fn into_call_to_from_definition_within_macro() {
3322        check(
3323            r#"
3324//- proc_macros: identity
3325//- minicore: from
3326struct A;
3327
3328struct B;
3329
3330impl From<A> for B {
3331    fn from(value: A) -> Self {
3332     //^^^^
3333        B
3334    }
3335}
3336
3337#[proc_macros::identity]
3338fn f() {
3339    let a = A;
3340    let b: B = a.into$0();
3341}
3342        "#,
3343        );
3344    }
3345
3346    #[test]
3347    fn into_call_to_from_definition_with_trait_bounds() {
3348        check(
3349            r#"
3350//- minicore: from, iterator
3351struct A;
3352
3353impl<T> From<T> for A
3354where
3355    T: IntoIterator<Item = i64>,
3356{
3357    fn from(value: T) -> Self {
3358     //^^^^
3359        A
3360    }
3361}
3362
3363fn f() {
3364    let a: A = [1, 2, 3].into$0();
3365}
3366        "#,
3367        );
3368    }
3369
3370    #[test]
3371    fn goto_into_definition_if_exists() {
3372        check(
3373            r#"
3374//- minicore: from
3375struct A;
3376
3377struct B;
3378
3379impl Into<B> for A {
3380    fn into(self) -> B {
3381     //^^^^
3382        B
3383    }
3384}
3385
3386fn f() {
3387    let a = A;
3388    let b: B = a.into$0();
3389}
3390        "#,
3391        );
3392    }
3393
3394    #[test]
3395    fn try_into_call_to_try_from_definition() {
3396        check(
3397            r#"
3398//- minicore: from
3399struct A;
3400
3401struct B;
3402
3403impl TryFrom<A> for B {
3404    type Error = String;
3405
3406    fn try_from(value: A) -> Result<Self, Self::Error> {
3407     //^^^^^^^^
3408        Ok(B)
3409    }
3410}
3411
3412fn f() {
3413    let a = A;
3414    let b: Result<B, _> = a.try_into$0();
3415}
3416        "#,
3417        );
3418    }
3419
3420    #[test]
3421    fn goto_try_into_definition_if_exists() {
3422        check(
3423            r#"
3424//- minicore: from
3425struct A;
3426
3427struct B;
3428
3429impl TryInto<B> for A {
3430    type Error = String;
3431
3432    fn try_into(self) -> Result<B, Self::Error> {
3433     //^^^^^^^^
3434        Ok(B)
3435    }
3436}
3437
3438fn f() {
3439    let a = A;
3440    let b: Result<B, _> = a.try_into$0();
3441}
3442        "#,
3443        );
3444    }
3445
3446    #[test]
3447    fn parse_call_to_from_str_definition() {
3448        check(
3449            r#"
3450//- minicore: from, str
3451struct A;
3452impl FromStr for A {
3453    type Error = String;
3454    fn from_str(value: &str) -> Result<Self, Self::Error> {
3455     //^^^^^^^^
3456        Ok(A)
3457    }
3458}
3459fn f() {
3460    let a: Result<A, _> = "aaaaaa".parse$0();
3461}
3462        "#,
3463        );
3464    }
3465
3466    #[test]
3467    fn to_string_call_to_display_definition() {
3468        check(
3469            r#"
3470//- minicore:fmt
3471//- /alloc.rs crate:alloc
3472pub mod string {
3473    pub struct String;
3474    pub trait ToString {
3475        fn to_string(&self) -> String;
3476    }
3477
3478    impl<T: core::fmt::Display> ToString for T {
3479        fn to_string(&self) -> String { String }
3480    }
3481}
3482//- /lib.rs crate:lib deps:alloc
3483use alloc::string::ToString;
3484struct A;
3485impl core::fmt::Display for A {
3486    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {}
3487    // ^^^
3488}
3489fn f() {
3490    A.to_string$0();
3491}
3492        "#,
3493        );
3494    }
3495
3496    #[test]
3497    fn use_inside_body() {
3498        check(
3499            r#"
3500fn main() {
3501    mod nice_module {
3502        pub(super) struct NiceStruct;
3503                       // ^^^^^^^^^^
3504    }
3505
3506    use nice_module::NiceStruct$0;
3507
3508    let _ = NiceStruct;
3509}
3510    "#,
3511        );
3512    }
3513
3514    #[test]
3515    fn shadow_builtin_type_by_module() {
3516        check(
3517            r#"
3518mod Foo{
3519pub mod str {
3520     // ^^^
3521    pub fn foo() {}
3522}
3523}
3524
3525fn main() {
3526    use Foo::str;
3527    let s = st$0r::foo();
3528}
3529"#,
3530        );
3531    }
3532
3533    #[test]
3534    fn not_goto_module_because_str_is_builtin_type() {
3535        check(
3536            r#"
3537mod str {
3538pub fn foo() {}
3539}
3540
3541fn main() {
3542    let s = st$0r::f();
3543}
3544"#,
3545        );
3546    }
3547
3548    #[test]
3549    fn struct_shadow_by_module() {
3550        check(
3551            r#"
3552mod foo {
3553    pub mod bar {
3554         // ^^^
3555        pub type baz = usize;
3556    }
3557}
3558struct bar;
3559fn main() {
3560    use foo::bar;
3561    let x: ba$0r::baz = 5;
3562
3563}
3564"#,
3565        );
3566    }
3567
3568    #[test]
3569    fn type_alias_shadow_by_module() {
3570        check(
3571            r#"
3572mod foo {
3573    pub mod bar {
3574         // ^^^
3575        pub fn baz() {}
3576    }
3577}
3578
3579trait Qux {}
3580
3581fn item<bar: Qux>() {
3582    use foo::bar;
3583    ba$0r::baz();
3584}
3585}
3586"#,
3587        );
3588
3589        check(
3590            r#"
3591mod foo {
3592    pub mod bar {
3593         // ^^^
3594        pub fn baz() {}
3595    }
3596}
3597
3598fn item<bar>(x: bar) {
3599    use foo::bar;
3600    let x: bar$0 = x;
3601}
3602"#,
3603        );
3604    }
3605
3606    #[test]
3607    fn trait_shadow_by_module() {
3608        check(
3609            r#"
3610pub mod foo {
3611    pub mod Bar {}
3612         // ^^^
3613}
3614
3615trait Bar {}
3616
3617fn main() {
3618    use foo::Bar;
3619    fn f<Qux: B$0ar>() {}
3620}
3621            "#,
3622        );
3623    }
3624
3625    #[test]
3626    fn const_shadow_by_module() {
3627        check(
3628            r#"
3629pub mod foo {
3630    pub struct u8 {}
3631    pub mod bar {
3632        pub mod u8 {}
3633    }
3634}
3635
3636fn main() {
3637    use foo::u8;
3638    {
3639        use foo::bar::u8;
3640
3641        fn f1<const N: u$08>() {}
3642    }
3643    fn f2<const N: u8>() {}
3644}
3645"#,
3646        );
3647
3648        check(
3649            r#"
3650pub mod foo {
3651    pub struct u8 {}
3652            // ^^
3653    pub mod bar {
3654        pub mod u8 {}
3655    }
3656}
3657
3658fn main() {
3659    use foo::u8;
3660    {
3661        use foo::bar::u8;
3662
3663        fn f1<const N: u8>() {}
3664    }
3665    fn f2<const N: u$08>() {}
3666}
3667"#,
3668        );
3669
3670        check(
3671            r#"
3672pub mod foo {
3673    pub struct buz {}
3674    pub mod bar {
3675        pub mod buz {}
3676             // ^^^
3677    }
3678}
3679
3680fn main() {
3681    use foo::buz;
3682    {
3683        use foo::bar::buz;
3684
3685        fn f1<const N: buz$0>() {}
3686    }
3687}
3688"#,
3689        );
3690    }
3691
3692    #[test]
3693    fn offset_of() {
3694        check(
3695            r#"
3696//- minicore: offset_of
3697struct Foo {
3698    field: i32,
3699 // ^^^^^
3700}
3701
3702fn foo() {
3703    let _ = core::mem::offset_of!(Foo, fiel$0d);
3704}
3705        "#,
3706        );
3707
3708        check(
3709            r#"
3710//- minicore: offset_of
3711struct Bar(Foo);
3712struct Foo {
3713    field: i32,
3714 // ^^^^^
3715}
3716
3717fn foo() {
3718    let _ = core::mem::offset_of!(Bar, 0.fiel$0d);
3719}
3720        "#,
3721        );
3722
3723        check(
3724            r#"
3725//- minicore: offset_of
3726struct Bar(Baz);
3727enum Baz {
3728    Abc(Foo),
3729    None,
3730}
3731struct Foo {
3732    field: i32,
3733 // ^^^^^
3734}
3735
3736fn foo() {
3737    let _ = core::mem::offset_of!(Bar, 0.Abc.0.fiel$0d);
3738}
3739        "#,
3740        );
3741
3742        check(
3743            r#"
3744//- minicore: offset_of
3745struct Bar(Baz);
3746enum Baz {
3747    Abc(Foo),
3748 // ^^^
3749    None,
3750}
3751struct Foo {
3752    field: i32,
3753}
3754
3755fn foo() {
3756    let _ = core::mem::offset_of!(Bar, 0.Ab$0c.0.field);
3757}
3758        "#,
3759        );
3760    }
3761
3762    #[test]
3763    fn goto_def_for_match_keyword() {
3764        check(
3765            r#"
3766fn main() {
3767    match$0 0 {
3768 // ^^^^^
3769        0 => {},
3770        _ => {},
3771    }
3772}
3773"#,
3774        );
3775    }
3776
3777    #[test]
3778    fn goto_def_for_match_arm_fat_arrow() {
3779        check(
3780            r#"
3781fn main() {
3782    match 0 {
3783        0 =>$0 {},
3784       // ^^
3785        _ => {},
3786    }
3787}
3788"#,
3789        );
3790    }
3791
3792    #[test]
3793    fn goto_def_for_if_keyword() {
3794        check(
3795            r#"
3796fn main() {
3797    if$0 true {
3798 // ^^
3799        ()
3800    }
3801}
3802"#,
3803        );
3804    }
3805
3806    #[test]
3807    fn goto_def_for_match_nested_in_if() {
3808        check(
3809            r#"
3810fn main() {
3811    if true {
3812        match$0 0 {
3813     // ^^^^^
3814            0 => {},
3815            _ => {},
3816        }
3817    }
3818}
3819"#,
3820        );
3821    }
3822
3823    #[test]
3824    fn goto_def_for_multiple_match_expressions() {
3825        check(
3826            r#"
3827fn main() {
3828    match 0 {
3829        0 => {},
3830        _ => {},
3831    };
3832
3833    match$0 1 {
3834 // ^^^^^
3835        1 => {},
3836        _ => {},
3837    }
3838}
3839"#,
3840        );
3841    }
3842
3843    #[test]
3844    fn goto_def_for_nested_match_expressions() {
3845        check(
3846            r#"
3847fn main() {
3848    match 0 {
3849        0 => match$0 1 {
3850          // ^^^^^
3851            1 => {},
3852            _ => {},
3853        },
3854        _ => {},
3855    }
3856}
3857"#,
3858        );
3859    }
3860
3861    #[test]
3862    fn goto_def_for_if_else_chains() {
3863        check(
3864            r#"
3865fn main() {
3866    if true {
3867 // ^^
3868        ()
3869    } else if$0 false {
3870        ()
3871    } else {
3872        ()
3873    }
3874}
3875"#,
3876        );
3877    }
3878
3879    #[test]
3880    fn goto_def_for_match_with_guards() {
3881        check(
3882            r#"
3883fn main() {
3884    match 42 {
3885        x if x > 0 =>$0 {},
3886                // ^^
3887        _ => {},
3888    }
3889}
3890"#,
3891        );
3892    }
3893
3894    #[test]
3895    fn goto_def_for_match_with_macro_arm() {
3896        check(
3897            r#"
3898macro_rules! arm {
3899    () => { 0 => {} };
3900}
3901
3902fn main() {
3903    match$0 0 {
3904 // ^^^^^
3905        arm!(),
3906        _ => {},
3907    }
3908}
3909"#,
3910        );
3911    }
3912
3913    #[test]
3914    fn goto_const_from_match_pat_with_tuple_struct() {
3915        check(
3916            r#"
3917struct Tag(u8);
3918struct Path {}
3919
3920const Path: u8 = 0;
3921   // ^^^^
3922fn main() {
3923    match Tag(Path) {
3924        Tag(Path$0) => {}
3925        _ => {}
3926    }
3927}
3928
3929"#,
3930        );
3931    }
3932
3933    #[test]
3934    fn goto_const_from_match_pat() {
3935        check(
3936            r#"
3937type T1 = u8;
3938const T1: u8 = 0;
3939   // ^^
3940fn main() {
3941    let x = 0;
3942    match x {
3943        T1$0 => {}
3944        _ => {}
3945    }
3946}
3947"#,
3948        );
3949    }
3950
3951    #[test]
3952    fn goto_struct_from_match_pat() {
3953        check(
3954            r#"
3955struct T1;
3956    // ^^
3957fn main() {
3958    let x = 0;
3959    match x {
3960        T1$0 => {}
3961        _ => {}
3962    }
3963}
3964"#,
3965        );
3966    }
3967
3968    #[test]
3969    fn no_goto_trait_from_match_pat() {
3970        check(
3971            r#"
3972trait T1 {}
3973fn main() {
3974    let x = 0;
3975    match x {
3976        T1$0 => {}
3977     // ^^
3978        _ => {}
3979    }
3980}
3981"#,
3982        );
3983    }
3984
3985    #[test]
3986    fn goto_builtin_type() {
3987        check(
3988            r#"
3989//- /main.rs crate:main deps:std
3990const _: &str$0 = ""; }
3991
3992//- /libstd.rs crate:std
3993mod prim_str {}
3994//  ^^^^^^^^
3995"#,
3996        );
3997    }
3998
3999    #[test]
4000    fn ra_fixture() {
4001        check(
4002            r##"
4003fn fixture(#[rust_analyzer::rust_fixture] ra_fixture: &str) {}
4004
4005fn foo() {
4006    fixture(r#"
4007fn foo() {}
4008// ^^^
4009fn bar() {
4010    f$0oo();
4011}
4012    "#)
4013}
4014        "##,
4015        );
4016    }
4017
4018    #[test]
4019    fn regression_20038() {
4020        check(
4021            r#"
4022//- minicore: clone, fn
4023struct Map<Fut, F>(Fut, F);
4024
4025struct InspectFn<F>(F);
4026
4027trait FnOnce1<A> {
4028    type Output;
4029}
4030
4031trait Future1 {
4032    type Output;
4033}
4034
4035trait FusedFuture1: Future1 {
4036    fn is_terminated(&self) -> bool;
4037     //^^^^^^^^^^^^^
4038}
4039
4040impl<T, A, R> FnOnce1<A> for T
4041where
4042    T: FnOnce(A) -> R,
4043{
4044    type Output = R;
4045}
4046
4047impl<F, A> FnOnce1<A> for InspectFn<F>
4048where
4049    F: for<'a> FnOnce1<&'a A, Output = ()>,
4050{
4051    type Output = A;
4052}
4053
4054impl<Fut, F, T> Future1 for Map<Fut, F>
4055where
4056    Fut: Future1,
4057    F: FnOnce1<Fut::Output, Output = T>,
4058{
4059    type Output = T;
4060}
4061
4062impl<Fut, F, T> FusedFuture1 for Map<Fut, F>
4063where
4064    Fut: Future1,
4065    F: FnOnce1<Fut::Output, Output = T>,
4066{
4067    fn is_terminated(&self) -> bool {
4068        false
4069    }
4070}
4071
4072fn overflows<Fut, F>(inner: &Map<Fut, InspectFn<F>>)
4073where
4074    Map<Fut, InspectFn<F>>: FusedFuture1
4075{
4076    let _x = inner.is_terminated$0();
4077}
4078"#,
4079        )
4080    }
4081
4082    #[test]
4083    fn question_mark_on_result_goes_to_conversion() {
4084        check(
4085            r#"
4086//- minicore: try, result, from
4087
4088struct Foo;
4089struct Bar;
4090impl From<Foo> for Bar {
4091    fn from(_: Foo) -> Bar { Bar }
4092    // ^^^^
4093}
4094
4095fn foo() -> Result<(), Bar> {
4096    Err(Foo)?$0;
4097    Ok(())
4098}
4099        "#,
4100        );
4101    }
4102}