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