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    // macros in this position are not yet supported
2332    #[test]
2333    // FIXME
2334    #[should_panic]
2335    fn goto_doc_include_str() {
2336        check(
2337            r#"
2338//- /main.rs
2339#[rustc_builtin_macro]
2340macro_rules! include_str {}
2341
2342#[doc = include_str!("docs.md$0")]
2343struct Item;
2344
2345//- /docs.md
2346// docs
2347//^file
2348"#,
2349        );
2350    }
2351
2352    #[test]
2353    fn goto_shadow_include() {
2354        check(
2355            r#"
2356//- /main.rs
2357macro_rules! include {
2358    ("included.rs") => {}
2359}
2360
2361include!("included.rs$0");
2362
2363//- /included.rs
2364// empty
2365"#,
2366        );
2367    }
2368
2369    mod goto_impl_of_trait_fn {
2370        use super::check;
2371        #[test]
2372        fn cursor_on_impl() {
2373            check(
2374                r#"
2375trait Twait {
2376    fn a();
2377}
2378
2379struct Stwuct;
2380
2381impl Twait for Stwuct {
2382    fn a$0();
2383     //^
2384}
2385        "#,
2386            );
2387        }
2388        #[test]
2389        fn method_call() {
2390            check(
2391                r#"
2392trait Twait {
2393    fn a(&self);
2394}
2395
2396struct Stwuct;
2397
2398impl Twait for Stwuct {
2399    fn a(&self){};
2400     //^
2401}
2402fn f() {
2403    let s = Stwuct;
2404    s.a$0();
2405}
2406        "#,
2407            );
2408        }
2409        #[test]
2410        fn method_call_inside_block() {
2411            check(
2412                r#"
2413trait Twait {
2414    fn a(&self);
2415}
2416
2417fn outer() {
2418    struct Stwuct;
2419
2420    impl Twait for Stwuct {
2421        fn a(&self){}
2422         //^
2423    }
2424    fn f() {
2425        let s = Stwuct;
2426        s.a$0();
2427    }
2428}
2429        "#,
2430            );
2431        }
2432        #[test]
2433        fn path_call() {
2434            check(
2435                r#"
2436trait Twait {
2437    fn a(&self);
2438}
2439
2440struct Stwuct;
2441
2442impl Twait for Stwuct {
2443    fn a(&self){};
2444     //^
2445}
2446fn f() {
2447    let s = Stwuct;
2448    Stwuct::a$0(&s);
2449}
2450        "#,
2451            );
2452        }
2453        #[test]
2454        fn where_clause_can_work() {
2455            check(
2456                r#"
2457trait G {
2458    fn g(&self);
2459}
2460trait Bound{}
2461trait EA{}
2462struct Gen<T>(T);
2463impl <T:EA> G for Gen<T> {
2464    fn g(&self) {
2465    }
2466}
2467impl <T> G for Gen<T>
2468where T : Bound
2469{
2470    fn g(&self){
2471     //^
2472    }
2473}
2474struct A;
2475impl Bound for A{}
2476fn f() {
2477    let g = Gen::<A>(A);
2478    g.g$0();
2479}
2480                "#,
2481            );
2482        }
2483        #[test]
2484        fn wc_case_is_ok() {
2485            check(
2486                r#"
2487trait G {
2488    fn g(&self);
2489}
2490trait BParent{}
2491trait Bound: BParent{}
2492struct Gen<T>(T);
2493impl <T> G for Gen<T>
2494where T : Bound
2495{
2496    fn g(&self){
2497     //^
2498    }
2499}
2500struct A;
2501impl Bound for A{}
2502fn f() {
2503    let g = Gen::<A>(A);
2504    g.g$0();
2505}
2506"#,
2507            );
2508        }
2509
2510        #[test]
2511        fn method_call_defaulted() {
2512            check(
2513                r#"
2514trait Twait {
2515    fn a(&self) {}
2516     //^
2517}
2518
2519struct Stwuct;
2520
2521impl Twait for Stwuct {
2522}
2523fn f() {
2524    let s = Stwuct;
2525    s.a$0();
2526}
2527        "#,
2528            );
2529        }
2530
2531        #[test]
2532        fn method_call_on_generic() {
2533            check(
2534                r#"
2535trait Twait {
2536    fn a(&self) {}
2537     //^
2538}
2539
2540fn f<T: Twait>(s: T) {
2541    s.a$0();
2542}
2543        "#,
2544            );
2545        }
2546    }
2547
2548    #[test]
2549    fn goto_def_of_trait_impl_const() {
2550        check(
2551            r#"
2552trait Twait {
2553    const NOMS: bool;
2554       // ^^^^
2555}
2556
2557struct Stwuct;
2558
2559impl Twait for Stwuct {
2560    const NOMS$0: bool = true;
2561}
2562"#,
2563        );
2564    }
2565
2566    #[test]
2567    fn goto_def_of_trait_impl_type_alias() {
2568        check(
2569            r#"
2570trait Twait {
2571    type IsBad;
2572      // ^^^^^
2573}
2574
2575struct Stwuct;
2576
2577impl Twait for Stwuct {
2578    type IsBad$0 = !;
2579}
2580"#,
2581        );
2582    }
2583
2584    #[test]
2585    fn goto_def_derive_input() {
2586        check(
2587            r#"
2588        //- minicore:derive
2589        #[rustc_builtin_macro]
2590        pub macro Copy {}
2591               // ^^^^
2592        #[derive(Copy$0)]
2593        struct Foo;
2594                    "#,
2595        );
2596        check(
2597            r#"
2598//- minicore:derive
2599#[rustc_builtin_macro]
2600pub macro Copy {}
2601       // ^^^^
2602#[cfg_attr(feature = "false", derive)]
2603#[derive(Copy$0)]
2604struct Foo;
2605            "#,
2606        );
2607        check(
2608            r#"
2609//- minicore:derive
2610mod foo {
2611    #[rustc_builtin_macro]
2612    pub macro Copy {}
2613           // ^^^^
2614}
2615#[derive(foo::Copy$0)]
2616struct Foo;
2617            "#,
2618        );
2619        check(
2620            r#"
2621//- minicore:derive
2622mod foo {
2623 // ^^^
2624    #[rustc_builtin_macro]
2625    pub macro Copy {}
2626}
2627#[derive(foo$0::Copy)]
2628struct Foo;
2629            "#,
2630        );
2631    }
2632
2633    #[test]
2634    fn goto_def_in_macro_multi() {
2635        check(
2636            r#"
2637struct Foo {
2638    foo: ()
2639  //^^^
2640}
2641macro_rules! foo {
2642    ($ident:ident) => {
2643        fn $ident(Foo { $ident }: Foo) {}
2644    }
2645}
2646  foo!(foo$0);
2647     //^^^
2648     //^^^
2649"#,
2650        );
2651        check(
2652            r#"
2653fn bar() {}
2654 //^^^
2655struct bar;
2656     //^^^
2657macro_rules! foo {
2658    ($ident:ident) => {
2659        fn foo() {
2660            let _: $ident = $ident;
2661        }
2662    }
2663}
2664
2665foo!(bar$0);
2666"#,
2667        );
2668    }
2669
2670    #[test]
2671    fn goto_await_poll() {
2672        check(
2673            r#"
2674//- minicore: future
2675
2676struct MyFut;
2677
2678impl core::future::Future for MyFut {
2679    type Output = ();
2680
2681    fn poll(
2682     //^^^^
2683        self: std::pin::Pin<&mut Self>,
2684        cx: &mut std::task::Context<'_>
2685    ) -> std::task::Poll<Self::Output>
2686    {
2687        ()
2688    }
2689}
2690
2691fn f() {
2692    MyFut.await$0;
2693}
2694"#,
2695        );
2696    }
2697
2698    #[test]
2699    fn goto_await_into_future_poll() {
2700        check(
2701            r#"
2702//- minicore: future
2703
2704struct Futurable;
2705
2706impl core::future::IntoFuture for Futurable {
2707    type IntoFuture = MyFut;
2708}
2709
2710struct MyFut;
2711
2712impl core::future::Future for MyFut {
2713    type Output = ();
2714
2715    fn poll(
2716     //^^^^
2717        self: std::pin::Pin<&mut Self>,
2718        cx: &mut std::task::Context<'_>
2719    ) -> std::task::Poll<Self::Output>
2720    {
2721        ()
2722    }
2723}
2724
2725fn f() {
2726    Futurable.await$0;
2727}
2728"#,
2729        );
2730    }
2731
2732    #[test]
2733    fn goto_try_op() {
2734        check(
2735            r#"
2736//- minicore: try
2737
2738struct Struct;
2739
2740impl core::ops::Try for Struct {
2741    fn branch(
2742     //^^^^^^
2743        self
2744    ) {}
2745}
2746
2747fn f() {
2748    Struct?$0;
2749}
2750"#,
2751        );
2752    }
2753
2754    #[test]
2755    fn goto_index_op() {
2756        check(
2757            r#"
2758//- minicore: index
2759
2760struct Struct;
2761
2762impl core::ops::Index<usize> for Struct {
2763    fn index(
2764     //^^^^^
2765        self
2766    ) {}
2767}
2768
2769fn f() {
2770    Struct[0]$0;
2771}
2772"#,
2773        );
2774    }
2775
2776    #[test]
2777    fn goto_index_mut_op() {
2778        check(
2779            r#"
2780//- minicore: index
2781
2782struct Foo;
2783struct Bar;
2784
2785impl core::ops::Index<usize> for Foo {
2786    type Output = Bar;
2787
2788    fn index(&self, index: usize) -> &Self::Output {}
2789}
2790
2791impl core::ops::IndexMut<usize> for Foo {
2792    fn index_mut(&mut self, index: usize) -> &mut Self::Output {}
2793     //^^^^^^^^^
2794}
2795
2796fn f() {
2797    let mut foo = Foo;
2798    foo[0]$0 = Bar;
2799}
2800"#,
2801        );
2802    }
2803
2804    #[test]
2805    fn goto_prefix_op() {
2806        check(
2807            r#"
2808//- minicore: deref
2809
2810struct Struct;
2811
2812impl core::ops::Deref for Struct {
2813    fn deref(
2814     //^^^^^
2815        self
2816    ) {}
2817}
2818
2819fn f() {
2820    $0*Struct;
2821}
2822"#,
2823        );
2824    }
2825
2826    #[test]
2827    fn goto_deref_mut() {
2828        check(
2829            r#"
2830//- minicore: deref, deref_mut
2831
2832struct Foo;
2833struct Bar;
2834
2835impl core::ops::Deref for Foo {
2836    type Target = Bar;
2837    fn deref(&self) -> &Self::Target {}
2838}
2839
2840impl core::ops::DerefMut for Foo {
2841    fn deref_mut(&mut self) -> &mut Self::Target {}
2842     //^^^^^^^^^
2843}
2844
2845fn f() {
2846    let a = Foo;
2847    $0*a = Bar;
2848}
2849"#,
2850        );
2851    }
2852
2853    #[test]
2854    fn goto_bin_op() {
2855        check(
2856            r#"
2857//- minicore: add
2858
2859struct Struct;
2860
2861impl core::ops::Add for Struct {
2862    fn add(
2863     //^^^
2864        self
2865    ) {}
2866}
2867
2868fn f() {
2869    Struct +$0 Struct;
2870}
2871"#,
2872        );
2873    }
2874
2875    #[test]
2876    fn goto_bin_op_multiple_impl() {
2877        check(
2878            r#"
2879//- minicore: add
2880struct S;
2881impl core::ops::Add for S {
2882    fn add(
2883     //^^^
2884    ) {}
2885}
2886impl core::ops::Add<usize> for S {
2887    fn add(
2888    ) {}
2889}
2890
2891fn f() {
2892    S +$0 S
2893}
2894"#,
2895        );
2896
2897        check(
2898            r#"
2899//- minicore: add
2900struct S;
2901impl core::ops::Add for S {
2902    fn add(
2903    ) {}
2904}
2905impl core::ops::Add<usize> for S {
2906    fn add(
2907     //^^^
2908    ) {}
2909}
2910
2911fn f() {
2912    S +$0 0usize
2913}
2914"#,
2915        );
2916    }
2917
2918    #[test]
2919    fn path_call_multiple_trait_impl() {
2920        check(
2921            r#"
2922trait Trait<T> {
2923    fn f(_: T);
2924}
2925impl Trait<i32> for usize {
2926    fn f(_: i32) {}
2927     //^
2928}
2929impl Trait<i64> for usize {
2930    fn f(_: i64) {}
2931}
2932fn main() {
2933    usize::f$0(0i32);
2934}
2935"#,
2936        );
2937
2938        check(
2939            r#"
2940trait Trait<T> {
2941    fn f(_: T);
2942}
2943impl Trait<i32> for usize {
2944    fn f(_: i32) {}
2945}
2946impl Trait<i64> for usize {
2947    fn f(_: i64) {}
2948     //^
2949}
2950fn main() {
2951    usize::f$0(0i64);
2952}
2953"#,
2954        )
2955    }
2956
2957    #[test]
2958    fn query_impls_in_nearest_block() {
2959        check(
2960            r#"
2961struct S1;
2962impl S1 {
2963    fn e() -> () {}
2964}
2965fn f1() {
2966    struct S1;
2967    impl S1 {
2968        fn e() -> () {}
2969         //^
2970    }
2971    fn f2() {
2972        fn f3() {
2973            S1::e$0();
2974        }
2975    }
2976}
2977"#,
2978        );
2979
2980        check(
2981            r#"
2982struct S1;
2983impl S1 {
2984    fn e() -> () {}
2985}
2986fn f1() {
2987    struct S1;
2988    impl S1 {
2989        fn e() -> () {}
2990         //^
2991    }
2992    fn f2() {
2993        struct S2;
2994        S1::e$0();
2995    }
2996}
2997fn f12() {
2998    struct S1;
2999    impl S1 {
3000        fn e() -> () {}
3001    }
3002}
3003"#,
3004        );
3005
3006        check(
3007            r#"
3008struct S1;
3009impl S1 {
3010    fn e() -> () {}
3011     //^
3012}
3013fn f2() {
3014    struct S2;
3015    S1::e$0();
3016}
3017"#,
3018        );
3019    }
3020
3021    #[test]
3022    fn implicit_format_args() {
3023        check(
3024            r#"
3025//- minicore: fmt
3026fn test() {
3027    let a = "world";
3028     // ^
3029    format_args!("hello {a$0}");
3030}
3031"#,
3032        );
3033    }
3034
3035    #[test]
3036    fn goto_macro_def_from_macro_use() {
3037        check(
3038            r#"
3039//- /main.rs crate:main deps:mac
3040#[macro_use(foo$0)]
3041extern crate mac;
3042
3043//- /mac.rs crate:mac
3044#[macro_export]
3045macro_rules! foo {
3046           //^^^
3047    () => {};
3048}
3049            "#,
3050        );
3051
3052        check(
3053            r#"
3054//- /main.rs crate:main deps:mac
3055#[macro_use(foo, bar$0, baz)]
3056extern crate mac;
3057
3058//- /mac.rs crate:mac
3059#[macro_export]
3060macro_rules! foo {
3061    () => {};
3062}
3063
3064#[macro_export]
3065macro_rules! bar {
3066           //^^^
3067    () => {};
3068}
3069
3070#[macro_export]
3071macro_rules! baz {
3072    () => {};
3073}
3074            "#,
3075        );
3076    }
3077
3078    #[test]
3079    fn goto_shadowed_preludes_in_block_module() {
3080        check(
3081            r#"
3082//- /main.rs crate:main edition:2021 deps:core
3083pub struct S;
3084         //^
3085
3086fn main() {
3087    fn f() -> S$0 {
3088        fn inner() {} // forces a block def map
3089        return S;
3090    }
3091}
3092//- /core.rs crate:core
3093pub mod prelude {
3094    pub mod rust_2021 {
3095        pub enum S;
3096    }
3097}
3098        "#,
3099        );
3100    }
3101
3102    #[test]
3103    fn goto_def_on_return_kw() {
3104        check(
3105            r#"
3106macro_rules! N {
3107    ($i:ident, $x:expr, $blk:expr) => {
3108        for $i in 0..$x {
3109            $blk
3110        }
3111    };
3112}
3113
3114fn main() {
3115    fn f() {
3116 // ^^
3117        N!(i, 5, {
3118            println!("{}", i);
3119            return$0;
3120        });
3121
3122        for i in 1..5 {
3123            return;
3124        }
3125       (|| {
3126            return;
3127        })();
3128    }
3129}
3130"#,
3131        )
3132    }
3133
3134    #[test]
3135    fn goto_def_on_return_kw_in_closure() {
3136        check(
3137            r#"
3138macro_rules! N {
3139    ($i:ident, $x:expr, $blk:expr) => {
3140        for $i in 0..$x {
3141            $blk
3142        }
3143    };
3144}
3145
3146fn main() {
3147    fn f() {
3148        N!(i, 5, {
3149            println!("{}", i);
3150            return;
3151        });
3152
3153        for i in 1..5 {
3154            return;
3155        }
3156       (|| {
3157     // ^
3158            return$0;
3159        })();
3160    }
3161}
3162"#,
3163        )
3164    }
3165
3166    #[test]
3167    fn goto_def_on_break_kw() {
3168        check(
3169            r#"
3170fn main() {
3171    for i in 1..5 {
3172 // ^^^
3173        break$0;
3174    }
3175}
3176"#,
3177        )
3178    }
3179
3180    #[test]
3181    fn goto_def_on_continue_kw() {
3182        check(
3183            r#"
3184fn main() {
3185    for i in 1..5 {
3186 // ^^^
3187        continue$0;
3188    }
3189}
3190"#,
3191        )
3192    }
3193
3194    #[test]
3195    fn goto_def_on_break_kw_for_block() {
3196        check(
3197            r#"
3198fn main() {
3199    'a:{
3200 // ^^^
3201        break$0 'a;
3202    }
3203}
3204"#,
3205        )
3206    }
3207
3208    #[test]
3209    fn goto_def_on_break_with_label() {
3210        check(
3211            r#"
3212fn foo() {
3213    'outer: loop {
3214         // ^^^^
3215         'inner: loop {
3216            'innermost: loop {
3217            }
3218            break$0 'outer;
3219        }
3220    }
3221}
3222"#,
3223        );
3224    }
3225
3226    #[test]
3227    fn label_inside_macro() {
3228        check(
3229            r#"
3230macro_rules! m {
3231    ($s:stmt) => { $s };
3232}
3233
3234fn foo() {
3235    'label: loop {
3236 // ^^^^^^
3237        m!(continue 'label$0);
3238    }
3239}
3240"#,
3241        );
3242    }
3243
3244    #[test]
3245    fn goto_def_on_return_in_try() {
3246        check(
3247            r#"
3248fn main() {
3249    fn f() {
3250 // ^^
3251        try {
3252            return$0;
3253        }
3254
3255        return;
3256    }
3257}
3258"#,
3259        )
3260    }
3261
3262    #[test]
3263    fn goto_def_on_break_in_try() {
3264        check(
3265            r#"
3266fn main() {
3267    for i in 1..100 {
3268 // ^^^
3269        let x: Result<(), ()> = try {
3270            break$0;
3271        };
3272    }
3273}
3274"#,
3275        )
3276    }
3277
3278    #[test]
3279    fn goto_def_on_return_in_async_block() {
3280        check(
3281            r#"
3282fn main() {
3283    async {
3284 // ^^^^^
3285        return$0;
3286    }
3287}
3288"#,
3289        )
3290    }
3291
3292    #[test]
3293    fn goto_def_on_for_kw() {
3294        check(
3295            r#"
3296fn main() {
3297    for$0 i in 1..5 {}
3298 // ^^^
3299}
3300"#,
3301        )
3302    }
3303
3304    #[test]
3305    fn goto_def_on_fn_kw() {
3306        check(
3307            r#"
3308fn main() {
3309    fn$0 foo() {}
3310 // ^^
3311}
3312"#,
3313        )
3314    }
3315
3316    #[test]
3317    fn shadow_builtin_macro() {
3318        check(
3319            r#"
3320//- minicore: column
3321//- /a.rs crate:a
3322#[macro_export]
3323macro_rules! column { () => {} }
3324          // ^^^^^^
3325
3326//- /b.rs crate:b deps:a
3327use a::column;
3328fn foo() {
3329    $0column!();
3330}
3331        "#,
3332        );
3333    }
3334
3335    #[test]
3336    fn issue_18138() {
3337        check(
3338            r#"
3339mod foo {
3340    macro_rules! x {
3341        () => {
3342            pub struct Foo;
3343                    // ^^^
3344        };
3345    }
3346    pub(crate) use x as m;
3347}
3348
3349mod bar {
3350    use crate::m;
3351
3352    m!();
3353 // ^^
3354
3355    fn qux() {
3356        Foo$0;
3357    }
3358}
3359
3360mod m {}
3361
3362use foo::m;
3363"#,
3364        );
3365    }
3366
3367    #[test]
3368    fn macro_label_hygiene() {
3369        check(
3370            r#"
3371macro_rules! m {
3372    ($x:stmt) => {
3373        'bar: loop { $x }
3374    };
3375}
3376
3377fn foo() {
3378    'bar: loop {
3379 // ^^^^
3380        m!(continue 'bar$0);
3381    }
3382}
3383"#,
3384        );
3385    }
3386    #[test]
3387    fn into_call_to_from_definition() {
3388        check(
3389            r#"
3390//- minicore: from
3391struct A;
3392
3393struct B;
3394
3395impl From<A> for B {
3396    fn from(value: A) -> Self {
3397     //^^^^
3398        B
3399    }
3400}
3401
3402fn f() {
3403    let a = A;
3404    let b: B = a.into$0();
3405}
3406        "#,
3407        );
3408    }
3409
3410    #[test]
3411    fn into_call_to_from_definition_within_macro() {
3412        check(
3413            r#"
3414//- proc_macros: identity
3415//- minicore: from
3416struct A;
3417
3418struct B;
3419
3420impl From<A> for B {
3421    fn from(value: A) -> Self {
3422     //^^^^
3423        B
3424    }
3425}
3426
3427#[proc_macros::identity]
3428fn f() {
3429    let a = A;
3430    let b: B = a.into$0();
3431}
3432        "#,
3433        );
3434    }
3435
3436    #[test]
3437    fn into_call_to_from_definition_with_trait_bounds() {
3438        check(
3439            r#"
3440//- minicore: from, iterator
3441struct A;
3442
3443impl<T> From<T> for A
3444where
3445    T: IntoIterator<Item = i64>,
3446{
3447    fn from(value: T) -> Self {
3448     //^^^^
3449        A
3450    }
3451}
3452
3453fn f() {
3454    let a: A = [1, 2, 3].into$0();
3455}
3456        "#,
3457        );
3458    }
3459
3460    #[test]
3461    fn goto_into_definition_if_exists() {
3462        check(
3463            r#"
3464//- minicore: from
3465struct A;
3466
3467struct B;
3468
3469impl Into<B> for A {
3470    fn into(self) -> B {
3471     //^^^^
3472        B
3473    }
3474}
3475
3476fn f() {
3477    let a = A;
3478    let b: B = a.into$0();
3479}
3480        "#,
3481        );
3482    }
3483
3484    #[test]
3485    fn try_into_call_to_try_from_definition() {
3486        check(
3487            r#"
3488//- minicore: from
3489struct A;
3490
3491struct B;
3492
3493impl TryFrom<A> for B {
3494    type Error = String;
3495
3496    fn try_from(value: A) -> Result<Self, Self::Error> {
3497     //^^^^^^^^
3498        Ok(B)
3499    }
3500}
3501
3502fn f() {
3503    let a = A;
3504    let b: Result<B, _> = a.try_into$0();
3505}
3506        "#,
3507        );
3508    }
3509
3510    #[test]
3511    fn goto_try_into_definition_if_exists() {
3512        check(
3513            r#"
3514//- minicore: from
3515struct A;
3516
3517struct B;
3518
3519impl TryInto<B> for A {
3520    type Error = String;
3521
3522    fn try_into(self) -> Result<B, Self::Error> {
3523     //^^^^^^^^
3524        Ok(B)
3525    }
3526}
3527
3528fn f() {
3529    let a = A;
3530    let b: Result<B, _> = a.try_into$0();
3531}
3532        "#,
3533        );
3534    }
3535
3536    #[test]
3537    fn parse_call_to_from_str_definition() {
3538        check(
3539            r#"
3540//- minicore: from, str
3541struct A;
3542impl FromStr for A {
3543    type Error = String;
3544    fn from_str(value: &str) -> Result<Self, Self::Error> {
3545     //^^^^^^^^
3546        Ok(A)
3547    }
3548}
3549fn f() {
3550    let a: Result<A, _> = "aaaaaa".parse$0();
3551}
3552        "#,
3553        );
3554    }
3555
3556    #[test]
3557    fn to_string_call_to_display_definition() {
3558        check(
3559            r#"
3560//- minicore:fmt
3561//- /alloc.rs crate:alloc
3562pub mod string {
3563    pub struct String;
3564    pub trait ToString {
3565        fn to_string(&self) -> String;
3566    }
3567
3568    impl<T: core::fmt::Display> ToString for T {
3569        fn to_string(&self) -> String { String }
3570    }
3571}
3572//- /lib.rs crate:lib deps:alloc
3573use alloc::string::ToString;
3574struct A;
3575impl core::fmt::Display for A {
3576    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {}
3577    // ^^^
3578}
3579fn f() {
3580    A.to_string$0();
3581}
3582        "#,
3583        );
3584    }
3585
3586    #[test]
3587    fn use_inside_body() {
3588        check(
3589            r#"
3590fn main() {
3591    mod nice_module {
3592        pub(super) struct NiceStruct;
3593                       // ^^^^^^^^^^
3594    }
3595
3596    use nice_module::NiceStruct$0;
3597
3598    let _ = NiceStruct;
3599}
3600    "#,
3601        );
3602    }
3603
3604    #[test]
3605    fn shadow_builtin_type_by_module() {
3606        check(
3607            r#"
3608mod Foo{
3609pub mod str {
3610     // ^^^
3611    pub fn foo() {}
3612}
3613}
3614
3615fn main() {
3616    use Foo::str;
3617    let s = st$0r::foo();
3618}
3619"#,
3620        );
3621    }
3622
3623    #[test]
3624    fn not_goto_module_because_str_is_builtin_type() {
3625        check(
3626            r#"
3627mod str {
3628pub fn foo() {}
3629}
3630
3631fn main() {
3632    let s = st$0r::f();
3633}
3634"#,
3635        );
3636    }
3637
3638    #[test]
3639    fn struct_shadow_by_module() {
3640        check(
3641            r#"
3642mod foo {
3643    pub mod bar {
3644         // ^^^
3645        pub type baz = usize;
3646    }
3647}
3648struct bar;
3649fn main() {
3650    use foo::bar;
3651    let x: ba$0r::baz = 5;
3652
3653}
3654"#,
3655        );
3656    }
3657
3658    #[test]
3659    fn type_alias_shadow_by_module() {
3660        check(
3661            r#"
3662mod foo {
3663    pub mod bar {
3664         // ^^^
3665        pub fn baz() {}
3666    }
3667}
3668
3669trait Qux {}
3670
3671fn item<bar: Qux>() {
3672    use foo::bar;
3673    ba$0r::baz();
3674}
3675}
3676"#,
3677        );
3678
3679        check(
3680            r#"
3681mod foo {
3682    pub mod bar {
3683         // ^^^
3684        pub fn baz() {}
3685    }
3686}
3687
3688fn item<bar>(x: bar) {
3689    use foo::bar;
3690    let x: bar$0 = x;
3691}
3692"#,
3693        );
3694    }
3695
3696    #[test]
3697    fn trait_shadow_by_module() {
3698        check(
3699            r#"
3700pub mod foo {
3701    pub mod Bar {}
3702         // ^^^
3703}
3704
3705trait Bar {}
3706
3707fn main() {
3708    use foo::Bar;
3709    fn f<Qux: B$0ar>() {}
3710}
3711            "#,
3712        );
3713    }
3714
3715    #[test]
3716    fn const_shadow_by_module() {
3717        check(
3718            r#"
3719pub mod foo {
3720    pub struct u8 {}
3721    pub mod bar {
3722        pub mod u8 {}
3723    }
3724}
3725
3726fn main() {
3727    use foo::u8;
3728    {
3729        use foo::bar::u8;
3730
3731        fn f1<const N: u$08>() {}
3732    }
3733    fn f2<const N: u8>() {}
3734}
3735"#,
3736        );
3737
3738        check(
3739            r#"
3740pub mod foo {
3741    pub struct u8 {}
3742            // ^^
3743    pub mod bar {
3744        pub mod u8 {}
3745    }
3746}
3747
3748fn main() {
3749    use foo::u8;
3750    {
3751        use foo::bar::u8;
3752
3753        fn f1<const N: u8>() {}
3754    }
3755    fn f2<const N: u$08>() {}
3756}
3757"#,
3758        );
3759
3760        check(
3761            r#"
3762pub mod foo {
3763    pub struct buz {}
3764    pub mod bar {
3765        pub mod buz {}
3766             // ^^^
3767    }
3768}
3769
3770fn main() {
3771    use foo::buz;
3772    {
3773        use foo::bar::buz;
3774
3775        fn f1<const N: buz$0>() {}
3776    }
3777}
3778"#,
3779        );
3780    }
3781
3782    #[test]
3783    fn offset_of() {
3784        check(
3785            r#"
3786//- minicore: offset_of
3787struct Foo {
3788    field: i32,
3789 // ^^^^^
3790}
3791
3792fn foo() {
3793    let _ = core::mem::offset_of!(Foo, fiel$0d);
3794}
3795        "#,
3796        );
3797
3798        check(
3799            r#"
3800//- minicore: offset_of
3801struct Bar(Foo);
3802struct Foo {
3803    field: i32,
3804 // ^^^^^
3805}
3806
3807fn foo() {
3808    let _ = core::mem::offset_of!(Bar, 0.fiel$0d);
3809}
3810        "#,
3811        );
3812
3813        check(
3814            r#"
3815//- minicore: offset_of
3816struct Bar(Baz);
3817enum Baz {
3818    Abc(Foo),
3819    None,
3820}
3821struct Foo {
3822    field: i32,
3823 // ^^^^^
3824}
3825
3826fn foo() {
3827    let _ = core::mem::offset_of!(Bar, 0.Abc.0.fiel$0d);
3828}
3829        "#,
3830        );
3831
3832        check(
3833            r#"
3834//- minicore: offset_of
3835struct Bar(Baz);
3836enum Baz {
3837    Abc(Foo),
3838 // ^^^
3839    None,
3840}
3841struct Foo {
3842    field: i32,
3843}
3844
3845fn foo() {
3846    let _ = core::mem::offset_of!(Bar, 0.Ab$0c.0.field);
3847}
3848        "#,
3849        );
3850    }
3851
3852    #[test]
3853    fn goto_def_for_match_keyword() {
3854        check(
3855            r#"
3856fn main() {
3857    match$0 0 {
3858 // ^^^^^
3859        0 => {},
3860        _ => {},
3861    }
3862}
3863"#,
3864        );
3865    }
3866
3867    #[test]
3868    fn goto_def_for_match_arm_fat_arrow() {
3869        check(
3870            r#"
3871fn main() {
3872    match 0 {
3873        0 =>$0 {},
3874       // ^^
3875        _ => {},
3876    }
3877}
3878"#,
3879        );
3880    }
3881
3882    #[test]
3883    fn goto_def_for_if_keyword() {
3884        check(
3885            r#"
3886fn main() {
3887    if$0 true {
3888 // ^^
3889        ()
3890    }
3891}
3892"#,
3893        );
3894    }
3895
3896    #[test]
3897    fn goto_def_for_match_nested_in_if() {
3898        check(
3899            r#"
3900fn main() {
3901    if true {
3902        match$0 0 {
3903     // ^^^^^
3904            0 => {},
3905            _ => {},
3906        }
3907    }
3908}
3909"#,
3910        );
3911    }
3912
3913    #[test]
3914    fn goto_def_for_multiple_match_expressions() {
3915        check(
3916            r#"
3917fn main() {
3918    match 0 {
3919        0 => {},
3920        _ => {},
3921    };
3922
3923    match$0 1 {
3924 // ^^^^^
3925        1 => {},
3926        _ => {},
3927    }
3928}
3929"#,
3930        );
3931    }
3932
3933    #[test]
3934    fn goto_def_for_nested_match_expressions() {
3935        check(
3936            r#"
3937fn main() {
3938    match 0 {
3939        0 => match$0 1 {
3940          // ^^^^^
3941            1 => {},
3942            _ => {},
3943        },
3944        _ => {},
3945    }
3946}
3947"#,
3948        );
3949    }
3950
3951    #[test]
3952    fn goto_def_for_if_else_chains() {
3953        check(
3954            r#"
3955fn main() {
3956    if true {
3957 // ^^
3958        ()
3959    } else if$0 false {
3960        ()
3961    } else {
3962        ()
3963    }
3964}
3965"#,
3966        );
3967    }
3968
3969    #[test]
3970    fn goto_def_for_match_with_guards() {
3971        check(
3972            r#"
3973fn main() {
3974    match 42 {
3975        x if x > 0 =>$0 {},
3976                // ^^
3977        _ => {},
3978    }
3979}
3980"#,
3981        );
3982    }
3983
3984    #[test]
3985    fn goto_def_for_match_with_macro_arm() {
3986        check(
3987            r#"
3988macro_rules! arm {
3989    () => { 0 => {} };
3990}
3991
3992fn main() {
3993    match$0 0 {
3994 // ^^^^^
3995        arm!(),
3996        _ => {},
3997    }
3998}
3999"#,
4000        );
4001    }
4002
4003    #[test]
4004    fn goto_const_from_match_pat_with_tuple_struct() {
4005        check(
4006            r#"
4007struct Tag(u8);
4008struct Path {}
4009
4010const Path: u8 = 0;
4011   // ^^^^
4012fn main() {
4013    match Tag(Path) {
4014        Tag(Path$0) => {}
4015        _ => {}
4016    }
4017}
4018
4019"#,
4020        );
4021    }
4022
4023    #[test]
4024    fn goto_const_from_match_pat() {
4025        check(
4026            r#"
4027type T1 = u8;
4028const T1: u8 = 0;
4029   // ^^
4030fn main() {
4031    let x = 0;
4032    match x {
4033        T1$0 => {}
4034        _ => {}
4035    }
4036}
4037"#,
4038        );
4039    }
4040
4041    #[test]
4042    fn goto_struct_from_match_pat() {
4043        check(
4044            r#"
4045struct T1;
4046    // ^^
4047fn main() {
4048    let x = 0;
4049    match x {
4050        T1$0 => {}
4051        _ => {}
4052    }
4053}
4054"#,
4055        );
4056    }
4057
4058    #[test]
4059    fn no_goto_trait_from_match_pat() {
4060        check(
4061            r#"
4062trait T1 {}
4063fn main() {
4064    let x = 0;
4065    match x {
4066        T1$0 => {}
4067     // ^^
4068        _ => {}
4069    }
4070}
4071"#,
4072        );
4073    }
4074
4075    #[test]
4076    fn goto_builtin_type() {
4077        check(
4078            r#"
4079//- /main.rs crate:main deps:std
4080const _: &str$0 = ""; }
4081
4082//- /libstd.rs crate:std
4083mod prim_str {}
4084//  ^^^^^^^^
4085"#,
4086        );
4087    }
4088
4089    #[test]
4090    fn ra_fixture() {
4091        check(
4092            r##"
4093fn fixture(#[rust_analyzer::rust_fixture] ra_fixture: &str) {}
4094
4095fn foo() {
4096    fixture(r#"
4097fn foo() {}
4098// ^^^
4099fn bar() {
4100    f$0oo();
4101}
4102    "#)
4103}
4104        "##,
4105        );
4106    }
4107
4108    #[test]
4109    fn regression_20038() {
4110        check(
4111            r#"
4112//- minicore: clone, fn
4113struct Map<Fut, F>(Fut, F);
4114
4115struct InspectFn<F>(F);
4116
4117trait FnOnce1<A> {
4118    type Output;
4119}
4120
4121trait Future1 {
4122    type Output;
4123}
4124
4125trait FusedFuture1: Future1 {
4126    fn is_terminated(&self) -> bool;
4127     //^^^^^^^^^^^^^
4128}
4129
4130impl<T, A, R> FnOnce1<A> for T
4131where
4132    T: FnOnce(A) -> R,
4133{
4134    type Output = R;
4135}
4136
4137impl<F, A> FnOnce1<A> for InspectFn<F>
4138where
4139    F: for<'a> FnOnce1<&'a A, Output = ()>,
4140{
4141    type Output = A;
4142}
4143
4144impl<Fut, F, T> Future1 for Map<Fut, F>
4145where
4146    Fut: Future1,
4147    F: FnOnce1<Fut::Output, Output = T>,
4148{
4149    type Output = T;
4150}
4151
4152impl<Fut, F, T> FusedFuture1 for Map<Fut, F>
4153where
4154    Fut: Future1,
4155    F: FnOnce1<Fut::Output, Output = T>,
4156{
4157    fn is_terminated(&self) -> bool {
4158        false
4159    }
4160}
4161
4162fn overflows<Fut, F>(inner: &Map<Fut, InspectFn<F>>)
4163where
4164    Map<Fut, InspectFn<F>>: FusedFuture1
4165{
4166    let _x = inner.is_terminated$0();
4167}
4168"#,
4169        )
4170    }
4171
4172    #[test]
4173    fn question_mark_on_result_goes_to_conversion() {
4174        check(
4175            r#"
4176//- minicore: try, result, from
4177
4178struct Foo;
4179struct Bar;
4180impl From<Foo> for Bar {
4181    fn from(_: Foo) -> Bar { Bar }
4182    // ^^^^
4183}
4184
4185fn foo() -> Result<(), Bar> {
4186    Err(Foo)?$0;
4187    Ok(())
4188}
4189        "#,
4190        );
4191    }
4192
4193    #[test]
4194    fn goto_definition_for_comparison_operators() {
4195        check(
4196            r#"
4197//- minicore: eq, ord
4198struct Foo;
4199impl PartialEq for Foo {
4200    fn eq(&self, other: &Self) -> bool { true }
4201     //^^
4202}
4203
4204fn main() {
4205    let a = Foo;
4206    let b = Foo;
4207    let _ = a !=$0 b;
4208}
4209"#,
4210        );
4211    }
4212
4213    #[test]
4214    fn ide_features_work_in_field_default() {
4215        check(
4216            r#"
4217struct S;
4218impl S {
4219    fn foo(&self) {}
4220    // ^^^
4221}
4222
4223struct Struct {
4224    field: () = S.foo$0(),
4225}
4226        "#,
4227        );
4228    }
4229}