ide/
goto_definition.rs

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