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