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