Skip to main content

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