aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/base_db/src/fixture.rs45
-rw-r--r--crates/cfg/src/lib.rs17
-rw-r--r--crates/hir/src/has_source.rs2
-rw-r--r--crates/hir/src/lib.rs12
-rw-r--r--crates/hir/src/semantics.rs17
-rw-r--r--crates/hir_def/src/generics.rs10
-rw-r--r--crates/hir_def/src/item_tree/lower.rs2
-rw-r--r--crates/hir_def/src/item_tree/pretty.rs4
-rw-r--r--crates/hir_def/src/nameres/collector.rs41
-rw-r--r--crates/hir_def/src/resolver.rs6
-rw-r--r--crates/hir_def/src/visibility.rs5
-rw-r--r--crates/hir_expand/src/builtin_macro.rs4
-rw-r--r--crates/hir_expand/src/hygiene.rs9
-rw-r--r--crates/hir_expand/src/lib.rs9
-rw-r--r--crates/hir_ty/Cargo.toml2
-rw-r--r--crates/hir_ty/src/chalk_db.rs5
-rw-r--r--crates/hir_ty/src/consteval.rs3
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs2
-rw-r--r--crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs9
-rw-r--r--crates/hir_ty/src/infer/coerce.rs8
-rw-r--r--crates/hir_ty/src/infer/expr.rs26
-rw-r--r--crates/hir_ty/src/infer/pat.rs11
-rw-r--r--crates/hir_ty/src/lower.rs2
-rw-r--r--crates/hir_ty/src/op.rs38
-rw-r--r--crates/hir_ty/src/test_db.rs10
-rw-r--r--crates/hir_ty/src/tests.rs235
-rw-r--r--crates/hir_ty/src/tests/coercion.rs1017
-rw-r--r--crates/hir_ty/src/tests/display_source_code.rs10
-rw-r--r--crates/hir_ty/src/tests/macros.rs29
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs363
-rw-r--r--crates/hir_ty/src/tests/patterns.rs80
-rw-r--r--crates/hir_ty/src/tests/regression.rs280
-rw-r--r--crates/hir_ty/src/tests/simple.rs793
-rw-r--r--crates/hir_ty/src/tests/traits.rs1086
-rw-r--r--crates/ide/Cargo.toml1
-rw-r--r--crates/ide/src/diagnostics.rs498
-rw-r--r--crates/ide/src/display/navigation_target.rs6
-rw-r--r--crates/ide/src/doc_links.rs18
-rw-r--r--crates/ide/src/fixture.rs8
-rw-r--r--crates/ide/src/goto_definition.rs10
-rw-r--r--crates/ide/src/goto_implementation.rs7
-rw-r--r--crates/ide/src/goto_type_definition.rs60
-rw-r--r--crates/ide/src/hover.rs47
-rw-r--r--crates/ide/src/inlay_hints.rs52
-rw-r--r--crates/ide/src/join_lines.rs2
-rw-r--r--crates/ide/src/lib.rs26
-rw-r--r--crates/ide/src/references.rs5
-rw-r--r--crates/ide/src/rename.rs (renamed from crates/ide/src/references/rename.rs)460
-rw-r--r--crates/ide/src/syntax_highlighting.rs4
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs50
-rw-r--r--crates/ide/src/syntax_highlighting/html.rs1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_injection.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_strings.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html6
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/injection.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html1
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs5
-rw-r--r--crates/ide/src/typing.rs36
-rw-r--r--crates/ide_assists/src/handlers/apply_demorgan.rs114
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs3
-rw-r--r--crates/ide_assists/src/handlers/convert_into_to_from.rs50
-rw-r--r--crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs135
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs747
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs29
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs45
-rw-r--r--crates/ide_assists/src/handlers/fix_visibility.rs34
-rw-r--r--crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs41
-rw-r--r--crates/ide_assists/src/handlers/generate_default_from_new.rs83
-rw-r--r--crates/ide_assists/src/handlers/generate_deref.rs27
-rw-r--r--crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs105
-rw-r--r--crates/ide_assists/src/handlers/generate_function.rs49
-rw-r--r--crates/ide_assists/src/handlers/inline_local_variable.rs55
-rw-r--r--crates/ide_assists/src/handlers/move_module_to_file.rs65
-rw-r--r--crates/ide_assists/src/handlers/qualify_path.rs1201
-rw-r--r--crates/ide_assists/src/handlers/remove_dbg.rs4
-rw-r--r--crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs173
-rw-r--r--crates/ide_assists/src/handlers/replace_if_let_with_match.rs66
-rw-r--r--crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs5
-rw-r--r--crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs13
-rw-r--r--crates/ide_assists/src/handlers/replace_unwrap_with_match.rs60
-rw-r--r--crates/ide_assists/src/handlers/unmerge_use.rs16
-rw-r--r--crates/ide_assists/src/lib.rs164
-rw-r--r--crates/ide_assists/src/tests.rs35
-rw-r--r--crates/ide_assists/src/tests/generated.rs27
-rw-r--r--crates/ide_assists/src/utils.rs6
-rw-r--r--crates/ide_completion/src/completions.rs134
-rw-r--r--crates/ide_completion/src/completions/attribute.rs7
-rw-r--r--crates/ide_completion/src/completions/attribute/derive.rs66
-rw-r--r--crates/ide_completion/src/completions/attribute/lint.rs3
-rw-r--r--crates/ide_completion/src/completions/attribute/repr.rs199
-rw-r--r--crates/ide_completion/src/completions/dot.rs9
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs6
-rw-r--r--crates/ide_completion/src/completions/fn_param.rs4
-rw-r--r--crates/ide_completion/src/completions/keyword.rs278
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs13
-rw-r--r--crates/ide_completion/src/completions/mod_.rs138
-rw-r--r--crates/ide_completion/src/completions/pattern.rs397
-rw-r--r--crates/ide_completion/src/completions/postfix.rs31
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs336
-rw-r--r--crates/ide_completion/src/completions/record.rs30
-rw-r--r--crates/ide_completion/src/completions/snippet.rs32
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs313
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs278
-rw-r--r--crates/ide_completion/src/context.rs156
-rw-r--r--crates/ide_completion/src/item.rs2
-rw-r--r--crates/ide_completion/src/lib.rs123
-rw-r--r--crates/ide_completion/src/patterns.rs44
-rw-r--r--crates/ide_completion/src/render.rs212
-rw-r--r--crates/ide_completion/src/render/builder_ext.rs4
-rw-r--r--crates/ide_completion/src/render/enum_variant.rs2
-rw-r--r--crates/ide_completion/src/render/function.rs2
-rw-r--r--crates/ide_completion/src/render/macro_.rs8
-rw-r--r--crates/ide_completion/src/tests.rs (renamed from crates/ide_completion/src/test_utils.rs)74
-rw-r--r--crates/ide_completion/src/tests/item_list.rs223
-rw-r--r--crates/ide_completion/src/tests/items.rs95
-rw-r--r--crates/ide_completion/src/tests/pattern.rs348
-rw-r--r--crates/ide_completion/src/tests/type_pos.rs177
-rw-r--r--crates/ide_completion/src/tests/use_tree.rs255
-rw-r--r--crates/ide_db/src/assists.rs136
-rw-r--r--crates/ide_db/src/helpers.rs11
-rw-r--r--crates/ide_db/src/helpers/famous_defs_fixture.rs153
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs78
-rw-r--r--crates/ide_db/src/helpers/insert_use/tests.rs172
-rw-r--r--crates/ide_db/src/lib.rs6
-rw-r--r--crates/ide_db/src/path_transform.rs (renamed from crates/ide_assists/src/path_transform.rs)12
-rw-r--r--crates/ide_db/src/rename.rs468
-rw-r--r--crates/ide_diagnostics/Cargo.toml29
-rw-r--r--crates/ide_diagnostics/src/handlers/break_outside_of_loop.rs (renamed from crates/ide/src/diagnostics/break_outside_of_loop.rs)8
-rw-r--r--crates/ide_diagnostics/src/handlers/field_shorthand.rs (renamed from crates/ide/src/diagnostics/field_shorthand.rs)6
-rw-r--r--crates/ide_diagnostics/src/handlers/inactive_code.rs (renamed from crates/ide/src/diagnostics/inactive_code.rs)35
-rw-r--r--crates/ide_diagnostics/src/handlers/incorrect_case.rs (renamed from crates/ide/src/diagnostics/incorrect_case.rs)115
-rw-r--r--crates/ide_diagnostics/src/handlers/macro_error.rs (renamed from crates/ide/src/diagnostics/macro_error.rs)26
-rw-r--r--crates/ide_diagnostics/src/handlers/mismatched_arg_count.rs (renamed from crates/ide/src/diagnostics/mismatched_arg_count.rs)28
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_fields.rs (renamed from crates/ide/src/diagnostics/missing_fields.rs)42
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_match_arms.rs (renamed from crates/ide/src/diagnostics/missing_match_arms.rs)106
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs (renamed from crates/ide/src/diagnostics/missing_ok_or_some_in_tail_expr.rs)85
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_unsafe.rs (renamed from crates/ide/src/diagnostics/missing_unsafe.rs)16
-rw-r--r--crates/ide_diagnostics/src/handlers/no_such_field.rs (renamed from crates/ide/src/diagnostics/no_such_field.rs)13
-rw-r--r--crates/ide_diagnostics/src/handlers/remove_this_semicolon.rs (renamed from crates/ide/src/diagnostics/remove_this_semicolon.rs)11
-rw-r--r--crates/ide_diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs (renamed from crates/ide/src/diagnostics/replace_filter_map_next_with_find_map.rs)93
-rw-r--r--crates/ide_diagnostics/src/handlers/unimplemented_builtin_macro.rs (renamed from crates/ide/src/diagnostics/unimplemented_builtin_macro.rs)7
-rw-r--r--crates/ide_diagnostics/src/handlers/unlinked_file.rs (renamed from crates/ide/src/diagnostics/unlinked_file.rs)30
-rw-r--r--crates/ide_diagnostics/src/handlers/unresolved_extern_crate.rs (renamed from crates/ide/src/diagnostics/unresolved_extern_crate.rs)10
-rw-r--r--crates/ide_diagnostics/src/handlers/unresolved_import.rs (renamed from crates/ide/src/diagnostics/unresolved_import.rs)24
-rw-r--r--crates/ide_diagnostics/src/handlers/unresolved_macro_call.rs (renamed from crates/ide/src/diagnostics/unresolved_macro_call.rs)14
-rw-r--r--crates/ide_diagnostics/src/handlers/unresolved_module.rs (renamed from crates/ide/src/diagnostics/unresolved_module.rs)11
-rw-r--r--crates/ide_diagnostics/src/handlers/unresolved_proc_macro.rs (renamed from crates/ide/src/diagnostics/unresolved_proc_macro.rs)7
-rw-r--r--crates/ide_diagnostics/src/handlers/useless_braces.rs148
-rw-r--r--crates/ide_diagnostics/src/lib.rs374
-rw-r--r--crates/mbe/src/expander/matcher.rs22
-rw-r--r--crates/parser/src/grammar/params.rs3
-rw-r--r--crates/proc_macro_api/src/version.rs10
-rw-r--r--crates/project_model/src/build_data.rs4
-rw-r--r--crates/project_model/src/cargo_workspace.rs17
-rw-r--r--crates/project_model/src/lib.rs2
-rw-r--r--crates/project_model/src/sysroot.rs11
-rw-r--r--crates/project_model/src/workspace.rs124
-rw-r--r--crates/rust-analyzer/src/config.rs22
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt2
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt2
-rw-r--r--crates/rust-analyzer/src/integrated_benchmarks.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs1
-rw-r--r--crates/rust-analyzer/tests/slow-tests/support.rs4
-rw-r--r--crates/syntax/src/ast/node_ext.rs34
-rw-r--r--crates/syntax/test_data/lexer/err/0001_unclosed_char_at_eof.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0002_unclosed_char_with_ferris.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0003_unclosed_char_with_ascii_escape.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0004_unclosed_char_with_unicode_escape.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0005_unclosed_char_with_space.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0006_unclosed_char_with_slash.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0007_unclosed_char_with_slash_n.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0008_unclosed_char_with_slash_single_quote.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0009_unclosed_byte_at_eof.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0010_unclosed_byte_with_ferris.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0011_unclosed_byte_with_ascii_escape.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0012_unclosed_byte_with_unicode_escape.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0013_unclosed_byte_with_space.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0014_unclosed_byte_with_slash.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0015_unclosed_byte_with_slash_n.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0016_unclosed_byte_with_slash_single_quote.txt4
-rw-r--r--crates/syntax/test_data/lexer/err/0057_lifetime_starts_with_a_number.txt8
-rw-r--r--crates/syntax/test_data/lexer/ok/0006_chars.txt16
-rw-r--r--crates/syntax/test_data/lexer/ok/0007_lifetimes.txt8
-rw-r--r--crates/syntax/test_data/lexer/ok/0008_byte_strings.txt14
-rw-r--r--crates/syntax/test_data/parser/err/0024_many_type_parens.rast16
-rw-r--r--crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast2
-rw-r--r--crates/syntax/test_data/parser/err/0043_weird_blocks.rast2
-rw-r--r--crates/syntax/test_data/parser/err/0044_unexpected_for_type.rast30
-rw-r--r--crates/syntax/test_data/parser/err/0046_ambiguous_trait_object.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast2
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0003_where_pred_for.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0006_self_param.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast2
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0015_continue_expr.rast2
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0033_reference_type;.rast2
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0034_break_expr.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast2
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast2
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0055_literal_pattern.rast2
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0056_where_clause.rast12
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0081_for_type.rast10
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0085_expr_literals.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0109_label.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0154_no_dyn_trait_leading_for.rast4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0161_labeled_block.rast2
-rw-r--r--crates/syntax/test_data/parser/ok/0011_outer_attribute.rast2
-rw-r--r--crates/syntax/test_data/parser/ok/0011_outer_attribute.rs2
-rw-r--r--crates/syntax/test_data/parser/ok/0018_struct_type_params.rast34
-rw-r--r--crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast28
-rw-r--r--crates/syntax/test_data/parser/ok/0030_string_suffixes.rast4
-rw-r--r--crates/syntax/test_data/parser/ok/0032_where_for.rast4
-rw-r--r--crates/syntax/test_data/parser/ok/0033_label_break.rast14
-rw-r--r--crates/syntax/test_data/parser/ok/0035_weird_exprs.rast18
-rw-r--r--crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast12
-rw-r--r--crates/syntax/test_data/parser/ok/0067_where_for_pred.rast30
-rw-r--r--crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast6
-rw-r--r--crates/test_utils/src/fixture.rs194
-rw-r--r--crates/test_utils/src/lib.rs55
-rw-r--r--crates/test_utils/src/minicore.rs549
-rw-r--r--crates/vfs/src/vfs_path.rs2
228 files changed, 8634 insertions, 7953 deletions
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs
index da4afb5eb..6ce377710 100644
--- a/crates/base_db/src/fixture.rs
+++ b/crates/base_db/src/fixture.rs
@@ -9,8 +9,8 @@ use test_utils::{
9use vfs::{file_set::FileSet, VfsPath}; 9use vfs::{file_set::FileSet, VfsPath};
10 10
11use crate::{ 11use crate::{
12 input::CrateName, Change, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, FileRange, 12 input::CrateName, Change, CrateDisplayName, CrateGraph, CrateId, Edition, Env, FileId,
13 SourceDatabaseExt, SourceRoot, SourceRootId, 13 FilePosition, FileRange, SourceDatabaseExt, SourceRoot, SourceRootId,
14}; 14};
15 15
16pub const WORKSPACE: SourceRootId = SourceRootId(0); 16pub const WORKSPACE: SourceRootId = SourceRootId(0);
@@ -24,6 +24,14 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
24 (db, fixture.files[0]) 24 (db, fixture.files[0])
25 } 25 }
26 26
27 fn with_many_files(ra_fixture: &str) -> (Self, Vec<FileId>) {
28 let fixture = ChangeFixture::parse(ra_fixture);
29 let mut db = Self::default();
30 fixture.change.apply(&mut db);
31 assert!(fixture.file_position.is_none());
32 (db, fixture.files)
33 }
34
27 fn with_files(ra_fixture: &str) -> Self { 35 fn with_files(ra_fixture: &str) -> Self {
28 let fixture = ChangeFixture::parse(ra_fixture); 36 let fixture = ChangeFixture::parse(ra_fixture);
29 let mut db = Self::default(); 37 let mut db = Self::default();
@@ -73,7 +81,7 @@ pub struct ChangeFixture {
73 81
74impl ChangeFixture { 82impl ChangeFixture {
75 pub fn parse(ra_fixture: &str) -> ChangeFixture { 83 pub fn parse(ra_fixture: &str) -> ChangeFixture {
76 let fixture = Fixture::parse(ra_fixture); 84 let (mini_core, fixture) = Fixture::parse(ra_fixture);
77 let mut change = Change::new(); 85 let mut change = Change::new();
78 86
79 let mut files = Vec::new(); 87 let mut files = Vec::new();
@@ -98,7 +106,7 @@ impl ChangeFixture {
98 let (range_or_offset, text) = extract_range_or_offset(&entry.text); 106 let (range_or_offset, text) = extract_range_or_offset(&entry.text);
99 assert!(file_position.is_none()); 107 assert!(file_position.is_none());
100 file_position = Some((file_id, range_or_offset)); 108 file_position = Some((file_id, range_or_offset));
101 text.to_string() 109 text
102 } 110 }
103 } else { 111 } else {
104 entry.text.clone() 112 entry.text.clone()
@@ -106,6 +114,9 @@ impl ChangeFixture {
106 114
107 let meta = FileMeta::from(entry); 115 let meta = FileMeta::from(entry);
108 assert!(meta.path.starts_with(&source_root_prefix)); 116 assert!(meta.path.starts_with(&source_root_prefix));
117 if !meta.deps.is_empty() {
118 assert!(meta.krate.is_some(), "can't specify deps without naming the crate")
119 }
109 120
110 if meta.introduce_new_source_root { 121 if meta.introduce_new_source_root {
111 roots.push(SourceRoot::new_local(mem::take(&mut file_set))); 122 roots.push(SourceRoot::new_local(mem::take(&mut file_set)));
@@ -158,6 +169,31 @@ impl ChangeFixture {
158 } 169 }
159 } 170 }
160 171
172 if let Some(mini_core) = mini_core {
173 let core_file = file_id;
174 file_id.0 += 1;
175
176 let mut fs = FileSet::default();
177 fs.insert(core_file, VfsPath::new_virtual_path("/sysroot/core/lib.rs".to_string()));
178 roots.push(SourceRoot::new_library(fs));
179
180 change.change_file(core_file, Some(Arc::new(mini_core.source_code())));
181
182 let all_crates = crate_graph.crates_in_topological_order();
183
184 let core_crate = crate_graph.add_crate_root(
185 core_file,
186 Edition::Edition2021,
187 Some(CrateDisplayName::from_canonical_name("core".to_string())),
188 CfgOptions::default(),
189 Env::default(),
190 Vec::new(),
191 );
192
193 for krate in all_crates {
194 crate_graph.add_dep(krate, CrateName::new("core").unwrap(), core_crate).unwrap();
195 }
196 }
161 roots.push(SourceRoot::new_local(mem::take(&mut file_set))); 197 roots.push(SourceRoot::new_local(mem::take(&mut file_set)));
162 change.set_roots(roots); 198 change.set_roots(roots);
163 change.set_crate_graph(crate_graph); 199 change.set_crate_graph(crate_graph);
@@ -166,6 +202,7 @@ impl ChangeFixture {
166 } 202 }
167} 203}
168 204
205#[derive(Debug)]
169struct FileMeta { 206struct FileMeta {
170 path: String, 207 path: String,
171 krate: Option<String>, 208 krate: Option<String>,
diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs
index 03b8dd767..916d39a0b 100644
--- a/crates/cfg/src/lib.rs
+++ b/crates/cfg/src/lib.rs
@@ -1,4 +1,4 @@
1//! cfg defines conditional compiling options, `cfg` attibute parser and evaluator 1//! cfg defines conditional compiling options, `cfg` attribute parser and evaluator
2 2
3mod cfg_expr; 3mod cfg_expr;
4mod dnf; 4mod dnf;
@@ -52,6 +52,7 @@ impl CfgOptions {
52 } 52 }
53} 53}
54 54
55#[derive(Clone, Debug, PartialEq, Eq)]
55pub struct CfgDiff { 56pub struct CfgDiff {
56 // Invariants: No duplicates, no atom that's both in `enable` and `disable`. 57 // Invariants: No duplicates, no atom that's both in `enable` and `disable`.
57 enable: Vec<CfgAtom>, 58 enable: Vec<CfgAtom>,
@@ -59,6 +60,20 @@ pub struct CfgDiff {
59} 60}
60 61
61impl CfgDiff { 62impl CfgDiff {
63 /// Create a new CfgDiff. Will return None if the same item appears more than once in the set
64 /// of both.
65 pub fn new(enable: Vec<CfgAtom>, disable: Vec<CfgAtom>) -> Option<CfgDiff> {
66 let mut occupied = FxHashSet::default();
67 for item in enable.iter().chain(disable.iter()) {
68 if !occupied.insert(item) {
69 // was present
70 return None;
71 }
72 }
73
74 Some(CfgDiff { enable, disable })
75 }
76
62 /// Returns the total number of atoms changed by this diff. 77 /// Returns the total number of atoms changed by this diff.
63 pub fn len(&self) -> usize { 78 pub fn len(&self) -> usize {
64 self.enable.len() + self.disable.len() 79 self.enable.len() + self.disable.len()
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index dc10a4d0f..197149c5e 100644
--- a/crates/hir/src/has_source.rs
+++ b/crates/hir/src/has_source.rs
@@ -127,7 +127,7 @@ impl HasSource for Impl {
127} 127}
128 128
129impl HasSource for TypeParam { 129impl HasSource for TypeParam {
130 type Ast = Either<ast::Trait, ast::TypeParam>; 130 type Ast = Either<ast::TypeParam, ast::Trait>;
131 fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { 131 fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
132 let child_source = self.id.parent.child_source(db.upcast()); 132 let child_source = self.id.parent.child_source(db.upcast());
133 Some(child_source.map(|it| it[self.id.local_id].clone())) 133 Some(child_source.map(|it| it[self.id.local_id].clone()))
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 5bc0b2338..b7eabaabb 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -2688,18 +2688,6 @@ impl ScopeDef {
2688 2688
2689 items 2689 items
2690 } 2690 }
2691
2692 pub fn is_value_def(&self) -> bool {
2693 matches!(
2694 self,
2695 ScopeDef::ModuleDef(ModuleDef::Function(_))
2696 | ScopeDef::ModuleDef(ModuleDef::Variant(_))
2697 | ScopeDef::ModuleDef(ModuleDef::Const(_))
2698 | ScopeDef::ModuleDef(ModuleDef::Static(_))
2699 | ScopeDef::GenericParam(GenericParam::ConstParam(_))
2700 | ScopeDef::Local(_)
2701 )
2702 }
2703} 2691}
2704 2692
2705impl From<ItemInNs> for ScopeDef { 2693impl From<ItemInNs> for ScopeDef {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 613266e07..43162797e 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -51,12 +51,14 @@ impl PathResolution {
51 PathResolution::Def(ModuleDef::BuiltinType(builtin)) => { 51 PathResolution::Def(ModuleDef::BuiltinType(builtin)) => {
52 Some(TypeNs::BuiltinType((*builtin).into())) 52 Some(TypeNs::BuiltinType((*builtin).into()))
53 } 53 }
54 PathResolution::Def(ModuleDef::Const(_)) 54 PathResolution::Def(
55 | PathResolution::Def(ModuleDef::Variant(_)) 55 ModuleDef::Const(_)
56 | PathResolution::Def(ModuleDef::Function(_)) 56 | ModuleDef::Variant(_)
57 | PathResolution::Def(ModuleDef::Module(_)) 57 | ModuleDef::Function(_)
58 | PathResolution::Def(ModuleDef::Static(_)) 58 | ModuleDef::Module(_)
59 | PathResolution::Def(ModuleDef::Trait(_)) => None, 59 | ModuleDef::Static(_)
60 | ModuleDef::Trait(_),
61 ) => None,
60 PathResolution::Def(ModuleDef::TypeAlias(alias)) => { 62 PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
61 Some(TypeNs::TypeAliasId((*alias).into())) 63 Some(TypeNs::TypeAliasId((*alias).into()))
62 } 64 }
@@ -65,8 +67,7 @@ impl PathResolution {
65 } 67 }
66 PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())), 68 PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
67 PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())), 69 PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
68 PathResolution::AssocItem(AssocItem::Const(_)) 70 PathResolution::AssocItem(AssocItem::Const(_) | AssocItem::Function(_)) => None,
69 | PathResolution::AssocItem(AssocItem::Function(_)) => None,
70 PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => { 71 PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {
71 Some(TypeNs::TypeAliasId((*alias).into())) 72 Some(TypeNs::TypeAliasId((*alias).into()))
72 } 73 }
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index 6933f6e3c..0f04b2bae 100644
--- a/crates/hir_def/src/generics.rs
+++ b/crates/hir_def/src/generics.rs
@@ -92,7 +92,7 @@ pub enum WherePredicateTypeTarget {
92 92
93#[derive(Default)] 93#[derive(Default)]
94pub(crate) struct SourceMap { 94pub(crate) struct SourceMap {
95 pub(crate) type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>, 95 pub(crate) type_params: ArenaMap<LocalTypeParamId, Either<ast::TypeParam, ast::Trait>>,
96 lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>, 96 lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>,
97 const_params: ArenaMap<LocalConstParamId, ast::ConstParam>, 97 const_params: ArenaMap<LocalConstParamId, ast::ConstParam>,
98} 98}
@@ -199,7 +199,7 @@ impl GenericParams {
199 default: None, 199 default: None,
200 provenance: TypeParamProvenance::TraitSelf, 200 provenance: TypeParamProvenance::TraitSelf,
201 }); 201 });
202 sm.type_params.insert(self_param_id, Either::Left(src.value.clone())); 202 sm.type_params.insert(self_param_id, Either::Right(src.value.clone()));
203 // add super traits as bounds on Self 203 // add super traits as bounds on Self
204 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 204 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
205 let self_param = TypeRef::Path(name![Self].into()); 205 let self_param = TypeRef::Path(name![Self].into());
@@ -277,7 +277,7 @@ impl GenericParams {
277 provenance: TypeParamProvenance::TypeParamList, 277 provenance: TypeParamProvenance::TypeParamList,
278 }; 278 };
279 let param_id = self.types.alloc(param); 279 let param_id = self.types.alloc(param);
280 sm.type_params.insert(param_id, Either::Right(type_param.clone())); 280 sm.type_params.insert(param_id, Either::Left(type_param.clone()));
281 281
282 let type_ref = TypeRef::Path(name.into()); 282 let type_ref = TypeRef::Path(name.into());
283 self.fill_bounds(lower_ctx, &type_param, Either::Left(type_ref)); 283 self.fill_bounds(lower_ctx, &type_param, Either::Left(type_ref));
@@ -413,7 +413,7 @@ impl GenericParams {
413} 413}
414 414
415impl HasChildSource<LocalTypeParamId> for GenericDefId { 415impl HasChildSource<LocalTypeParamId> for GenericDefId {
416 type Value = Either<ast::Trait, ast::TypeParam>; 416 type Value = Either<ast::TypeParam, ast::Trait>;
417 fn child_source( 417 fn child_source(
418 &self, 418 &self,
419 db: &dyn DefDatabase, 419 db: &dyn DefDatabase,
@@ -449,7 +449,7 @@ impl ChildBySource for GenericDefId {
449 let sm = sm.as_ref(); 449 let sm = sm.as_ref();
450 for (local_id, src) in sm.value.type_params.iter() { 450 for (local_id, src) in sm.value.type_params.iter() {
451 let id = TypeParamId { parent: *self, local_id }; 451 let id = TypeParamId { parent: *self, local_id };
452 if let Either::Right(type_param) = src { 452 if let Either::Left(type_param) = src {
453 res[keys::TYPE_PARAM].insert(sm.with_value(type_param.clone()), id) 453 res[keys::TYPE_PARAM].insert(sm.with_value(type_param.clone()), id)
454 } 454 }
455 } 455 }
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 3f90bda74..5b1386406 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -674,7 +674,7 @@ impl<'a> Ctx<'a> {
674 default: None, 674 default: None,
675 provenance: TypeParamProvenance::TraitSelf, 675 provenance: TypeParamProvenance::TraitSelf,
676 }); 676 });
677 sm.type_params.insert(self_param_id, Either::Left(trait_def.clone())); 677 sm.type_params.insert(self_param_id, Either::Right(trait_def.clone()));
678 // add super traits as bounds on Self 678 // add super traits as bounds on Self
679 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 679 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
680 let self_param = TypeRef::Path(name![Self].into()); 680 let self_param = TypeRef::Path(name![Self].into());
diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs
index b1e1b70d0..e63bc8232 100644
--- a/crates/hir_def/src/item_tree/pretty.rs
+++ b/crates/hir_def/src/item_tree/pretty.rs
@@ -63,7 +63,7 @@ impl<'a> Printer<'a> {
63 fn blank(&mut self) { 63 fn blank(&mut self) {
64 let mut iter = self.buf.chars().rev().fuse(); 64 let mut iter = self.buf.chars().rev().fuse();
65 match (iter.next(), iter.next()) { 65 match (iter.next(), iter.next()) {
66 (Some('\n'), Some('\n')) | (Some('\n'), None) | (None, None) => {} 66 (Some('\n'), Some('\n') | None) | (None, None) => {}
67 (Some('\n'), Some(_)) => { 67 (Some('\n'), Some(_)) => {
68 self.buf.push('\n'); 68 self.buf.push('\n');
69 } 69 }
@@ -77,7 +77,7 @@ impl<'a> Printer<'a> {
77 77
78 fn whitespace(&mut self) { 78 fn whitespace(&mut self) {
79 match self.buf.chars().next_back() { 79 match self.buf.chars().next_back() {
80 None | Some('\n') | Some(' ') => {} 80 None | Some('\n' | ' ') => {}
81 _ => self.buf.push(' '), 81 _ => self.buf.push(' '),
82 } 82 }
83 } 83 }
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 6fab58f15..927a7b6e8 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -1260,7 +1260,7 @@ impl DefCollector<'_> {
1260 for directive in &self.unresolved_imports { 1260 for directive in &self.unresolved_imports {
1261 if let ImportSource::Import { id: import, use_tree } = &directive.import.source { 1261 if let ImportSource::Import { id: import, use_tree } = &directive.import.source {
1262 match (directive.import.path.segments().first(), &directive.import.path.kind) { 1262 match (directive.import.path.segments().first(), &directive.import.path.kind) {
1263 (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => { 1263 (Some(krate), PathKind::Plain | PathKind::Abs) => {
1264 if diagnosed_extern_crates.contains(krate) { 1264 if diagnosed_extern_crates.contains(krate) {
1265 continue; 1265 continue;
1266 } 1266 }
@@ -1992,8 +1992,8 @@ mod tests {
1992 collector.def_map 1992 collector.def_map
1993 } 1993 }
1994 1994
1995 fn do_resolve(code: &str) -> DefMap { 1995 fn do_resolve(not_ra_fixture: &str) -> DefMap {
1996 let (db, _file_id) = TestDB::with_single_file(code); 1996 let (db, _file_id) = TestDB::with_single_file(not_ra_fixture);
1997 let krate = db.test_crate(); 1997 let krate = db.test_crate();
1998 1998
1999 let edition = db.crate_graph()[krate].edition; 1999 let edition = db.crate_graph()[krate].edition;
@@ -2005,24 +2005,37 @@ mod tests {
2005 fn test_macro_expand_will_stop_1() { 2005 fn test_macro_expand_will_stop_1() {
2006 do_resolve( 2006 do_resolve(
2007 r#" 2007 r#"
2008 macro_rules! foo { 2008macro_rules! foo {
2009 ($($ty:ty)*) => { foo!($($ty)*); } 2009 ($($ty:ty)*) => { foo!($($ty)*); }
2010 } 2010}
2011 foo!(KABOOM); 2011foo!(KABOOM);
2012 "#, 2012"#,
2013 );
2014 do_resolve(
2015 r#"
2016macro_rules! foo {
2017 ($($ty:ty)*) => { foo!(() $($ty)*); }
2018}
2019foo!(KABOOM);
2020"#,
2013 ); 2021 );
2014 } 2022 }
2015 2023
2016 #[ignore] // this test does succeed, but takes quite a while :/ 2024 #[ignore]
2017 #[test] 2025 #[test]
2018 fn test_macro_expand_will_stop_2() { 2026 fn test_macro_expand_will_stop_2() {
2027 // FIXME: this test does succeed, but takes quite a while: 90 seconds in
2028 // the release mode. That's why the argument is not an ra_fixture --
2029 // otherwise injection highlighting gets stuck.
2030 //
2031 // We need to find a way to fail this faster.
2019 do_resolve( 2032 do_resolve(
2020 r#" 2033 r#"
2021 macro_rules! foo { 2034macro_rules! foo {
2022 ($($ty:ty)*) => { foo!($($ty)* $($ty)*); } 2035 ($($ty:ty)*) => { foo!($($ty)* $($ty)*); }
2023 } 2036}
2024 foo!(KABOOM); 2037foo!(KABOOM);
2025 "#, 2038"#,
2026 ); 2039 );
2027 } 2040 }
2028} 2041}
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index d4681fa3e..49c573087 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -605,8 +605,7 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
605 ModuleDefId::ConstId(it) => ValueNs::ConstId(it), 605 ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
606 ModuleDefId::StaticId(it) => ValueNs::StaticId(it), 606 ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
607 607
608 ModuleDefId::AdtId(AdtId::EnumId(_)) 608 ModuleDefId::AdtId(AdtId::EnumId(_) | AdtId::UnionId(_))
609 | ModuleDefId::AdtId(AdtId::UnionId(_))
610 | ModuleDefId::TraitId(_) 609 | ModuleDefId::TraitId(_)
611 | ModuleDefId::TypeAliasId(_) 610 | ModuleDefId::TypeAliasId(_)
612 | ModuleDefId::BuiltinType(_) 611 | ModuleDefId::BuiltinType(_)
@@ -641,8 +640,7 @@ pub trait HasResolver: Copy {
641impl HasResolver for ModuleId { 640impl HasResolver for ModuleId {
642 fn resolver(self, db: &dyn DefDatabase) -> Resolver { 641 fn resolver(self, db: &dyn DefDatabase) -> Resolver {
643 let mut def_map = self.def_map(db); 642 let mut def_map = self.def_map(db);
644 let mut modules = Vec::new(); 643 let mut modules = vec![(def_map.clone(), self.local_id)];
645 modules.push((def_map.clone(), self.local_id));
646 while let Some(parent) = def_map.parent() { 644 while let Some(parent) = def_map.parent() {
647 def_map = parent.def_map(db); 645 def_map = parent.def_map(db);
648 modules.push((def_map.clone(), parent.local_id)); 646 modules.push((def_map.clone(), parent.local_id));
diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs
index 83500f54e..aeb1e7726 100644
--- a/crates/hir_def/src/visibility.rs
+++ b/crates/hir_def/src/visibility.rs
@@ -172,9 +172,8 @@ impl Visibility {
172 /// visible in unrelated modules). 172 /// visible in unrelated modules).
173 pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option<Visibility> { 173 pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option<Visibility> {
174 match (self, other) { 174 match (self, other) {
175 (Visibility::Module(_), Visibility::Public) 175 (Visibility::Module(_) | Visibility::Public, Visibility::Public)
176 | (Visibility::Public, Visibility::Module(_)) 176 | (Visibility::Public, Visibility::Module(_)) => Some(Visibility::Public),
177 | (Visibility::Public, Visibility::Public) => Some(Visibility::Public),
178 (Visibility::Module(mod_a), Visibility::Module(mod_b)) => { 177 (Visibility::Module(mod_a), Visibility::Module(mod_b)) => {
179 if mod_a.krate != mod_b.krate { 178 if mod_a.krate != mod_b.krate {
180 return None; 179 return None;
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index f24d1d919..4c83a2efe 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -202,7 +202,7 @@ fn assert_expand(
202 202
203 let arg_tts = args.into_iter().flat_map(|arg| { 203 let arg_tts = args.into_iter().flat_map(|arg| {
204 quote! { &(#arg), } 204 quote! { &(#arg), }
205 }.token_trees).collect::<Vec<_>>(); 205 }.token_trees);
206 206
207 let expanded = quote! { 207 let expanded = quote! {
208 { { (##arg_tts); } } 208 { { (##arg_tts); } }
@@ -254,7 +254,7 @@ fn format_args_expand(
254 let _format_string = args.remove(0); 254 let _format_string = args.remove(0);
255 let arg_tts = args.into_iter().flat_map(|arg| { 255 let arg_tts = args.into_iter().flat_map(|arg| {
256 quote! { std::fmt::ArgumentV1::new(&(#arg), std::fmt::Display::fmt), } 256 quote! { std::fmt::ArgumentV1::new(&(#arg), std::fmt::Display::fmt), }
257 }.token_trees).collect::<Vec<_>>(); 257 }.token_trees);
258 let expanded = quote! { 258 let expanded = quote! {
259 std::fmt::Arguments::new_v1(&[], &[##arg_tts]) 259 std::fmt::Arguments::new_v1(&[], &[##arg_tts])
260 }; 260 };
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs
index 05c6c3fb1..848522411 100644
--- a/crates/hir_expand/src/hygiene.rs
+++ b/crates/hir_expand/src/hygiene.rs
@@ -146,10 +146,11 @@ impl HygieneInfo {
146 (&self.macro_arg.1, InFile::new(loc.kind.file_id(), arg_start)) 146 (&self.macro_arg.1, InFile::new(loc.kind.file_id(), arg_start))
147 } 147 }
148 mbe::Origin::Def => match (&*self.macro_def, self.def_start) { 148 mbe::Origin::Def => match (&*self.macro_def, self.def_start) {
149 (TokenExpander::MacroDef { def_site_token_map, .. }, Some(tt)) 149 (
150 | (TokenExpander::MacroRules { def_site_token_map, .. }, Some(tt)) => { 150 TokenExpander::MacroDef { def_site_token_map, .. }
151 (def_site_token_map, tt) 151 | TokenExpander::MacroRules { def_site_token_map, .. },
152 } 152 Some(tt),
153 ) => (def_site_token_map, tt),
153 _ => panic!("`Origin::Def` used with non-`macro_rules!` macro"), 154 _ => panic!("`Origin::Def` used with non-`macro_rules!` macro"),
154 }, 155 },
155 }; 156 };
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index 33107aa24..c31426d7c 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -368,10 +368,11 @@ impl ExpansionInfo {
368 let (token_map, tt) = match origin { 368 let (token_map, tt) = match origin {
369 mbe::Origin::Call => (&self.macro_arg.1, self.arg.clone()), 369 mbe::Origin::Call => (&self.macro_arg.1, self.arg.clone()),
370 mbe::Origin::Def => match (&*self.macro_def, self.def.as_ref()) { 370 mbe::Origin::Def => match (&*self.macro_def, self.def.as_ref()) {
371 (db::TokenExpander::MacroRules { def_site_token_map, .. }, Some(tt)) 371 (
372 | (db::TokenExpander::MacroDef { def_site_token_map, .. }, Some(tt)) => { 372 db::TokenExpander::MacroRules { def_site_token_map, .. }
373 (def_site_token_map, tt.as_ref().map(|tt| tt.syntax().clone())) 373 | db::TokenExpander::MacroDef { def_site_token_map, .. },
374 } 374 Some(tt),
375 ) => (def_site_token_map, tt.as_ref().map(|tt| tt.syntax().clone())),
375 _ => panic!("`Origin::Def` used with non-`macro_rules!` macro"), 376 _ => panic!("`Origin::Def` used with non-`macro_rules!` macro"),
376 }, 377 },
377 }; 378 };
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index a1894e8d8..74129eb21 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -20,7 +20,7 @@ rustc-hash = "1.1.0"
20scoped-tls = "1" 20scoped-tls = "1"
21chalk-solve = { version = "0.68", default-features = false } 21chalk-solve = { version = "0.68", default-features = false }
22chalk-ir = "0.68" 22chalk-ir = "0.68"
23chalk-recursive = "0.68" 23chalk-recursive = { version = "0.68", default-features = false }
24la-arena = { version = "0.2.0", path = "../../lib/arena" } 24la-arena = { version = "0.2.0", path = "../../lib/arena" }
25once_cell = { version = "1.5.0" } 25once_cell = { version = "1.5.0" }
26 26
diff --git a/crates/hir_ty/src/chalk_db.rs b/crates/hir_ty/src/chalk_db.rs
index a4c09c742..a55b99de0 100644
--- a/crates/hir_ty/src/chalk_db.rs
+++ b/crates/hir_ty/src/chalk_db.rs
@@ -2,6 +2,7 @@
2//! about the code that Chalk needs. 2//! about the code that Chalk needs.
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use cov_mark::hit;
5use log::debug; 6use log::debug;
6 7
7use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds}; 8use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds};
@@ -106,7 +107,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
106 }; 107 };
107 108
108 fn local_impls(db: &dyn HirDatabase, module: ModuleId) -> Option<Arc<TraitImpls>> { 109 fn local_impls(db: &dyn HirDatabase, module: ModuleId) -> Option<Arc<TraitImpls>> {
109 db.trait_impls_in_block(module.containing_block()?) 110 let block = module.containing_block()?;
111 hit!(block_local_impls);
112 db.trait_impls_in_block(block)
110 } 113 }
111 114
112 // Note: Since we're using impls_for_trait, only impls where the trait 115 // Note: Since we're using impls_for_trait, only impls where the trait
diff --git a/crates/hir_ty/src/consteval.rs b/crates/hir_ty/src/consteval.rs
index 6f0bf8f8c..ab1afce08 100644
--- a/crates/hir_ty/src/consteval.rs
+++ b/crates/hir_ty/src/consteval.rs
@@ -38,8 +38,7 @@ impl ConstExt for Const {
38// FIXME: support more than just evaluating literals 38// FIXME: support more than just evaluating literals
39pub fn eval_usize(expr: &Expr) -> Option<u64> { 39pub fn eval_usize(expr: &Expr) -> Option<u64> {
40 match expr { 40 match expr {
41 Expr::Literal(Literal::Uint(v, None)) 41 Expr::Literal(Literal::Uint(v, None | Some(BuiltinUint::Usize))) => (*v).try_into().ok(),
42 | Expr::Literal(Literal::Uint(v, Some(BuiltinUint::Usize))) => (*v).try_into().ok(),
43 _ => None, 42 _ => None,
44 } 43 }
45} 44}
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index b809b96a0..dc8f20138 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -56,7 +56,7 @@ impl BodyValidationDiagnostic {
56 pub fn collect(db: &dyn HirDatabase, owner: DefWithBodyId) -> Vec<BodyValidationDiagnostic> { 56 pub fn collect(db: &dyn HirDatabase, owner: DefWithBodyId) -> Vec<BodyValidationDiagnostic> {
57 let _p = profile::span("BodyValidationDiagnostic::collect"); 57 let _p = profile::span("BodyValidationDiagnostic::collect");
58 let infer = db.infer(owner); 58 let infer = db.infer(owner);
59 let mut validator = ExprValidator::new(owner, infer.clone()); 59 let mut validator = ExprValidator::new(owner, infer);
60 validator.validate_body(db); 60 validator.validate_body(db);
61 validator.diagnostics 61 validator.diagnostics
62 } 62 }
diff --git a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
index 471cd4921..e3d640a79 100644
--- a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
+++ b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
@@ -84,10 +84,7 @@ impl IntRange {
84 #[inline] 84 #[inline]
85 fn is_integral(ty: &Ty) -> bool { 85 fn is_integral(ty: &Ty) -> bool {
86 match ty.kind(&Interner) { 86 match ty.kind(&Interner) {
87 TyKind::Scalar(Scalar::Char) 87 TyKind::Scalar(Scalar::Char | Scalar::Int(_) | Scalar::Uint(_) | Scalar::Bool) => true,
88 | TyKind::Scalar(Scalar::Int(_))
89 | TyKind::Scalar(Scalar::Uint(_))
90 | TyKind::Scalar(Scalar::Bool) => true,
91 _ => false, 88 _ => false,
92 } 89 }
93 } 90 }
@@ -381,7 +378,7 @@ impl Constructor {
381 // Wildcards cover anything 378 // Wildcards cover anything
382 (_, Wildcard) => true, 379 (_, Wildcard) => true,
383 // The missing ctors are not covered by anything in the matrix except wildcards. 380 // The missing ctors are not covered by anything in the matrix except wildcards.
384 (Missing, _) | (Wildcard, _) => false, 381 (Missing | Wildcard, _) => false,
385 382
386 (Single, Single) => true, 383 (Single, Single) => true,
387 (Variant(self_id), Variant(other_id)) => self_id == other_id, 384 (Variant(self_id), Variant(other_id)) => self_id == other_id,
@@ -523,7 +520,7 @@ impl SplitWildcard {
523 } 520 }
524 } 521 }
525 TyKind::Scalar(Scalar::Char) => unhandled(), 522 TyKind::Scalar(Scalar::Char) => unhandled(),
526 TyKind::Scalar(Scalar::Int(..)) | TyKind::Scalar(Scalar::Uint(..)) => unhandled(), 523 TyKind::Scalar(Scalar::Int(..) | Scalar::Uint(..)) => unhandled(),
527 TyKind::Never if !cx.feature_exhaustive_patterns() && !pcx.is_top_level => { 524 TyKind::Never if !cx.feature_exhaustive_patterns() && !pcx.is_top_level => {
528 smallvec![NonExhaustive] 525 smallvec![NonExhaustive]
529 } 526 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 4b7f31521..7be914451 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -47,10 +47,7 @@ impl<'a> InferenceContext<'a> {
47 // pointers to have a chance at getting a match. See 47 // pointers to have a chance at getting a match. See
48 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 48 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
49 let sig = match (ty1.kind(&Interner), ty2.kind(&Interner)) { 49 let sig = match (ty1.kind(&Interner), ty2.kind(&Interner)) {
50 (TyKind::FnDef(..), TyKind::FnDef(..)) 50 (TyKind::FnDef(..) | TyKind::Closure(..), TyKind::FnDef(..) | TyKind::Closure(..)) => {
51 | (TyKind::Closure(..), TyKind::FnDef(..))
52 | (TyKind::FnDef(..), TyKind::Closure(..))
53 | (TyKind::Closure(..), TyKind::Closure(..)) => {
54 // FIXME: we're ignoring safety here. To be more correct, if we have one FnDef and one Closure, 51 // FIXME: we're ignoring safety here. To be more correct, if we have one FnDef and one Closure,
55 // we should be coercing the closure to a fn pointer of the safety of the FnDef 52 // we should be coercing the closure to a fn pointer of the safety of the FnDef
56 cov_mark::hit!(coerce_fn_reification); 53 cov_mark::hit!(coerce_fn_reification);
@@ -448,8 +445,7 @@ fn safe_to_unsafe_fn_ty(fn_ty: FnPointer) -> FnPointer {
448 445
449fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError> { 446fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError> {
450 match (from, to) { 447 match (from, to) {
451 (Mutability::Mut, Mutability::Mut) 448 (Mutability::Mut, Mutability::Mut | Mutability::Not)
452 | (Mutability::Mut, Mutability::Not)
453 | (Mutability::Not, Mutability::Not) => Ok(()), 449 | (Mutability::Not, Mutability::Not) => Ok(()),
454 (Mutability::Not, Mutability::Mut) => Err(TypeError), 450 (Mutability::Not, Mutability::Mut) => Err(TypeError),
455 } 451 }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 5ea2e5934..c3a5b979f 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -367,7 +367,7 @@ impl<'a> InferenceContext<'a> {
367 Expr::Path(p) => { 367 Expr::Path(p) => {
368 // FIXME this could be more efficient... 368 // FIXME this could be more efficient...
369 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 369 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
370 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty()) 370 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or_else(|| self.err_ty())
371 } 371 }
372 Expr::Continue { .. } => TyKind::Never.intern(&Interner), 372 Expr::Continue { .. } => TyKind::Never.intern(&Interner),
373 Expr::Break { expr, label } => { 373 Expr::Break { expr, label } => {
@@ -511,7 +511,7 @@ impl<'a> InferenceContext<'a> {
511 _ => None, 511 _ => None,
512 } 512 }
513 }) 513 })
514 .unwrap_or(self.err_ty()); 514 .unwrap_or_else(|| self.err_ty());
515 let ty = self.insert_type_vars(ty); 515 let ty = self.insert_type_vars(ty);
516 self.normalize_associated_types_in(ty) 516 self.normalize_associated_types_in(ty)
517 } 517 }
@@ -593,11 +593,11 @@ impl<'a> InferenceContext<'a> {
593 UnaryOp::Neg => { 593 UnaryOp::Neg => {
594 match inner_ty.kind(&Interner) { 594 match inner_ty.kind(&Interner) {
595 // Fast path for builtins 595 // Fast path for builtins
596 TyKind::Scalar(Scalar::Int(_)) 596 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_))
597 | TyKind::Scalar(Scalar::Uint(_)) 597 | TyKind::InferenceVar(
598 | TyKind::Scalar(Scalar::Float(_)) 598 _,
599 | TyKind::InferenceVar(_, TyVariableKind::Integer) 599 TyVariableKind::Integer | TyVariableKind::Float,
600 | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty, 600 ) => inner_ty,
601 // Otherwise we resolve via the std::ops::Neg trait 601 // Otherwise we resolve via the std::ops::Neg trait
602 _ => self 602 _ => self
603 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 603 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
@@ -606,9 +606,7 @@ impl<'a> InferenceContext<'a> {
606 UnaryOp::Not => { 606 UnaryOp::Not => {
607 match inner_ty.kind(&Interner) { 607 match inner_ty.kind(&Interner) {
608 // Fast path for builtins 608 // Fast path for builtins
609 TyKind::Scalar(Scalar::Bool) 609 TyKind::Scalar(Scalar::Bool | Scalar::Int(_) | Scalar::Uint(_))
610 | TyKind::Scalar(Scalar::Int(_))
611 | TyKind::Scalar(Scalar::Uint(_))
612 | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty, 610 | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
613 // Otherwise we resolve via the std::ops::Not trait 611 // Otherwise we resolve via the std::ops::Not trait
614 _ => self 612 _ => self
@@ -735,7 +733,7 @@ impl<'a> InferenceContext<'a> {
735 Expr::Array(array) => { 733 Expr::Array(array) => {
736 let elem_ty = 734 let elem_ty =
737 match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(&Interner)) { 735 match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(&Interner)) {
738 Some(TyKind::Array(st, _)) | Some(TyKind::Slice(st)) => st.clone(), 736 Some(TyKind::Array(st, _) | TyKind::Slice(st)) => st.clone(),
739 _ => self.table.new_type_var(), 737 _ => self.table.new_type_var(),
740 }; 738 };
741 739
@@ -820,8 +818,10 @@ impl<'a> InferenceContext<'a> {
820 for stmt in statements { 818 for stmt in statements {
821 match stmt { 819 match stmt {
822 Statement::Let { pat, type_ref, initializer } => { 820 Statement::Let { pat, type_ref, initializer } => {
823 let decl_ty = 821 let decl_ty = type_ref
824 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty()); 822 .as_ref()
823 .map(|tr| self.make_ty(tr))
824 .unwrap_or_else(|| self.err_ty());
825 825
826 // Always use the declared type when specified 826 // Always use the declared type when specified
827 let mut ty = decl_ty.clone(); 827 let mut ty = decl_ty.clone();
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 035f4ded6..c79ed91ea 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -192,7 +192,7 @@ impl<'a> InferenceContext<'a> {
192 Pat::Path(path) => { 192 Pat::Path(path) => {
193 // FIXME use correct resolver for the surrounding expression 193 // FIXME use correct resolver for the surrounding expression
194 let resolver = self.resolver.clone(); 194 let resolver = self.resolver.clone();
195 self.infer_path(&resolver, path, pat.into()).unwrap_or(self.err_ty()) 195 self.infer_path(&resolver, path, pat.into()).unwrap_or_else(|| self.err_ty())
196 } 196 }
197 Pat::Bind { mode, name: _, subpat } => { 197 Pat::Bind { mode, name: _, subpat } => {
198 let mode = if mode == &BindingAnnotation::Unannotated { 198 let mode = if mode == &BindingAnnotation::Unannotated {
@@ -297,10 +297,11 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
297 Expr::Literal(Literal::String(..)) => false, 297 Expr::Literal(Literal::String(..)) => false,
298 _ => true, 298 _ => true,
299 }, 299 },
300 Pat::Bind { mode: BindingAnnotation::Mutable, subpat: Some(subpat), .. } 300 Pat::Bind {
301 | Pat::Bind { mode: BindingAnnotation::Unannotated, subpat: Some(subpat), .. } => { 301 mode: BindingAnnotation::Mutable | BindingAnnotation::Unannotated,
302 is_non_ref_pat(body, *subpat) 302 subpat: Some(subpat),
303 } 303 ..
304 } => is_non_ref_pat(body, *subpat),
304 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false, 305 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false,
305 } 306 }
306} 307}
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 817a65c20..ea03b6a6c 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -562,7 +562,7 @@ impl<'a> TyLoweringContext<'a> {
562 }, 562 },
563 ); 563 );
564 564
565 ty.unwrap_or(TyKind::Error.intern(&Interner)) 565 ty.unwrap_or_else(|| TyKind::Error.intern(&Interner))
566 } else { 566 } else {
567 TyKind::Error.intern(&Interner) 567 TyKind::Error.intern(&Interner)
568 } 568 }
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index 0222de2bc..5ef6342d5 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -8,17 +8,15 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
8 match op { 8 match op {
9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
10 BinaryOp::Assignment { .. } => TyBuilder::unit(), 10 BinaryOp::Assignment { .. } => TyBuilder::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { 11 BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr) => {
12 // all integer combinations are valid here 12 // all integer combinations are valid here
13 if matches!( 13 if matches!(
14 lhs_ty.kind(&Interner), 14 lhs_ty.kind(&Interner),
15 TyKind::Scalar(Scalar::Int(_)) 15 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))
16 | TyKind::Scalar(Scalar::Uint(_))
17 | TyKind::InferenceVar(_, TyVariableKind::Integer) 16 | TyKind::InferenceVar(_, TyVariableKind::Integer)
18 ) && matches!( 17 ) && matches!(
19 rhs_ty.kind(&Interner), 18 rhs_ty.kind(&Interner),
20 TyKind::Scalar(Scalar::Int(_)) 19 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))
21 | TyKind::Scalar(Scalar::Uint(_))
22 | TyKind::InferenceVar(_, TyVariableKind::Integer) 20 | TyKind::InferenceVar(_, TyVariableKind::Integer)
23 ) { 21 ) {
24 lhs_ty 22 lhs_ty
@@ -32,15 +30,15 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
32 | (TyKind::Scalar(Scalar::Uint(_)), TyKind::Scalar(Scalar::Uint(_))) 30 | (TyKind::Scalar(Scalar::Uint(_)), TyKind::Scalar(Scalar::Uint(_)))
33 | (TyKind::Scalar(Scalar::Float(_)), TyKind::Scalar(Scalar::Float(_))) => rhs_ty, 31 | (TyKind::Scalar(Scalar::Float(_)), TyKind::Scalar(Scalar::Float(_))) => rhs_ty,
34 // ({int}, int) | ({int}, uint) 32 // ({int}, int) | ({int}, uint)
35 (TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Int(_))) 33 (
36 | (TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Uint(_))) => { 34 TyKind::InferenceVar(_, TyVariableKind::Integer),
37 rhs_ty 35 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)),
38 } 36 ) => rhs_ty,
39 // (int, {int}) | (uint, {int}) 37 // (int, {int}) | (uint, {int})
40 (TyKind::Scalar(Scalar::Int(_)), TyKind::InferenceVar(_, TyVariableKind::Integer)) 38 (
41 | (TyKind::Scalar(Scalar::Uint(_)), TyKind::InferenceVar(_, TyVariableKind::Integer)) => { 39 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)),
42 lhs_ty 40 TyKind::InferenceVar(_, TyVariableKind::Integer),
43 } 41 ) => lhs_ty,
44 // ({float} | float) 42 // ({float} | float)
45 (TyKind::InferenceVar(_, TyVariableKind::Float), TyKind::Scalar(Scalar::Float(_))) => { 43 (TyKind::InferenceVar(_, TyVariableKind::Float), TyKind::Scalar(Scalar::Float(_))) => {
46 rhs_ty 44 rhs_ty
@@ -69,21 +67,15 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
69 BinaryOp::Assignment { op: None } => lhs_ty, 67 BinaryOp::Assignment { op: None } => lhs_ty,
70 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.kind(&Interner) { 68 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.kind(&Interner) {
71 TyKind::Scalar(_) | TyKind::Str => lhs_ty, 69 TyKind::Scalar(_) | TyKind::Str => lhs_ty,
72 TyKind::InferenceVar(_, TyVariableKind::Integer) 70 TyKind::InferenceVar(_, TyVariableKind::Integer | TyVariableKind::Float) => lhs_ty,
73 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
74 _ => TyKind::Error.intern(&Interner), 71 _ => TyKind::Error.intern(&Interner),
75 }, 72 },
76 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { 73 BinaryOp::ArithOp(ArithOp::Shl | ArithOp::Shr) => TyKind::Error.intern(&Interner),
77 TyKind::Error.intern(&Interner)
78 }
79 BinaryOp::CmpOp(CmpOp::Ord { .. }) 74 BinaryOp::CmpOp(CmpOp::Ord { .. })
80 | BinaryOp::Assignment { op: Some(_) } 75 | BinaryOp::Assignment { op: Some(_) }
81 | BinaryOp::ArithOp(_) => match lhs_ty.kind(&Interner) { 76 | BinaryOp::ArithOp(_) => match lhs_ty.kind(&Interner) {
82 TyKind::Scalar(Scalar::Int(_)) 77 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_)) => lhs_ty,
83 | TyKind::Scalar(Scalar::Uint(_)) 78 TyKind::InferenceVar(_, TyVariableKind::Integer | TyVariableKind::Float) => lhs_ty,
84 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
85 TyKind::InferenceVar(_, TyVariableKind::Integer)
86 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
87 _ => TyKind::Error.intern(&Interner), 79 _ => TyKind::Error.intern(&Interner),
88 }, 80 },
89 } 81 }
diff --git a/crates/hir_ty/src/test_db.rs b/crates/hir_ty/src/test_db.rs
index 4640ea821..b99a03492 100644
--- a/crates/hir_ty/src/test_db.rs
+++ b/crates/hir_ty/src/test_db.rs
@@ -86,16 +86,20 @@ impl FileLoader for TestDB {
86} 86}
87 87
88impl TestDB { 88impl TestDB {
89 pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { 89 pub(crate) fn module_for_file_opt(&self, file_id: FileId) -> Option<ModuleId> {
90 for &krate in self.relevant_crates(file_id).iter() { 90 for &krate in self.relevant_crates(file_id).iter() {
91 let crate_def_map = self.crate_def_map(krate); 91 let crate_def_map = self.crate_def_map(krate);
92 for (local_id, data) in crate_def_map.modules() { 92 for (local_id, data) in crate_def_map.modules() {
93 if data.origin.file_id() == Some(file_id) { 93 if data.origin.file_id() == Some(file_id) {
94 return crate_def_map.module_id(local_id); 94 return Some(crate_def_map.module_id(local_id));
95 } 95 }
96 } 96 }
97 } 97 }
98 panic!("Can't find module for file") 98 None
99 }
100
101 pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId {
102 self.module_for_file_opt(file_id).unwrap()
99 } 103 }
100 104
101 pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> { 105 pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index b873585c4..0651f34ae 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -11,23 +11,21 @@ mod incremental;
11 11
12use std::{collections::HashMap, env, sync::Arc}; 12use std::{collections::HashMap, env, sync::Arc};
13 13
14use base_db::{fixture::WithFixture, FileRange, SourceDatabase, SourceDatabaseExt}; 14use base_db::{fixture::WithFixture, FileRange, SourceDatabaseExt};
15use expect_test::Expect; 15use expect_test::Expect;
16use hir_def::{ 16use hir_def::{
17 body::{Body, BodySourceMap, SyntheticSyntax}, 17 body::{Body, BodySourceMap, SyntheticSyntax},
18 child_by_source::ChildBySource,
19 db::DefDatabase, 18 db::DefDatabase,
19 expr::{ExprId, PatId},
20 item_scope::ItemScope, 20 item_scope::ItemScope,
21 keys,
22 nameres::DefMap, 21 nameres::DefMap,
23 src::HasSource, 22 src::HasSource,
24 AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, 23 AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId,
25}; 24};
26use hir_expand::{db::AstDatabase, InFile}; 25use hir_expand::{db::AstDatabase, InFile};
27use once_cell::race::OnceBool; 26use once_cell::race::OnceBool;
28use stdx::format_to; 27use stdx::format_to;
29use syntax::{ 28use syntax::{
30 algo,
31 ast::{self, AstNode, NameOwner}, 29 ast::{self, AstNode, NameOwner},
32 SyntaxNode, 30 SyntaxNode,
33}; 31};
@@ -59,51 +57,55 @@ fn setup_tracing() -> Option<tracing::subscriber::DefaultGuard> {
59} 57}
60 58
61fn check_types(ra_fixture: &str) { 59fn check_types(ra_fixture: &str) {
62 check_types_impl(ra_fixture, false) 60 check_impl(ra_fixture, false, true, false)
63} 61}
64 62
65fn check_types_source_code(ra_fixture: &str) { 63fn check_types_source_code(ra_fixture: &str) {
66 check_types_impl(ra_fixture, true) 64 check_impl(ra_fixture, false, true, true)
67}
68
69fn check_types_impl(ra_fixture: &str, display_source: bool) {
70 let _tracing = setup_tracing();
71 let db = TestDB::with_files(ra_fixture);
72 let mut checked_one = false;
73 for (file_id, annotations) in db.extract_annotations() {
74 for (range, expected) in annotations {
75 let ty = type_at_range(&db, FileRange { file_id, range });
76 let actual = if display_source {
77 let module = db.module_for_file(file_id);
78 ty.display_source_code(&db, module).unwrap()
79 } else {
80 ty.display_test(&db).to_string()
81 };
82 assert_eq!(expected, actual);
83 checked_one = true;
84 }
85 }
86
87 assert!(checked_one, "no `//^` annotations found");
88} 65}
89 66
90fn check_no_mismatches(ra_fixture: &str) { 67fn check_no_mismatches(ra_fixture: &str) {
91 check_mismatches_impl(ra_fixture, true) 68 check_impl(ra_fixture, true, false, false)
92} 69}
93 70
94#[allow(unused)] 71fn check(ra_fixture: &str) {
95fn check_mismatches(ra_fixture: &str) { 72 check_impl(ra_fixture, false, false, false)
96 check_mismatches_impl(ra_fixture, false)
97} 73}
98 74
99fn check_mismatches_impl(ra_fixture: &str, allow_none: bool) { 75fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_source: bool) {
100 let _tracing = setup_tracing(); 76 let _tracing = setup_tracing();
101 let (db, file_id) = TestDB::with_single_file(ra_fixture); 77 let (db, files) = TestDB::with_many_files(ra_fixture);
102 let module = db.module_for_file(file_id); 78
103 let def_map = module.def_map(&db); 79 let mut had_annotations = false;
80 let mut mismatches = HashMap::new();
81 let mut types = HashMap::new();
82 for (file_id, annotations) in db.extract_annotations() {
83 for (range, expected) in annotations {
84 let file_range = FileRange { file_id, range };
85 if only_types {
86 types.insert(file_range, expected);
87 } else if expected.starts_with("type: ") {
88 types.insert(file_range, expected.trim_start_matches("type: ").to_string());
89 } else if expected.starts_with("expected") {
90 mismatches.insert(file_range, expected);
91 } else {
92 panic!("unexpected annotation: {}", expected);
93 }
94 had_annotations = true;
95 }
96 }
97 assert!(had_annotations || allow_none, "no `//^` annotations found");
104 98
105 let mut defs: Vec<DefWithBodyId> = Vec::new(); 99 let mut defs: Vec<DefWithBodyId> = Vec::new();
106 visit_module(&db, &def_map, module.local_id, &mut |it| defs.push(it)); 100 for file_id in files {
101 let module = db.module_for_file_opt(file_id);
102 let module = match module {
103 Some(m) => m,
104 None => continue,
105 };
106 let def_map = module.def_map(&db);
107 visit_module(&db, &def_map, module.local_id, &mut |it| defs.push(it));
108 }
107 defs.sort_by_key(|def| match def { 109 defs.sort_by_key(|def| match def {
108 DefWithBodyId::FunctionId(it) => { 110 DefWithBodyId::FunctionId(it) => {
109 let loc = it.lookup(&db); 111 let loc = it.lookup(&db);
@@ -118,37 +120,59 @@ fn check_mismatches_impl(ra_fixture: &str, allow_none: bool) {
118 loc.source(&db).value.syntax().text_range().start() 120 loc.source(&db).value.syntax().text_range().start()
119 } 121 }
120 }); 122 });
121 let mut mismatches = HashMap::new(); 123 let mut unexpected_type_mismatches = String::new();
122 let mut push_mismatch = |src_ptr: InFile<SyntaxNode>, mismatch: TypeMismatch| {
123 let range = src_ptr.value.text_range();
124 if src_ptr.file_id.call_node(&db).is_some() {
125 panic!("type mismatch in macro expansion");
126 }
127 let file_range = FileRange { file_id: src_ptr.file_id.original_file(&db), range };
128 let actual = format!(
129 "expected {}, got {}",
130 mismatch.expected.display_test(&db),
131 mismatch.actual.display_test(&db)
132 );
133 mismatches.insert(file_range, actual);
134 };
135 for def in defs { 124 for def in defs {
136 let (_body, body_source_map) = db.body_with_source_map(def); 125 let (_body, body_source_map) = db.body_with_source_map(def);
137 let inference_result = db.infer(def); 126 let inference_result = db.infer(def);
127
128 for (pat, ty) in inference_result.type_of_pat.iter() {
129 let node = match pat_node(&body_source_map, pat, &db) {
130 Some(value) => value,
131 None => continue,
132 };
133 let range = node.as_ref().original_file_range(&db);
134 if let Some(expected) = types.remove(&range) {
135 let actual = if display_source {
136 ty.display_source_code(&db, def.module(&db)).unwrap()
137 } else {
138 ty.display_test(&db).to_string()
139 };
140 assert_eq!(actual, expected);
141 }
142 }
143
144 for (expr, ty) in inference_result.type_of_expr.iter() {
145 let node = match expr_node(&body_source_map, expr, &db) {
146 Some(value) => value,
147 None => continue,
148 };
149 let range = node.as_ref().original_file_range(&db);
150 if let Some(expected) = types.remove(&range) {
151 let actual = if display_source {
152 ty.display_source_code(&db, def.module(&db)).unwrap()
153 } else {
154 ty.display_test(&db).to_string()
155 };
156 assert_eq!(actual, expected);
157 }
158 }
159
138 for (pat, mismatch) in inference_result.pat_type_mismatches() { 160 for (pat, mismatch) in inference_result.pat_type_mismatches() {
139 let syntax_ptr = match body_source_map.pat_syntax(pat) { 161 let node = match pat_node(&body_source_map, pat, &db) {
140 Ok(sp) => { 162 Some(value) => value,
141 let root = db.parse_or_expand(sp.file_id).unwrap(); 163 None => continue,
142 sp.map(|ptr| {
143 ptr.either(
144 |it| it.to_node(&root).syntax().clone(),
145 |it| it.to_node(&root).syntax().clone(),
146 )
147 })
148 }
149 Err(SyntheticSyntax) => continue,
150 }; 164 };
151 push_mismatch(syntax_ptr, mismatch.clone()); 165 let range = node.as_ref().original_file_range(&db);
166 let actual = format!(
167 "expected {}, got {}",
168 mismatch.expected.display_test(&db),
169 mismatch.actual.display_test(&db)
170 );
171 if let Some(annotation) = mismatches.remove(&range) {
172 assert_eq!(actual, annotation);
173 } else {
174 format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual);
175 }
152 } 176 }
153 for (expr, mismatch) in inference_result.expr_type_mismatches() { 177 for (expr, mismatch) in inference_result.expr_type_mismatches() {
154 let node = match body_source_map.expr_syntax(expr) { 178 let node = match body_source_map.expr_syntax(expr) {
@@ -158,45 +182,70 @@ fn check_mismatches_impl(ra_fixture: &str, allow_none: bool) {
158 } 182 }
159 Err(SyntheticSyntax) => continue, 183 Err(SyntheticSyntax) => continue,
160 }; 184 };
161 push_mismatch(node, mismatch.clone()); 185 let range = node.as_ref().original_file_range(&db);
162 } 186 let actual = format!(
163 } 187 "expected {}, got {}",
164 let mut checked_one = false; 188 mismatch.expected.display_test(&db),
165 for (file_id, annotations) in db.extract_annotations() { 189 mismatch.actual.display_test(&db)
166 for (range, expected) in annotations { 190 );
167 let file_range = FileRange { file_id, range }; 191 if let Some(annotation) = mismatches.remove(&range) {
168 if let Some(mismatch) = mismatches.remove(&file_range) { 192 assert_eq!(actual, annotation);
169 assert_eq!(mismatch, expected);
170 } else { 193 } else {
171 assert!(false, "Expected mismatch not encountered: {}\n", expected); 194 format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual);
172 } 195 }
173 checked_one = true;
174 } 196 }
175 } 197 }
198
176 let mut buf = String::new(); 199 let mut buf = String::new();
177 for (range, mismatch) in mismatches { 200 if !unexpected_type_mismatches.is_empty() {
178 format_to!(buf, "{:?}: {}\n", range.range, mismatch,); 201 format_to!(buf, "Unexpected type mismatches:\n{}", unexpected_type_mismatches);
202 }
203 if !mismatches.is_empty() {
204 format_to!(buf, "Unchecked mismatch annotations:\n");
205 for m in mismatches {
206 format_to!(buf, "{:?}: {}\n", m.0.range, m.1);
207 }
179 } 208 }
180 assert!(buf.is_empty(), "Unexpected type mismatches:\n{}", buf); 209 if !types.is_empty() {
210 format_to!(buf, "Unchecked type annotations:\n");
211 for t in types {
212 format_to!(buf, "{:?}: type {}\n", t.0.range, t.1);
213 }
214 }
215 assert!(buf.is_empty(), "{}", buf);
216}
181 217
182 assert!(checked_one || allow_none, "no `//^` annotations found"); 218fn expr_node(
219 body_source_map: &BodySourceMap,
220 expr: ExprId,
221 db: &TestDB,
222) -> Option<InFile<SyntaxNode>> {
223 Some(match body_source_map.expr_syntax(expr) {
224 Ok(sp) => {
225 let root = db.parse_or_expand(sp.file_id).unwrap();
226 sp.map(|ptr| ptr.to_node(&root).syntax().clone())
227 }
228 Err(SyntheticSyntax) => return None,
229 })
183} 230}
184 231
185fn type_at_range(db: &TestDB, pos: FileRange) -> Ty { 232fn pat_node(
186 let file = db.parse(pos.file_id).ok().unwrap(); 233 body_source_map: &BodySourceMap,
187 let expr = algo::find_node_at_range::<ast::Expr>(file.syntax(), pos.range).unwrap(); 234 pat: PatId,
188 let fn_def = expr.syntax().ancestors().find_map(ast::Fn::cast).unwrap(); 235 db: &TestDB,
189 let module = db.module_for_file(pos.file_id); 236) -> Option<InFile<SyntaxNode>> {
190 let func = *module.child_by_source(db)[keys::FUNCTION] 237 Some(match body_source_map.pat_syntax(pat) {
191 .get(&InFile::new(pos.file_id.into(), fn_def)) 238 Ok(sp) => {
192 .unwrap(); 239 let root = db.parse_or_expand(sp.file_id).unwrap();
193 240 sp.map(|ptr| {
194 let (_body, source_map) = db.body_with_source_map(func.into()); 241 ptr.either(
195 if let Some(expr_id) = source_map.node_expr(InFile::new(pos.file_id.into(), &expr)) { 242 |it| it.to_node(&root).syntax().clone(),
196 let infer = db.infer(func.into()); 243 |it| it.to_node(&root).syntax().clone(),
197 return infer[expr_id].clone(); 244 )
198 } 245 })
199 panic!("Can't find expression") 246 }
247 Err(SyntheticSyntax) => return None,
248 })
200} 249}
201 250
202fn infer(ra_fixture: &str) -> String { 251fn infer(ra_fixture: &str) -> String {
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index 71047703d..87089f09d 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -1,380 +1,157 @@
1use expect_test::expect; 1use super::{check, check_no_mismatches, check_types};
2
3use super::{check_infer, check_infer_with_mismatches, check_no_mismatches, check_types};
4 2
5#[test] 3#[test]
6fn infer_block_expr_type_mismatch() { 4fn block_expr_type_mismatch() {
7 check_infer( 5 // FIXME fix double type mismatch
6 check(
8 r" 7 r"
9 fn test() { 8fn test() {
10 let a: i32 = { 1i64 }; 9 let a: i32 = { 1i64 };
11 } 10 // ^^^^^^^^ expected i32, got i64
11 // ^^^^ expected i32, got i64
12}
12 ", 13 ",
13 expect![[r"
14 10..40 '{ ...4 }; }': ()
15 20..21 'a': i32
16 29..37 '{ 1i64 }': i64
17 31..35 '1i64': i64
18 "]],
19 ); 14 );
20} 15}
21 16
22#[test] 17#[test]
23fn coerce_places() { 18fn coerce_places() {
24 check_infer( 19 check_no_mismatches(
25 r#" 20 r#"
26 struct S<T> { a: T } 21//- minicore: coerce_unsized
22struct S<T> { a: T }
27 23
28 fn f<T>(_: &[T]) -> T { loop {} } 24fn f<T>(_: &[T]) -> T { loop {} }
29 fn g<T>(_: S<&[T]>) -> T { loop {} } 25fn g<T>(_: S<&[T]>) -> T { loop {} }
30 26
31 fn gen<T>() -> *mut [T; 2] { loop {} } 27fn gen<T>() -> *mut [T; 2] { loop {} }
32 fn test1<U>() -> *mut [U] { 28fn test1<U>() -> *mut [U] {
33 gen() 29 gen()
34 } 30}
35
36 fn test2() {
37 let arr: &[u8; 1] = &[1];
38
39 let a: &[_] = arr;
40 let b = f(arr);
41 let c: &[_] = { arr };
42 let d = g(S { a: arr });
43 let e: [&[_]; 1] = [arr];
44 let f: [&[_]; 2] = [arr; 2];
45 let g: (&[_], &[_]) = (arr, arr);
46 }
47 31
48 #[lang = "sized"] 32fn test2() {
49 pub trait Sized {} 33 let arr: &[u8; 1] = &[1];
50 #[lang = "unsize"]
51 pub trait Unsize<T: ?Sized> {}
52 #[lang = "coerce_unsized"]
53 pub trait CoerceUnsized<T> {}
54 34
55 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} 35 let a: &[_] = arr;
56 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} 36 let b = f(arr);
57 "#, 37 let c: &[_] = { arr };
58 expect![[r#" 38 let d = g(S { a: arr });
59 30..31 '_': &[T] 39 let e: [&[_]; 1] = [arr];
60 44..55 '{ loop {} }': T 40 let f: [&[_]; 2] = [arr; 2];
61 46..53 'loop {}': ! 41 let g: (&[_], &[_]) = (arr, arr);
62 51..53 '{}': () 42}
63 64..65 '_': S<&[T]> 43"#,
64 81..92 '{ loop {} }': T
65 83..90 'loop {}': !
66 88..90 '{}': ()
67 121..132 '{ loop {} }': *mut [T; 2]
68 123..130 'loop {}': !
69 128..130 '{}': ()
70 159..172 '{ gen() }': *mut [U]
71 165..168 'gen': fn gen<U>() -> *mut [U; 2]
72 165..170 'gen()': *mut [U; 2]
73 185..419 '{ ...rr); }': ()
74 195..198 'arr': &[u8; 1]
75 211..215 '&[1]': &[u8; 1]
76 212..215 '[1]': [u8; 1]
77 213..214 '1': u8
78 226..227 'a': &[u8]
79 236..239 'arr': &[u8; 1]
80 249..250 'b': u8
81 253..254 'f': fn f<u8>(&[u8]) -> u8
82 253..259 'f(arr)': u8
83 255..258 'arr': &[u8; 1]
84 269..270 'c': &[u8]
85 279..286 '{ arr }': &[u8]
86 281..284 'arr': &[u8; 1]
87 296..297 'd': u8
88 300..301 'g': fn g<u8>(S<&[u8]>) -> u8
89 300..315 'g(S { a: arr })': u8
90 302..314 'S { a: arr }': S<&[u8]>
91 309..312 'arr': &[u8; 1]
92 325..326 'e': [&[u8]; 1]
93 340..345 '[arr]': [&[u8]; 1]
94 341..344 'arr': &[u8; 1]
95 355..356 'f': [&[u8]; 2]
96 370..378 '[arr; 2]': [&[u8]; 2]
97 371..374 'arr': &[u8; 1]
98 376..377 '2': usize
99 388..389 'g': (&[u8], &[u8])
100 406..416 '(arr, arr)': (&[u8], &[u8])
101 407..410 'arr': &[u8; 1]
102 412..415 'arr': &[u8; 1]
103 "#]],
104 ); 44 );
105} 45}
106 46
107#[test] 47#[test]
108fn infer_let_stmt_coerce() { 48fn let_stmt_coerce() {
109 check_infer( 49 check_no_mismatches(
110 r" 50 r"
111 fn test() { 51//- minicore: coerce_unsized
112 let x: &[isize] = &[1]; 52fn test() {
113 let x: *const [isize] = &[1]; 53 let x: &[isize] = &[1];
114 } 54 let x: *const [isize] = &[1];
115 ", 55}
116 expect![[r#" 56",
117 10..75 '{ ...[1]; }': ()
118 20..21 'x': &[isize]
119 34..38 '&[1]': &[isize; 1]
120 35..38 '[1]': [isize; 1]
121 36..37 '1': isize
122 48..49 'x': *const [isize]
123 68..72 '&[1]': &[isize; 1]
124 69..72 '[1]': [isize; 1]
125 70..71 '1': isize
126 "#]],
127 ); 57 );
128} 58}
129 59
130#[test] 60#[test]
131fn infer_custom_coerce_unsized() { 61fn custom_coerce_unsized() {
132 check_infer( 62 check(
133 r#" 63 r#"
134 struct A<T: ?Sized>(*const T); 64//- minicore: coerce_unsized
135 struct B<T: ?Sized>(*const T); 65use core::{marker::Unsize, ops::CoerceUnsized};
136 struct C<T: ?Sized> { inner: *const T }
137 66
138 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} 67struct A<T: ?Sized>(*const T);
139 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} 68struct B<T: ?Sized>(*const T);
69struct C<T: ?Sized> { inner: *const T }
140 70
141 fn foo1<T>(x: A<[T]>) -> A<[T]> { x } 71impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
142 fn foo2<T>(x: B<[T]>) -> B<[T]> { x } 72impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
143 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
144 73
145 fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { 74fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
146 let d = foo1(a); 75fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
147 let e = foo2(b); 76fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
148 let f = foo3(c);
149 }
150 77
151 78fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
152 #[lang = "sized"] 79 let d = foo1(a);
153 pub trait Sized {} 80 // ^ expected A<[{unknown}]>, got A<[u8; 2]>
154 #[lang = "unsize"] 81 let e = foo2(b);
155 pub trait Unsize<T: ?Sized> {} 82 // ^ type: B<[u8]>
156 #[lang = "coerce_unsized"] 83 let f = foo3(c);
157 pub trait CoerceUnsized<T> {} 84 // ^ type: C<[u8]>
158 85}
159 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} 86"#,
160 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
161 "#,
162 expect![[r#"
163 257..258 'x': A<[T]>
164 278..283 '{ x }': A<[T]>
165 280..281 'x': A<[T]>
166 295..296 'x': B<[T]>
167 316..321 '{ x }': B<[T]>
168 318..319 'x': B<[T]>
169 333..334 'x': C<[T]>
170 354..359 '{ x }': C<[T]>
171 356..357 'x': C<[T]>
172 369..370 'a': A<[u8; 2]>
173 384..385 'b': B<[u8; 2]>
174 399..400 'c': C<[u8; 2]>
175 414..480 '{ ...(c); }': ()
176 424..425 'd': A<[{unknown}]>
177 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
178 428..435 'foo1(a)': A<[{unknown}]>
179 433..434 'a': A<[u8; 2]>
180 445..446 'e': B<[u8]>
181 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
182 449..456 'foo2(b)': B<[u8]>
183 454..455 'b': B<[u8; 2]>
184 466..467 'f': C<[u8]>
185 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
186 470..477 'foo3(c)': C<[u8]>
187 475..476 'c': C<[u8; 2]>
188 "#]],
189 ); 87 );
190} 88}
191 89
192#[test] 90#[test]
193fn infer_if_coerce() { 91fn if_coerce() {
194 check_infer( 92 check_no_mismatches(
195 r#" 93 r#"
196 fn foo<T>(x: &[T]) -> &[T] { loop {} } 94//- minicore: coerce_unsized
197 fn test() { 95fn foo<T>(x: &[T]) -> &[T] { x }
198 let x = if true { 96fn test() {
199 foo(&[1]) 97 let x = if true {
200 } else { 98 foo(&[1])
201 &[1] 99 } else {
202 }; 100 &[1]
203 } 101 };
204 102}
205 103"#,
206 #[lang = "sized"]
207 pub trait Sized {}
208 #[lang = "unsize"]
209 pub trait Unsize<T: ?Sized> {}
210 "#,
211 expect![[r#"
212 10..11 'x': &[T]
213 27..38 '{ loop {} }': &[T]
214 29..36 'loop {}': !
215 34..36 '{}': ()
216 49..125 '{ ... }; }': ()
217 59..60 'x': &[i32]
218 63..122 'if tru... }': &[i32]
219 66..70 'true': bool
220 71..96 '{ ... }': &[i32]
221 81..84 'foo': fn foo<i32>(&[i32]) -> &[i32]
222 81..90 'foo(&[1])': &[i32]
223 85..89 '&[1]': &[i32; 1]
224 86..89 '[1]': [i32; 1]
225 87..88 '1': i32
226 102..122 '{ ... }': &[i32; 1]
227 112..116 '&[1]': &[i32; 1]
228 113..116 '[1]': [i32; 1]
229 114..115 '1': i32
230 "#]],
231 ); 104 );
232} 105}
233 106
234#[test] 107#[test]
235fn infer_if_else_coerce() { 108fn if_else_coerce() {
236 check_infer( 109 check_no_mismatches(
237 r#" 110 r#"
238 fn foo<T>(x: &[T]) -> &[T] { loop {} } 111//- minicore: coerce_unsized
239 fn test() { 112fn foo<T>(x: &[T]) -> &[T] { x }
240 let x = if true { 113fn test() {
241 &[1] 114 let x = if true {
242 } else { 115 &[1]
243 foo(&[1]) 116 } else {
244 }; 117 foo(&[1])
245 } 118 };
246 119}
247 #[lang = "sized"] 120"#,
248 pub trait Sized {}
249 #[lang = "unsize"]
250 pub trait Unsize<T: ?Sized> {}
251 #[lang = "coerce_unsized"]
252 pub trait CoerceUnsized<T> {}
253
254 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
255 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
256 "#,
257 expect![[r#"
258 10..11 'x': &[T]
259 27..38 '{ loop {} }': &[T]
260 29..36 'loop {}': !
261 34..36 '{}': ()
262 49..125 '{ ... }; }': ()
263 59..60 'x': &[i32]
264 63..122 'if tru... }': &[i32]
265 66..70 'true': bool
266 71..91 '{ ... }': &[i32; 1]
267 81..85 '&[1]': &[i32; 1]
268 82..85 '[1]': [i32; 1]
269 83..84 '1': i32
270 97..122 '{ ... }': &[i32]
271 107..110 'foo': fn foo<i32>(&[i32]) -> &[i32]
272 107..116 'foo(&[1])': &[i32]
273 111..115 '&[1]': &[i32; 1]
274 112..115 '[1]': [i32; 1]
275 113..114 '1': i32
276 "#]],
277 ) 121 )
278} 122}
279 123
280#[test] 124#[test]
281fn infer_match_first_coerce() { 125fn match_first_coerce() {
282 check_infer( 126 check_no_mismatches(
283 r#" 127 r#"
284 fn foo<T>(x: &[T]) -> &[T] { loop {} } 128//- minicore: coerce_unsized
285 fn test(i: i32) { 129fn foo<T>(x: &[T]) -> &[T] { x }
286 let x = match i { 130fn test(i: i32) {
287 2 => foo(&[2]), 131 let x = match i {
288 1 => &[1], 132 2 => foo(&[2]),
289 _ => &[3], 133 1 => &[1],
290 }; 134 _ => &[3],
291 } 135 };
292 136}
293 #[lang = "sized"] 137"#,
294 pub trait Sized {}
295 #[lang = "unsize"]
296 pub trait Unsize<T: ?Sized> {}
297 "#,
298 expect![[r#"
299 10..11 'x': &[T]
300 27..38 '{ loop {} }': &[T]
301 29..36 'loop {}': !
302 34..36 '{}': ()
303 47..48 'i': i32
304 55..149 '{ ... }; }': ()
305 65..66 'x': &[i32]
306 69..146 'match ... }': &[i32]
307 75..76 'i': i32
308 87..88 '2': i32
309 87..88 '2': i32
310 92..95 'foo': fn foo<i32>(&[i32]) -> &[i32]
311 92..101 'foo(&[2])': &[i32]
312 96..100 '&[2]': &[i32; 1]
313 97..100 '[2]': [i32; 1]
314 98..99 '2': i32
315 111..112 '1': i32
316 111..112 '1': i32
317 116..120 '&[1]': &[i32; 1]
318 117..120 '[1]': [i32; 1]
319 118..119 '1': i32
320 130..131 '_': i32
321 135..139 '&[3]': &[i32; 1]
322 136..139 '[3]': [i32; 1]
323 137..138 '3': i32
324 "#]],
325 ); 138 );
326} 139}
327 140
328#[test] 141#[test]
329fn infer_match_second_coerce() { 142fn match_second_coerce() {
330 check_infer( 143 check_no_mismatches(
331 r#" 144 r#"
332 fn foo<T>(x: &[T]) -> &[T] { loop {} } 145//- minicore: coerce_unsized
333 fn test(i: i32) { 146fn foo<T>(x: &[T]) -> &[T] { loop {} }
334 let x = match i { 147fn test(i: i32) {
335 1 => &[1], 148 let x = match i {
336 2 => foo(&[2]), 149 1 => &[1],
337 _ => &[3], 150 2 => foo(&[2]),
338 }; 151 _ => &[3],
339 } 152 };
340 153}
341 #[lang = "sized"] 154"#,
342 pub trait Sized {}
343 #[lang = "unsize"]
344 pub trait Unsize<T: ?Sized> {}
345 #[lang = "coerce_unsized"]
346 pub trait CoerceUnsized<T> {}
347
348 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
349 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
350 "#,
351 expect![[r#"
352 10..11 'x': &[T]
353 27..38 '{ loop {} }': &[T]
354 29..36 'loop {}': !
355 34..36 '{}': ()
356 47..48 'i': i32
357 55..149 '{ ... }; }': ()
358 65..66 'x': &[i32]
359 69..146 'match ... }': &[i32]
360 75..76 'i': i32
361 87..88 '1': i32
362 87..88 '1': i32
363 92..96 '&[1]': &[i32; 1]
364 93..96 '[1]': [i32; 1]
365 94..95 '1': i32
366 106..107 '2': i32
367 106..107 '2': i32
368 111..114 'foo': fn foo<i32>(&[i32]) -> &[i32]
369 111..120 'foo(&[2])': &[i32]
370 115..119 '&[2]': &[i32; 1]
371 116..119 '[2]': [i32; 1]
372 117..118 '2': i32
373 130..131 '_': i32
374 135..139 '&[3]': &[i32; 1]
375 136..139 '[3]': [i32; 1]
376 137..138 '3': i32
377 "#]],
378 ); 155 );
379} 156}
380 157
@@ -382,207 +159,103 @@ fn infer_match_second_coerce() {
382fn coerce_merge_one_by_one1() { 159fn coerce_merge_one_by_one1() {
383 cov_mark::check!(coerce_merge_fail_fallback); 160 cov_mark::check!(coerce_merge_fail_fallback);
384 161
385 check_infer( 162 check(
386 r" 163 r"
387 fn test() { 164fn test() {
388 let t = &mut 1; 165 let t = &mut 1;
389 let x = match 1 { 166 let x = match 1 {
390 1 => t as *mut i32, 167 1 => t as *mut i32,
391 2 => t as &i32, 168 2 => t as &i32,
392 _ => t as *const i32, 169 //^^^^^^^^^ expected *mut i32, got &i32
393 }; 170 _ => t as *const i32,
394 } 171 };
172 x;
173 //^ type: *const i32
174}
395 ", 175 ",
396 expect![[r"
397 10..144 '{ ... }; }': ()
398 20..21 't': &mut i32
399 24..30 '&mut 1': &mut i32
400 29..30 '1': i32
401 40..41 'x': *const i32
402 44..141 'match ... }': *const i32
403 50..51 '1': i32
404 62..63 '1': i32
405 62..63 '1': i32
406 67..68 't': &mut i32
407 67..80 't as *mut i32': *mut i32
408 90..91 '2': i32
409 90..91 '2': i32
410 95..96 't': &mut i32
411 95..104 't as &i32': &i32
412 114..115 '_': i32
413 119..120 't': &mut i32
414 119..134 't as *const i32': *const i32
415 "]],
416 ); 176 );
417} 177}
418 178
419#[test] 179#[test]
420fn return_coerce_unknown() { 180fn return_coerce_unknown() {
421 check_infer_with_mismatches( 181 check_types(
422 r" 182 r"
423 fn foo() -> u32 { 183fn foo() -> u32 {
424 return unknown; 184 return unknown;
425 } 185 //^^^^^^^ u32
186}
426 ", 187 ",
427 expect![[r"
428 16..39 '{ ...own; }': u32
429 22..36 'return unknown': !
430 29..36 'unknown': u32
431 "]],
432 ); 188 );
433} 189}
434 190
435#[test] 191#[test]
436fn coerce_autoderef() { 192fn coerce_autoderef() {
437 check_infer_with_mismatches( 193 check_no_mismatches(
438 r" 194 r"
439 struct Foo; 195struct Foo;
440 fn takes_ref_foo(x: &Foo) {} 196fn takes_ref_foo(x: &Foo) {}
441 fn test() { 197fn test() {
442 takes_ref_foo(&Foo); 198 takes_ref_foo(&Foo);
443 takes_ref_foo(&&Foo); 199 takes_ref_foo(&&Foo);
444 takes_ref_foo(&&&Foo); 200 takes_ref_foo(&&&Foo);
445 } 201}",
446 ",
447 expect![[r"
448 29..30 'x': &Foo
449 38..40 '{}': ()
450 51..132 '{ ...oo); }': ()
451 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo)
452 57..76 'takes_...(&Foo)': ()
453 71..75 '&Foo': &Foo
454 72..75 'Foo': Foo
455 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo)
456 82..102 'takes_...&&Foo)': ()
457 96..101 '&&Foo': &&Foo
458 97..101 '&Foo': &Foo
459 98..101 'Foo': Foo
460 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo)
461 108..129 'takes_...&&Foo)': ()
462 122..128 '&&&Foo': &&&Foo
463 123..128 '&&Foo': &&Foo
464 124..128 '&Foo': &Foo
465 125..128 'Foo': Foo
466 "]],
467 ); 202 );
468} 203}
469 204
470#[test] 205#[test]
471fn coerce_autoderef_generic() { 206fn coerce_autoderef_generic() {
472 check_infer_with_mismatches( 207 check_no_mismatches(
473 r" 208 r#"
474 struct Foo; 209struct Foo;
475 fn takes_ref<T>(x: &T) -> T { *x } 210fn takes_ref<T>(x: &T) -> T { *x }
476 fn test() { 211fn test() {
477 takes_ref(&Foo); 212 takes_ref(&Foo);
478 takes_ref(&&Foo); 213 takes_ref(&&Foo);
479 takes_ref(&&&Foo); 214 takes_ref(&&&Foo);
480 } 215}
481 ", 216"#,
482 expect![[r"
483 28..29 'x': &T
484 40..46 '{ *x }': T
485 42..44 '*x': T
486 43..44 'x': &T
487 57..126 '{ ...oo); }': ()
488 63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo
489 63..78 'takes_ref(&Foo)': Foo
490 73..77 '&Foo': &Foo
491 74..77 'Foo': Foo
492 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo
493 84..100 'takes_...&&Foo)': &Foo
494 94..99 '&&Foo': &&Foo
495 95..99 '&Foo': &Foo
496 96..99 'Foo': Foo
497 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo
498 106..123 'takes_...&&Foo)': &&Foo
499 116..122 '&&&Foo': &&&Foo
500 117..122 '&&Foo': &&Foo
501 118..122 '&Foo': &Foo
502 119..122 'Foo': Foo
503 "]],
504 ); 217 );
505} 218}
506 219
507#[test] 220#[test]
508fn coerce_autoderef_block() { 221fn coerce_autoderef_block() {
509 check_infer_with_mismatches( 222 check_no_mismatches(
510 r#" 223 r#"
511 struct String {} 224//- minicore: deref
512 #[lang = "deref"] 225struct String {}
513 trait Deref { type Target; } 226impl core::ops::Deref for String { type Target = str; }
514 impl Deref for String { type Target = str; } 227fn takes_ref_str(x: &str) {}
515 fn takes_ref_str(x: &str) {} 228fn returns_string() -> String { loop {} }
516 fn returns_string() -> String { loop {} } 229fn test() {
517 fn test() { 230 takes_ref_str(&{ returns_string() });
518 takes_ref_str(&{ returns_string() }); 231}
519 } 232"#,
520 "#,
521 expect![[r"
522 126..127 'x': &str
523 135..137 '{}': ()
524 168..179 '{ loop {} }': String
525 170..177 'loop {}': !
526 175..177 '{}': ()
527 190..235 '{ ... }); }': ()
528 196..209 'takes_ref_str': fn takes_ref_str(&str)
529 196..232 'takes_...g() })': ()
530 210..231 '&{ ret...ng() }': &String
531 211..231 '{ retu...ng() }': String
532 213..227 'returns_string': fn returns_string() -> String
533 213..229 'return...ring()': String
534 "]],
535 ); 233 );
536} 234}
537 235
538#[test] 236#[test]
539fn closure_return_coerce() { 237fn closure_return_coerce() {
540 check_infer_with_mismatches( 238 check_no_mismatches(
541 r" 239 r"
542 fn foo() { 240fn foo() {
543 let x = || { 241 let x = || {
544 if true { 242 if true {
545 return &1u32; 243 return &1u32;
546 }
547 &&1u32
548 };
549 } 244 }
550 ", 245 &&1u32
551 expect![[r" 246 };
552 9..105 '{ ... }; }': () 247}",
553 19..20 'x': || -> &u32
554 23..102 '|| { ... }': || -> &u32
555 26..102 '{ ... }': &u32
556 36..81 'if tru... }': ()
557 39..43 'true': bool
558 44..81 '{ ... }': ()
559 58..70 'return &1u32': !
560 65..70 '&1u32': &u32
561 66..70 '1u32': u32
562 90..96 '&&1u32': &&u32
563 91..96 '&1u32': &u32
564 92..96 '1u32': u32
565 "]],
566 ); 248 );
567} 249}
568 250
569#[test] 251#[test]
570fn coerce_fn_item_to_fn_ptr() { 252fn coerce_fn_item_to_fn_ptr() {
571 check_infer_with_mismatches( 253 check_no_mismatches(
572 r" 254 r"
573 fn foo(x: u32) -> isize { 1 } 255fn foo(x: u32) -> isize { 1 }
574 fn test() { 256fn test() {
575 let f: fn(u32) -> isize = foo; 257 let f: fn(u32) -> isize = foo;
576 } 258}",
577 ",
578 expect![[r"
579 7..8 'x': u32
580 24..29 '{ 1 }': isize
581 26..27 '1': isize
582 40..78 '{ ...foo; }': ()
583 50..51 'f': fn(u32) -> isize
584 72..75 'foo': fn foo(u32) -> isize
585 "]],
586 ); 259 );
587} 260}
588 261
@@ -590,340 +263,160 @@ fn coerce_fn_item_to_fn_ptr() {
590fn coerce_fn_items_in_match_arms() { 263fn coerce_fn_items_in_match_arms() {
591 cov_mark::check!(coerce_fn_reification); 264 cov_mark::check!(coerce_fn_reification);
592 265
593 check_infer_with_mismatches( 266 check_types(
594 r" 267 r"
595 fn foo1(x: u32) -> isize { 1 } 268fn foo1(x: u32) -> isize { 1 }
596 fn foo2(x: u32) -> isize { 2 } 269fn foo2(x: u32) -> isize { 2 }
597 fn foo3(x: u32) -> isize { 3 } 270fn foo3(x: u32) -> isize { 3 }
598 fn test() { 271fn test() {
599 let x = match 1 { 272 let x = match 1 {
600 1 => foo1, 273 1 => foo1,
601 2 => foo2, 274 2 => foo2,
602 _ => foo3, 275 _ => foo3,
603 }; 276 };
604 } 277 x;
605 ", 278 //^ fn(u32) -> isize
606 expect![[r" 279}",
607 8..9 'x': u32
608 25..30 '{ 1 }': isize
609 27..28 '1': isize
610 39..40 'x': u32
611 56..61 '{ 2 }': isize
612 58..59 '2': isize
613 70..71 'x': u32
614 87..92 '{ 3 }': isize
615 89..90 '3': isize
616 103..192 '{ ... }; }': ()
617 113..114 'x': fn(u32) -> isize
618 117..189 'match ... }': fn(u32) -> isize
619 123..124 '1': i32
620 135..136 '1': i32
621 135..136 '1': i32
622 140..144 'foo1': fn foo1(u32) -> isize
623 154..155 '2': i32
624 154..155 '2': i32
625 159..163 'foo2': fn foo2(u32) -> isize
626 173..174 '_': i32
627 178..182 'foo3': fn foo3(u32) -> isize
628 "]],
629 ); 280 );
630} 281}
631 282
632#[test] 283#[test]
633fn coerce_closure_to_fn_ptr() { 284fn coerce_closure_to_fn_ptr() {
634 check_infer_with_mismatches( 285 check_no_mismatches(
635 r" 286 r"
636 fn test() { 287fn test() {
637 let f: fn(u32) -> isize = |x| { 1 }; 288 let f: fn(u32) -> isize = |x| { 1 };
638 } 289}",
639 ",
640 expect![[r"
641 10..54 '{ ...1 }; }': ()
642 20..21 'f': fn(u32) -> isize
643 42..51 '|x| { 1 }': |u32| -> isize
644 43..44 'x': u32
645 46..51 '{ 1 }': isize
646 48..49 '1': isize
647 "]],
648 ); 290 );
649} 291}
650 292
651#[test] 293#[test]
652fn coerce_placeholder_ref() { 294fn coerce_placeholder_ref() {
653 // placeholders should unify, even behind references 295 // placeholders should unify, even behind references
654 check_infer_with_mismatches( 296 check_no_mismatches(
655 r" 297 r"
656 struct S<T> { t: T } 298struct S<T> { t: T }
657 impl<TT> S<TT> { 299impl<TT> S<TT> {
658 fn get(&self) -> &TT { 300 fn get(&self) -> &TT {
659 &self.t 301 &self.t
660 } 302 }
661 } 303}",
662 ",
663 expect![[r"
664 50..54 'self': &S<TT>
665 63..86 '{ ... }': &TT
666 73..80 '&self.t': &TT
667 74..78 'self': &S<TT>
668 74..80 'self.t': TT
669 "]],
670 ); 304 );
671} 305}
672 306
673#[test] 307#[test]
674fn coerce_unsize_array() { 308fn coerce_unsize_array() {
675 check_infer_with_mismatches( 309 check_types(
676 r#" 310 r#"
677 #[lang = "unsize"] 311//- minicore: coerce_unsized
678 pub trait Unsize<T> {} 312fn test() {
679 #[lang = "coerce_unsized"] 313 let f: &[usize] = &[1, 2, 3];
680 pub trait CoerceUnsized<T> {} 314 //^ usize
681 315}"#,
682 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
683
684 fn test() {
685 let f: &[usize] = &[1, 2, 3];
686 }
687 "#,
688 expect![[r#"
689 161..198 '{ ... 3]; }': ()
690 171..172 'f': &[usize]
691 185..195 '&[1, 2, 3]': &[usize; 3]
692 186..195 '[1, 2, 3]': [usize; 3]
693 187..188 '1': usize
694 190..191 '2': usize
695 193..194 '3': usize
696 "#]],
697 ); 316 );
698} 317}
699 318
700#[test] 319#[test]
701fn coerce_unsize_trait_object_simple() { 320fn coerce_unsize_trait_object_simple() {
702 check_infer_with_mismatches( 321 check_types(
703 r#"
704 #[lang = "sized"]
705 pub trait Sized {}
706 #[lang = "unsize"]
707 pub trait Unsize<T> {}
708 #[lang = "coerce_unsized"]
709 pub trait CoerceUnsized<T> {}
710
711 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
712
713 trait Foo<T, U> {}
714 trait Bar<U, T, X>: Foo<T, U> {}
715 trait Baz<T, X>: Bar<usize, T, X> {}
716
717 struct S<T, X>;
718 impl<T, X> Foo<T, usize> for S<T, X> {}
719 impl<T, X> Bar<usize, T, X> for S<T, X> {}
720 impl<T, X> Baz<T, X> for S<T, X> {}
721
722 fn test() {
723 let obj: &dyn Baz<i8, i16> = &S;
724 let obj: &dyn Bar<_, i8, i16> = &S;
725 let obj: &dyn Foo<i8, _> = &S;
726 }
727 "#,
728 expect![[r"
729 424..539 '{ ... &S; }': ()
730 434..437 'obj': &dyn Baz<i8, i16>
731 459..461 '&S': &S<i8, i16>
732 460..461 'S': S<i8, i16>
733 471..474 'obj': &dyn Bar<usize, i8, i16>
734 499..501 '&S': &S<i8, i16>
735 500..501 'S': S<i8, i16>
736 511..514 'obj': &dyn Foo<i8, usize>
737 534..536 '&S': &S<i8, {unknown}>
738 535..536 'S': S<i8, {unknown}>
739 "]],
740 );
741}
742
743#[test]
744// The rust reference says this should be possible, but rustc doesn't implement
745// it. We used to support it, but Chalk doesn't.
746#[ignore]
747fn coerce_unsize_trait_object_to_trait_object() {
748 check_infer_with_mismatches(
749 r#" 322 r#"
750 #[lang = "sized"] 323//- minicore: coerce_unsized
751 pub trait Sized {} 324trait Foo<T, U> {}
752 #[lang = "unsize"] 325trait Bar<U, T, X>: Foo<T, U> {}
753 pub trait Unsize<T> {} 326trait Baz<T, X>: Bar<usize, T, X> {}
754 #[lang = "coerce_unsized"] 327
755 pub trait CoerceUnsized<T> {} 328struct S<T, X>;
756 329impl<T, X> Foo<T, usize> for S<T, X> {}
757 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 330impl<T, X> Bar<usize, T, X> for S<T, X> {}
758 331impl<T, X> Baz<T, X> for S<T, X> {}
759 trait Foo<T, U> {} 332
760 trait Bar<U, T, X>: Foo<T, U> {} 333fn test() {
761 trait Baz<T, X>: Bar<usize, T, X> {} 334 let obj: &dyn Baz<i8, i16> = &S;
762 335 //^ S<i8, i16>
763 struct S<T, X>; 336 let obj: &dyn Bar<_, i8, i16> = &S;
764 impl<T, X> Foo<T, usize> for S<T, X> {} 337 //^ S<i8, i16>
765 impl<T, X> Bar<usize, T, X> for S<T, X> {} 338 let obj: &dyn Foo<i8, _> = &S;
766 impl<T, X> Baz<T, X> for S<T, X> {} 339 //^ S<i8, {unknown}>
767 340}"#,
768 fn test() {
769 let obj: &dyn Baz<i8, i16> = &S;
770 let obj: &dyn Bar<_, _, _> = obj;
771 let obj: &dyn Foo<_, _> = obj;
772 let obj2: &dyn Baz<i8, i16> = &S;
773 let _: &dyn Foo<_, _> = obj2;
774 }
775 "#,
776 expect![[r"
777 424..609 '{ ...bj2; }': ()
778 434..437 'obj': &dyn Baz<i8, i16>
779 459..461 '&S': &S<i8, i16>
780 460..461 'S': S<i8, i16>
781 471..474 'obj': &dyn Bar<usize, i8, i16>
782 496..499 'obj': &dyn Baz<i8, i16>
783 509..512 'obj': &dyn Foo<i8, usize>
784 531..534 'obj': &dyn Bar<usize, i8, i16>
785 544..548 'obj2': &dyn Baz<i8, i16>
786 570..572 '&S': &S<i8, i16>
787 571..572 'S': S<i8, i16>
788 582..583 '_': &dyn Foo<i8, usize>
789 602..606 'obj2': &dyn Baz<i8, i16>
790 "]],
791 ); 341 );
792} 342}
793 343
794#[test] 344#[test]
795fn coerce_unsize_super_trait_cycle() { 345fn coerce_unsize_super_trait_cycle() {
796 check_infer_with_mismatches( 346 check_no_mismatches(
797 r#" 347 r#"
798 #[lang = "sized"] 348//- minicore: coerce_unsized
799 pub trait Sized {} 349trait A {}
800 #[lang = "unsize"] 350trait B: C + A {}
801 pub trait Unsize<T> {} 351trait C: B {}
802 #[lang = "coerce_unsized"] 352trait D: C
803 pub trait CoerceUnsized<T> {} 353
804 354struct S;
805 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 355impl A for S {}
806 356impl B for S {}
807 trait A {} 357impl C for S {}
808 trait B: C + A {} 358impl D for S {}
809 trait C: B {} 359
810 trait D: C 360fn test() {
811 361 let obj: &dyn D = &S;
812 struct S; 362 let obj: &dyn A = &S;
813 impl A for S {} 363}
814 impl B for S {} 364"#,
815 impl C for S {}
816 impl D for S {}
817
818 fn test() {
819 let obj: &dyn D = &S;
820 let obj: &dyn A = &S;
821 }
822 "#,
823 expect![[r"
824 328..383 '{ ... &S; }': ()
825 338..341 'obj': &dyn D
826 352..354 '&S': &S
827 353..354 'S': S
828 364..367 'obj': &dyn A
829 378..380 '&S': &S
830 379..380 'S': S
831 "]],
832 ); 365 );
833} 366}
834 367
835#[test] 368#[test]
836fn coerce_unsize_generic() { 369fn coerce_unsize_generic() {
837 // FIXME: fix the type mismatches here 370 // FIXME: fix the type mismatches here
838 check_infer_with_mismatches( 371 check(
839 r#" 372 r#"
840 #[lang = "unsize"] 373//- minicore: coerce_unsized
841 pub trait Unsize<T> {} 374struct Foo<T> { t: T };
842 #[lang = "coerce_unsized"] 375struct Bar<T>(Foo<T>);
843 pub trait CoerceUnsized<T> {}
844
845 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
846
847 struct Foo<T> { t: T };
848 struct Bar<T>(Foo<T>);
849 376
850 fn test() { 377fn test() {
851 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; 378 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
852 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); 379 //^^^^^^^^^ expected [usize], got [usize; 3]
853 } 380 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
854 "#, 381 //^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &Bar<[usize]>, got &Bar<[i32; 3]>
855 expect![[r#" 382}
856 209..317 '{ ... }); }': () 383"#,
857 219..220 '_': &Foo<[usize]>
858 238..259 '&Foo {..., 3] }': &Foo<[usize]>
859 239..259 'Foo { ..., 3] }': Foo<[usize]>
860 248..257 '[1, 2, 3]': [usize; 3]
861 249..250 '1': usize
862 252..253 '2': usize
863 255..256 '3': usize
864 269..270 '_': &Bar<[usize]>
865 288..314 '&Bar(F... 3] })': &Bar<[i32; 3]>
866 289..292 'Bar': Bar<[i32; 3]>(Foo<[i32; 3]>) -> Bar<[i32; 3]>
867 289..314 'Bar(Fo... 3] })': Bar<[i32; 3]>
868 293..313 'Foo { ..., 3] }': Foo<[i32; 3]>
869 302..311 '[1, 2, 3]': [i32; 3]
870 303..304 '1': i32
871 306..307 '2': i32
872 309..310 '3': i32
873 248..257: expected [usize], got [usize; 3]
874 288..314: expected &Bar<[usize]>, got &Bar<[i32; 3]>
875 "#]],
876 ); 384 );
877} 385}
878 386
879#[test] 387#[test]
880fn coerce_unsize_apit() { 388fn coerce_unsize_apit() {
881 // FIXME: #8984 389 // FIXME: #8984
882 check_infer_with_mismatches( 390 check(
883 r#" 391 r#"
884#[lang = "sized"] 392//- minicore: coerce_unsized
885pub trait Sized {}
886#[lang = "unsize"]
887pub trait Unsize<T> {}
888#[lang = "coerce_unsized"]
889pub trait CoerceUnsized<T> {}
890
891impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
892
893trait Foo {} 393trait Foo {}
894 394
895fn test(f: impl Foo) { 395fn test(f: impl Foo) {
896 let _: &dyn Foo = &f; 396 let _: &dyn Foo = &f;
397 //^^ expected &dyn Foo, got &impl Foo
897} 398}
898 "#, 399 "#,
899 expect![[r#"
900 210..211 'f': impl Foo
901 223..252 '{ ... &f; }': ()
902 233..234 '_': &dyn Foo
903 247..249 '&f': &impl Foo
904 248..249 'f': impl Foo
905 247..249: expected &dyn Foo, got &impl Foo
906 "#]],
907 ); 400 );
908} 401}
909 402
910#[test] 403#[test]
911fn infer_two_closures_lub() { 404fn two_closures_lub() {
912 check_types( 405 check_types(
913 r#" 406 r#"
914fn foo(c: i32) { 407fn foo(c: i32) {
915 let add = |a: i32, b: i32| a + b; 408 let add = |a: i32, b: i32| a + b;
916 let sub = |a, b| a - b; 409 let sub = |a, b| a - b;
917 //^ |i32, i32| -> i32 410 //^^^^^^^^^^^^ |i32, i32| -> i32
918 if c > 42 { add } else { sub }; 411 if c > 42 { add } else { sub };
919 //^ fn(i32, i32) -> i32 412 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fn(i32, i32) -> i32
920} 413}
921 "#, 414 "#,
922 ) 415 )
923} 416}
924 417
925#[test] 418#[test]
926fn infer_match_diverging_branch_1() { 419fn match_diverging_branch_1() {
927 check_types( 420 check_types(
928 r#" 421 r#"
929enum Result<T> { Ok(T), Err } 422enum Result<T> { Ok(T), Err }
@@ -942,7 +435,7 @@ fn test() -> i32 {
942} 435}
943 436
944#[test] 437#[test]
945fn infer_match_diverging_branch_2() { 438fn match_diverging_branch_2() {
946 // same as 1 except for order of branches 439 // same as 1 except for order of branches
947 check_types( 440 check_types(
948 r#" 441 r#"
@@ -998,15 +491,7 @@ fn main() {
998fn coerce_unsize_expected_type() { 491fn coerce_unsize_expected_type() {
999 check_no_mismatches( 492 check_no_mismatches(
1000 r#" 493 r#"
1001#[lang = "sized"] 494//- minicore: coerce_unsized
1002pub trait Sized {}
1003#[lang = "unsize"]
1004pub trait Unsize<T> {}
1005#[lang = "coerce_unsized"]
1006pub trait CoerceUnsized<T> {}
1007
1008impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
1009
1010fn main() { 495fn main() {
1011 let foo: &[u32] = &[1, 2]; 496 let foo: &[u32] = &[1, 2];
1012 let foo: &[u32] = match true { 497 let foo: &[u32] = match true {
diff --git a/crates/hir_ty/src/tests/display_source_code.rs b/crates/hir_ty/src/tests/display_source_code.rs
index 3d29021aa..058cd02d7 100644
--- a/crates/hir_ty/src/tests/display_source_code.rs
+++ b/crates/hir_ty/src/tests/display_source_code.rs
@@ -10,8 +10,8 @@ mod foo {
10 10
11fn bar() { 11fn bar() {
12 let foo: foo::Foo = foo::Foo; 12 let foo: foo::Foo = foo::Foo;
13 foo 13 foo;
14} //^ foo::Foo 14} //^^^ foo::Foo
15 15
16"#, 16"#,
17 ); 17 );
@@ -25,7 +25,7 @@ struct Foo<T = u8> { t: T }
25fn main() { 25fn main() {
26 let foo = Foo { t: 5u8 }; 26 let foo = Foo { t: 5u8 };
27 foo; 27 foo;
28} //^ Foo 28} //^^^ Foo
29"#, 29"#,
30 ); 30 );
31 31
@@ -35,7 +35,7 @@ struct Foo<K, T = u8> { k: K, t: T }
35fn main() { 35fn main() {
36 let foo = Foo { k: 400, t: 5u8 }; 36 let foo = Foo { k: 400, t: 5u8 };
37 foo; 37 foo;
38} //^ Foo<i32> 38} //^^^ Foo<i32>
39"#, 39"#,
40 ); 40 );
41} 41}
@@ -50,7 +50,7 @@ fn foo() -> *const (impl Unpin + Sized) { loop {} }
50fn main() { 50fn main() {
51 let foo = foo(); 51 let foo = foo();
52 foo; 52 foo;
53} //^ *const (impl Unpin + Sized) 53} //^^^ *const (impl Unpin + Sized)
54"#, 54"#,
55 ); 55 );
56} 56}
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index d14103aab..2cf41e49e 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -435,11 +435,11 @@ fn processes_impls_generated_by_macros() {
435macro_rules! m { 435macro_rules! m {
436 ($ident:ident) => (impl Trait for $ident {}) 436 ($ident:ident) => (impl Trait for $ident {})
437} 437}
438trait Trait { fn foo(self) -> u128 {} } 438trait Trait { fn foo(self) -> u128 { 0 } }
439struct S; 439struct S;
440m!(S); 440m!(S);
441fn test() { S.foo(); } 441fn test() { S.foo(); }
442 //^ u128 442 //^^^^^^^ u128
443"#, 443"#,
444 ); 444 );
445} 445}
@@ -457,7 +457,7 @@ impl S {
457} 457}
458 458
459fn test() { S.foo(); } 459fn test() { S.foo(); }
460 //^ u128 460 //^^^^^^^ u128
461"#, 461"#,
462 ); 462 );
463} 463}
@@ -479,7 +479,7 @@ impl S {
479} 479}
480 480
481fn test() { S.foo(); } 481fn test() { S.foo(); }
482 //^ u128 482 //^^^^^^^ u128
483"#, 483"#,
484 ); 484 );
485} 485}
@@ -743,7 +743,7 @@ include!("foo.rs");
743 743
744fn main() { 744fn main() {
745 bar(); 745 bar();
746} //^ u32 746} //^^^^^ u32
747 747
748//- /foo.rs 748//- /foo.rs
749fn bar() -> u32 {0} 749fn bar() -> u32 {0}
@@ -781,7 +781,7 @@ include!("f/foo.rs");
781 781
782fn main() { 782fn main() {
783 bar::bar(); 783 bar::bar();
784} //^ u32 784} //^^^^^^^^^^ u32
785 785
786//- /f/foo.rs 786//- /f/foo.rs
787pub mod bar; 787pub mod bar;
@@ -853,7 +853,7 @@ include!("foo.rs");
853 853
854fn main() { 854fn main() {
855 RegisterBlock { }; 855 RegisterBlock { };
856 //^ RegisterBlock 856 //^^^^^^^^^^^^^^^^^ RegisterBlock
857} 857}
858 "#; 858 "#;
859 let fixture = format!("{}\n//- /foo.rs\n{}", fixture, data); 859 let fixture = format!("{}\n//- /foo.rs\n{}", fixture, data);
@@ -879,7 +879,7 @@ include!(concat!("f", "oo.rs"));
879 879
880fn main() { 880fn main() {
881 bar(); 881 bar();
882} //^ u32 882} //^^^^^ u32
883 883
884//- /foo.rs 884//- /foo.rs
885fn bar() -> u32 {0} 885fn bar() -> u32 {0}
@@ -905,7 +905,7 @@ include!(concat!(env!("OUT_DIR"), "/foo.rs"));
905 905
906fn main() { 906fn main() {
907 bar(); 907 bar();
908} //^ {unknown} 908} //^^^^^ {unknown}
909 909
910//- /foo.rs 910//- /foo.rs
911fn bar() -> u32 {0} 911fn bar() -> u32 {0}
@@ -923,7 +923,7 @@ macro_rules! include {() => {}}
923include!("main.rs"); 923include!("main.rs");
924 924
925fn main() { 925fn main() {
926 0 926 0;
927} //^ i32 927} //^ i32
928"#, 928"#,
929 ); 929 );
@@ -979,7 +979,7 @@ fn infer_derive_clone_simple() {
979struct S; 979struct S;
980fn test() { 980fn test() {
981 S.clone(); 981 S.clone();
982} //^ S 982} //^^^^^^^^^ S
983 983
984//- /lib.rs crate:core 984//- /lib.rs crate:core
985pub mod prelude { 985pub mod prelude {
@@ -1028,7 +1028,7 @@ pub struct S;
1028use core::S; 1028use core::S;
1029fn test() { 1029fn test() {
1030 S.clone(); 1030 S.clone();
1031} //^ S 1031} //^^^^^^^^^ S
1032"#, 1032"#,
1033 ); 1033 );
1034} 1034}
@@ -1044,7 +1044,8 @@ struct S;
1044struct Wrapper<T>(T); 1044struct Wrapper<T>(T);
1045struct NonClone; 1045struct NonClone;
1046fn test() { 1046fn test() {
1047 (Wrapper(S).clone(), Wrapper(NonClone).clone()); 1047 let x = (Wrapper(S).clone(), Wrapper(NonClone).clone());
1048 x;
1048 //^ (Wrapper<S>, {unknown}) 1049 //^ (Wrapper<S>, {unknown})
1049} 1050}
1050 1051
@@ -1079,7 +1080,7 @@ struct S{}
1079 1080
1080fn test() { 1081fn test() {
1081 S{}; 1082 S{};
1082} //^ S 1083} //^^^ S
1083"#, 1084"#,
1084 ); 1085 );
1085} 1086}
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index f26b2c8a7..3f7a37295 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -257,7 +257,7 @@ fn test() {
257mod foo { 257mod foo {
258 struct S; 258 struct S;
259 impl S { 259 impl S {
260 fn thing() -> i128 {} 260 fn thing() -> i128 { 0 }
261 } 261 }
262} 262}
263"#, 263"#,
@@ -267,164 +267,128 @@ mod foo {
267#[test] 267#[test]
268fn infer_trait_method_simple() { 268fn infer_trait_method_simple() {
269 // the trait implementation is intentionally incomplete -- it shouldn't matter 269 // the trait implementation is intentionally incomplete -- it shouldn't matter
270 check_infer( 270 check_types(
271 r#" 271 r#"
272 trait Trait1 { 272trait Trait1 {
273 fn method(&self) -> u32; 273 fn method(&self) -> u32;
274 } 274}
275 struct S1; 275struct S1;
276 impl Trait1 for S1 {} 276impl Trait1 for S1 {}
277 trait Trait2 { 277trait Trait2 {
278 fn method(&self) -> i128; 278 fn method(&self) -> i128;
279 } 279}
280 struct S2; 280struct S2;
281 impl Trait2 for S2 {} 281impl Trait2 for S2 {}
282 fn test() { 282fn test() {
283 S1.method(); // -> u32 283 S1.method();
284 S2.method(); // -> i128 284 //^^^^^^^^^^^ u32
285 } 285 S2.method(); // -> i128
286 //^^^^^^^^^^^ i128
287}
286 "#, 288 "#,
287 expect![[r#"
288 30..34 'self': &Self
289 109..113 'self': &Self
290 169..227 '{ ...i128 }': ()
291 175..177 'S1': S1
292 175..186 'S1.method()': u32
293 202..204 'S2': S2
294 202..213 'S2.method()': i128
295 "#]],
296 ); 289 );
297} 290}
298 291
299#[test] 292#[test]
300fn infer_trait_method_scoped() { 293fn infer_trait_method_scoped() {
301 // the trait implementation is intentionally incomplete -- it shouldn't matter 294 // the trait implementation is intentionally incomplete -- it shouldn't matter
302 check_infer( 295 check_types(
303 r#" 296 r#"
304 struct S; 297struct S;
305 mod foo { 298mod foo {
306 pub trait Trait1 { 299 pub trait Trait1 {
307 fn method(&self) -> u32; 300 fn method(&self) -> u32;
308 } 301 }
309 impl Trait1 for super::S {} 302 impl Trait1 for super::S {}
310 } 303}
311 mod bar { 304mod bar {
312 pub trait Trait2 { 305 pub trait Trait2 {
313 fn method(&self) -> i128; 306 fn method(&self) -> i128;
314 } 307 }
315 impl Trait2 for super::S {} 308 impl Trait2 for super::S {}
316 } 309}
317 310
318 mod foo_test { 311mod foo_test {
319 use super::S; 312 use super::S;
320 use super::foo::Trait1; 313 use super::foo::Trait1;
321 fn test() { 314 fn test() {
322 S.method(); // -> u32 315 S.method();
323 } 316 //^^^^^^^^^^ u32
324 } 317 }
318}
325 319
326 mod bar_test { 320mod bar_test {
327 use super::S; 321 use super::S;
328 use super::bar::Trait2; 322 use super::bar::Trait2;
329 fn test() { 323 fn test() {
330 S.method(); // -> i128 324 S.method();
331 } 325 //^^^^^^^^^^ i128
332 } 326 }
327}
333 "#, 328 "#,
334 expect![[r#"
335 62..66 'self': &Self
336 168..172 'self': &Self
337 299..336 '{ ... }': ()
338 309..310 'S': S
339 309..319 'S.method()': u32
340 415..453 '{ ... }': ()
341 425..426 'S': S
342 425..435 'S.method()': i128
343 "#]],
344 ); 329 );
345} 330}
346 331
347#[test] 332#[test]
348fn infer_trait_method_generic_1() { 333fn infer_trait_method_generic_1() {
349 // the trait implementation is intentionally incomplete -- it shouldn't matter 334 // the trait implementation is intentionally incomplete -- it shouldn't matter
350 check_infer( 335 check_types(
351 r#" 336 r#"
352 trait Trait<T> { 337trait Trait<T> {
353 fn method(&self) -> T; 338 fn method(&self) -> T;
354 } 339}
355 struct S; 340struct S;
356 impl Trait<u32> for S {} 341impl Trait<u32> for S {}
357 fn test() { 342fn test() {
358 S.method(); 343 S.method();
359 } 344 //^^^^^^^^^^ u32
345}
360 "#, 346 "#,
361 expect![[r#"
362 32..36 'self': &Self
363 91..110 '{ ...d(); }': ()
364 97..98 'S': S
365 97..107 'S.method()': u32
366 "#]],
367 ); 347 );
368} 348}
369 349
370#[test] 350#[test]
371fn infer_trait_method_generic_more_params() { 351fn infer_trait_method_generic_more_params() {
372 // the trait implementation is intentionally incomplete -- it shouldn't matter 352 // the trait implementation is intentionally incomplete -- it shouldn't matter
373 check_infer( 353 check_types(
374 r#" 354 r#"
375 trait Trait<T1, T2, T3> { 355trait Trait<T1, T2, T3> {
376 fn method1(&self) -> (T1, T2, T3); 356 fn method1(&self) -> (T1, T2, T3);
377 fn method2(&self) -> (T3, T2, T1); 357 fn method2(&self) -> (T3, T2, T1);
378 } 358}
379 struct S1; 359struct S1;
380 impl Trait<u8, u16, u32> for S1 {} 360impl Trait<u8, u16, u32> for S1 {}
381 struct S2; 361struct S2;
382 impl<T> Trait<i8, i16, T> for S2 {} 362impl<T> Trait<i8, i16, T> for S2 {}
383 fn test() { 363fn test() {
384 S1.method1(); // u8, u16, u32 364 S1.method1();
385 S1.method2(); // u32, u16, u8 365 //^^^^^^^^^^^^ (u8, u16, u32)
386 S2.method1(); // i8, i16, {unknown} 366 S1.method2();
387 S2.method2(); // {unknown}, i16, i8 367 //^^^^^^^^^^^^ (u32, u16, u8)
388 } 368 S2.method1();
369 //^^^^^^^^^^^^ (i8, i16, {unknown})
370 S2.method2();
371 //^^^^^^^^^^^^ ({unknown}, i16, i8)
372}
389 "#, 373 "#,
390 expect![[r#"
391 42..46 'self': &Self
392 81..85 'self': &Self
393 209..360 '{ ..., i8 }': ()
394 215..217 'S1': S1
395 215..227 'S1.method1()': (u8, u16, u32)
396 249..251 'S1': S1
397 249..261 'S1.method2()': (u32, u16, u8)
398 283..285 'S2': S2
399 283..295 'S2.method1()': (i8, i16, {unknown})
400 323..325 'S2': S2
401 323..335 'S2.method2()': ({unknown}, i16, i8)
402 "#]],
403 ); 374 );
404} 375}
405 376
406#[test] 377#[test]
407fn infer_trait_method_generic_2() { 378fn infer_trait_method_generic_2() {
408 // the trait implementation is intentionally incomplete -- it shouldn't matter 379 // the trait implementation is intentionally incomplete -- it shouldn't matter
409 check_infer( 380 check_types(
410 r#" 381 r#"
411 trait Trait<T> { 382trait Trait<T> {
412 fn method(&self) -> T; 383 fn method(&self) -> T;
413 } 384}
414 struct S<T>(T); 385struct S<T>(T);
415 impl<U> Trait<U> for S<U> {} 386impl<U> Trait<U> for S<U> {}
416 fn test() { 387fn test() {
417 S(1u32).method(); 388 S(1u32).method();
418 } 389 //^^^^^^^^^^^^^^^^ u32
390}
419 "#, 391 "#,
420 expect![[r#"
421 32..36 'self': &Self
422 101..126 '{ ...d(); }': ()
423 107..108 'S': S<u32>(u32) -> S<u32>
424 107..114 'S(1u32)': S<u32>
425 107..123 'S(1u32...thod()': u32
426 109..113 '1u32': u32
427 "#]],
428 ); 392 );
429} 393}
430 394
@@ -685,10 +649,10 @@ fn method_resolution_unify_impl_self_type() {
685 check_types( 649 check_types(
686 r#" 650 r#"
687struct S<T>; 651struct S<T>;
688impl S<u32> { fn foo(&self) -> u8 {} } 652impl S<u32> { fn foo(&self) -> u8 { 0 } }
689impl S<i32> { fn foo(&self) -> i8 {} } 653impl S<i32> { fn foo(&self) -> i8 { 0 } }
690fn test() { (S::<u32>.foo(), S::<i32>.foo()); } 654fn test() { (S::<u32>.foo(), S::<i32>.foo()); }
691 //^ (u8, i8) 655 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (u8, i8)
692"#, 656"#,
693 ); 657 );
694} 658}
@@ -702,7 +666,7 @@ struct S;
702impl S { fn foo(&self) -> i8 { 0 } } 666impl S { fn foo(&self) -> i8 { 0 } }
703impl Trait for S { fn foo(self) -> u128 { 0 } } 667impl Trait for S { fn foo(self) -> u128 { 0 } }
704fn test() { S.foo(); } 668fn test() { S.foo(); }
705 //^ u128 669 //^^^^^^^ u128
706"#, 670"#,
707 ); 671 );
708} 672}
@@ -716,7 +680,7 @@ struct S;
716impl Clone for S {} 680impl Clone for S {}
717impl Clone for &S {} 681impl Clone for &S {}
718fn test() { (S.clone(), (&S).clone(), (&&S).clone()); } 682fn test() { (S.clone(), (&S).clone(), (&&S).clone()); }
719 //^ (S, S, &S) 683 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (S, S, &S)
720"#, 684"#,
721 ); 685 );
722} 686}
@@ -730,7 +694,7 @@ struct S;
730impl S { fn foo(self) -> i8 { 0 } } 694impl S { fn foo(self) -> i8 { 0 } }
731impl Trait for &S { fn foo(self) -> u128 { 0 } } 695impl Trait for &S { fn foo(self) -> u128 { 0 } }
732fn test() { (&S).foo(); } 696fn test() { (&S).foo(); }
733 //^ u128 697 //^^^^^^^^^^ u128
734"#, 698"#,
735 ); 699 );
736} 700}
@@ -744,7 +708,7 @@ struct S;
744impl S { fn foo(self) -> i8 { 0 } } 708impl S { fn foo(self) -> i8 { 0 } }
745impl Trait for S { fn foo(self) -> u128 { 0 } } 709impl Trait for S { fn foo(self) -> u128 { 0 } }
746fn test() { S.foo(); } 710fn test() { S.foo(); }
747 //^ i8 711 //^^^^^^^ i8
748"#, 712"#,
749 ); 713 );
750} 714}
@@ -758,7 +722,7 @@ struct S;
758impl S { fn foo(&self) -> i8 { 0 } } 722impl S { fn foo(&self) -> i8 { 0 } }
759impl Trait for &S { fn foo(self) -> u128 { 0 } } 723impl Trait for &S { fn foo(self) -> u128 { 0 } }
760fn test() { S.foo(); } 724fn test() { S.foo(); }
761 //^ i8 725 //^^^^^^^ i8
762"#, 726"#,
763 ); 727 );
764} 728}
@@ -771,7 +735,7 @@ trait Trait { fn foo(self) -> u128; }
771struct S; 735struct S;
772impl Trait for S { fn foo(self) -> u128 { 0 } } 736impl Trait for S { fn foo(self) -> u128 { 0 } }
773fn test() { (&S).foo(); } 737fn test() { (&S).foo(); }
774 //^ u128 738 //^^^^^^^^^^ u128
775"#, 739"#,
776 ); 740 );
777} 741}
@@ -780,14 +744,11 @@ fn test() { (&S).foo(); }
780fn method_resolution_unsize_array() { 744fn method_resolution_unsize_array() {
781 check_types( 745 check_types(
782 r#" 746 r#"
783#[lang = "slice"] 747//- minicore: slice
784impl<T> [T] {
785 fn len(&self) -> usize { loop {} }
786}
787fn test() { 748fn test() {
788 let a = [1, 2, 3]; 749 let a = [1, 2, 3];
789 a.len(); 750 a.len();
790} //^ usize 751} //^^^^^^^ usize
791"#, 752"#,
792 ); 753 );
793} 754}
@@ -802,7 +763,7 @@ impl Clone for S {}
802 763
803fn test() { 764fn test() {
804 S.clone(); 765 S.clone();
805 //^ S 766 //^^^^^^^^^ S
806} 767}
807 768
808//- /lib.rs crate:core 769//- /lib.rs crate:core
@@ -826,7 +787,7 @@ trait Trait { fn foo(self) -> u128; }
826struct S; 787struct S;
827impl<T> Trait for T where T: UnknownTrait {} 788impl<T> Trait for T where T: UnknownTrait {}
828fn test() { (&S).foo(); } 789fn test() { (&S).foo(); }
829 //^ u128 790 //^^^^^^^^^^ u128
830"#, 791"#,
831 ); 792 );
832} 793}
@@ -844,7 +805,7 @@ trait Trait { fn foo(self) -> u128; }
844struct S; 805struct S;
845impl<T> Trait for T where T: Clone {} 806impl<T> Trait for T where T: Clone {}
846fn test() { (&S).foo(); } 807fn test() { (&S).foo(); }
847 //^ {unknown} 808 //^^^^^^^^^^ {unknown}
848"#, 809"#,
849 ); 810 );
850} 811}
@@ -859,7 +820,7 @@ trait Trait { fn foo(self) -> u128; }
859struct S; 820struct S;
860impl<T: Clone> Trait for T {} 821impl<T: Clone> Trait for T {}
861fn test() { (&S).foo(); } 822fn test() { (&S).foo(); }
862 //^ {unknown} 823 //^^^^^^^^^^ {unknown}
863"#, 824"#,
864 ); 825 );
865} 826}
@@ -874,7 +835,7 @@ struct S;
874impl Clone for S {} 835impl Clone for S {}
875impl<T> Trait for T where T: Clone {} 836impl<T> Trait for T where T: Clone {}
876fn test() { S.foo(); } 837fn test() { S.foo(); }
877 //^ u128 838 //^^^^^^^ u128
878"#, 839"#,
879 ); 840 );
880} 841}
@@ -890,7 +851,7 @@ struct S2;
890impl From<S2> for S1 {} 851impl From<S2> for S1 {}
891impl<T, U> Into<U> for T where U: From<T> {} 852impl<T, U> Into<U> for T where U: From<T> {}
892fn test() { S2.into(); } 853fn test() { S2.into(); }
893 //^ {unknown} 854 //^^^^^^^^^ {unknown}
894"#, 855"#,
895 ); 856 );
896} 857}
@@ -906,7 +867,7 @@ struct S2;
906impl From<S2> for S1 {} 867impl From<S2> for S1 {}
907impl<T, U: From<T>> Into<U> for T {} 868impl<T, U: From<T>> Into<U> for T {}
908fn test() { S2.into(); } 869fn test() { S2.into(); }
909 //^ {unknown} 870 //^^^^^^^^^ {unknown}
910"#, 871"#,
911 ); 872 );
912} 873}
@@ -936,7 +897,7 @@ fn main() {
936 let a = Wrapper::<Foo<f32>>::new(1.0); 897 let a = Wrapper::<Foo<f32>>::new(1.0);
937 let b = Wrapper::<Bar<f32>>::new(1.0); 898 let b = Wrapper::<Bar<f32>>::new(1.0);
938 (a, b); 899 (a, b);
939 //^ (Wrapper<Foo<f32>>, Wrapper<Bar<f32>>) 900 //^^^^^^ (Wrapper<Foo<f32>>, Wrapper<Bar<f32>>)
940} 901}
941"#, 902"#,
942 ); 903 );
@@ -950,7 +911,7 @@ fn method_resolution_encountering_fn_type() {
950fn foo() {} 911fn foo() {}
951trait FnOnce { fn call(self); } 912trait FnOnce { fn call(self); }
952fn test() { foo.call(); } 913fn test() { foo.call(); }
953 //^ {unknown} 914 //^^^^^^^^^^ {unknown}
954"#, 915"#,
955 ); 916 );
956} 917}
@@ -1016,7 +977,7 @@ where
1016 Wrapper<T>: a::Foo, 977 Wrapper<T>: a::Foo,
1017{ 978{
1018 t.foo(); 979 t.foo();
1019} //^ {unknown} 980} //^^^^^^^ {unknown}
1020"#, 981"#,
1021 ); 982 );
1022} 983}
@@ -1033,7 +994,7 @@ impl A<i32> {
1033 994
1034fn main() { 995fn main() {
1035 A::from(3); 996 A::from(3);
1036} //^ A<i32> 997} //^^^^^^^^^^ A<i32>
1037"#, 998"#,
1038 ); 999 );
1039} 1000}
@@ -1061,7 +1022,7 @@ trait FnX {}
1061impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {} 1022impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {}
1062 1023
1063fn test() { (S {}).method(); } 1024fn test() { (S {}).method(); }
1064 //^ () 1025 //^^^^^^^^^^^^^^^ ()
1065"#, 1026"#,
1066 ); 1027 );
1067} 1028}
@@ -1146,8 +1107,8 @@ impl<T> Slice<T> {
1146 1107
1147fn main() { 1108fn main() {
1148 let foo: Slice<u32>; 1109 let foo: Slice<u32>;
1149 (foo.into_vec()); // we don't actually support arbitrary self types, but we shouldn't crash at least 1110 foo.into_vec(); // we shouldn't crash on this at least
1150} //^ {unknown} 1111} //^^^^^^^^^^^^^^ {unknown}
1151"#, 1112"#,
1152 ); 1113 );
1153} 1114}
@@ -1168,7 +1129,7 @@ impl dyn Foo + '_ {
1168fn main() { 1129fn main() {
1169 let f = &42u32 as &dyn Foo; 1130 let f = &42u32 as &dyn Foo;
1170 f.dyn_foo(); 1131 f.dyn_foo();
1171 // ^u32 1132 // ^^^^^^^^^^^ u32
1172} 1133}
1173"#, 1134"#,
1174 ); 1135 );
@@ -1178,11 +1139,7 @@ fn main() {
1178fn autoderef_visibility_field() { 1139fn autoderef_visibility_field() {
1179 check_infer( 1140 check_infer(
1180 r#" 1141 r#"
1181#[lang = "deref"] 1142//- minicore: deref
1182pub trait Deref {
1183 type Target;
1184 fn deref(&self) -> &Self::Target;
1185}
1186mod a { 1143mod a {
1187 pub struct Foo(pub char); 1144 pub struct Foo(pub char);
1188 pub struct Bar(i32); 1145 pub struct Bar(i32);
@@ -1191,7 +1148,7 @@ mod a {
1191 Self(0) 1148 Self(0)
1192 } 1149 }
1193 } 1150 }
1194 impl super::Deref for Bar { 1151 impl core::ops::Deref for Bar {
1195 type Target = Foo; 1152 type Target = Foo;
1196 fn deref(&self) -> &Foo { 1153 fn deref(&self) -> &Foo {
1197 &Foo('z') 1154 &Foo('z')
@@ -1205,22 +1162,21 @@ mod b {
1205} 1162}
1206 "#, 1163 "#,
1207 expect![[r#" 1164 expect![[r#"
1208 67..71 'self': &Self 1165 107..138 '{ ... }': Bar
1209 200..231 '{ ... }': Bar 1166 121..125 'Self': Bar(i32) -> Bar
1210 214..218 'Self': Bar(i32) -> Bar 1167 121..128 'Self(0)': Bar
1211 214..221 'Self(0)': Bar 1168 126..127 '0': i32
1212 219..220 '0': i32 1169 226..230 'self': &Bar
1213 315..319 'self': &Bar 1170 240..273 '{ ... }': &Foo
1214 329..362 '{ ... }': &Foo 1171 254..263 '&Foo('z')': &Foo
1215 343..352 '&Foo('z')': &Foo 1172 255..258 'Foo': Foo(char) -> Foo
1216 344..347 'Foo': Foo(char) -> Foo 1173 255..263 'Foo('z')': Foo
1217 344..352 'Foo('z')': Foo 1174 259..262 ''z'': char
1218 348..351 ''z'': char 1175 303..350 '{ ... }': ()
1219 392..439 '{ ... }': () 1176 317..318 'x': char
1220 406..407 'x': char 1177 321..339 'super:...r::new': fn new() -> Bar
1221 410..428 'super:...r::new': fn new() -> Bar 1178 321..341 'super:...:new()': Bar
1222 410..430 'super:...:new()': Bar 1179 321..343 'super:...ew().0': char
1223 410..432 'super:...ew().0': char
1224 "#]], 1180 "#]],