aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-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
20 files changed, 1539 insertions, 2470 deletions
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 "#]],
1225 ) 1181 )
1226} 1182}
@@ -1230,11 +1186,7 @@ fn autoderef_visibility_method() {
1230 cov_mark::check!(autoderef_candidate_not_visible); 1186 cov_mark::check!(autoderef_candidate_not_visible);
1231 check_infer( 1187 check_infer(
1232 r#" 1188 r#"
1233#[lang = "deref"] 1189//- minicore: deref
1234pub trait Deref {
1235 type Target;
1236 fn deref(&self) -> &Self::Target;
1237}
1238mod a { 1190mod a {
1239 pub struct Foo(pub char); 1191 pub struct Foo(pub char);
1240 impl Foo { 1192 impl Foo {
@@ -1251,7 +1203,7 @@ mod a {
1251 self.0 1203 self.0
1252 } 1204 }
1253 } 1205 }
1254 impl super::Deref for Bar { 1206 impl core::ops::Deref for Bar {
1255 type Target = Foo; 1207 type Target = Foo;
1256 fn deref(&self) -> &Foo { 1208 fn deref(&self) -> &Foo {
1257 &Foo('z') 1209 &Foo('z')
@@ -1265,30 +1217,29 @@ mod b {
1265} 1217}
1266 "#, 1218 "#,
1267 expect![[r#" 1219 expect![[r#"
1268 67..71 'self': &Self 1220 75..79 'self': &Foo
1269 168..172 'self': &Foo 1221 89..119 '{ ... }': char
1270 182..212 '{ ... }': char 1222 103..107 'self': &Foo
1271 196..200 'self': &Foo 1223 103..109 'self.0': char
1272 196..202 'self.0': char 1224 195..226 '{ ... }': Bar
1273 288..319 '{ ... }': Bar 1225 209..213 'Self': Bar(i32) -> Bar
1274 302..306 'Self': Bar(i32) -> Bar 1226 209..216 'Self(0)': Bar
1275 302..309 'Self(0)': Bar 1227 214..215 '0': i32
1276 307..308 '0': i32 1228 245..249 'self': &Bar
1277 338..342 'self': &Bar 1229 258..288 '{ ... }': i32
1278 351..381 '{ ... }': i32 1230 272..276 'self': &Bar
1279 365..369 'self': &Bar 1231 272..278 'self.0': i32
1280 365..371 'self.0': i32 1232 376..380 'self': &Bar
1281 465..469 'self': &Bar 1233 390..423 '{ ... }': &Foo
1282 479..512 '{ ... }': &Foo 1234 404..413 '&Foo('z')': &Foo
1283 493..502 '&Foo('z')': &Foo 1235 405..408 'Foo': Foo(char) -> Foo
1284 494..497 'Foo': Foo(char) -> Foo 1236 405..413 'Foo('z')': Foo
1285 494..502 'Foo('z')': Foo 1237 409..412 ''z'': char
1286 498..501 ''z'': char 1238 453..506 '{ ... }': ()
1287 542..595 '{ ... }': () 1239 467..468 'x': char
1288 556..557 'x': char 1240 471..489 'super:...r::new': fn new() -> Bar
1289 560..578 'super:...r::new': fn new() -> Bar 1241 471..491 'super:...:new()': Bar
1290 560..580 'super:...:new()': Bar 1242 471..499 'super:...ango()': char
1291 560..588 'super:...ango()': char
1292 "#]], 1243 "#]],
1293 ) 1244 )
1294} 1245}
@@ -1389,11 +1340,11 @@ pub trait IntoIterator {
1389 1340
1390impl<T> IntoIterator for [T; 1] { 1341impl<T> IntoIterator for [T; 1] {
1391 type Out = T; 1342 type Out = T;
1392 fn into_iter(self) -> Self::Out {} 1343 fn into_iter(self) -> Self::Out { loop {} }
1393} 1344}
1394impl<'a, T> IntoIterator for &'a [T] { 1345impl<'a, T> IntoIterator for &'a [T] {
1395 type Out = &'a T; 1346 type Out = &'a T;
1396 fn into_iter(self) -> Self::Out {} 1347 fn into_iter(self) -> Self::Out { loop {} }
1397} 1348}
1398 "#, 1349 "#,
1399 ); 1350 );
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index aa513c56d..47aa30d2e 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -1,6 +1,6 @@
1use expect_test::expect; 1use expect_test::expect;
2 2
3use super::{check_infer, check_infer_with_mismatches, check_mismatches, check_types}; 3use super::{check, check_infer, check_infer_with_mismatches, check_types};
4 4
5#[test] 5#[test]
6fn infer_pattern() { 6fn infer_pattern() {
@@ -518,7 +518,7 @@ fn infer_generics_in_patterns() {
518 518
519#[test] 519#[test]
520fn infer_const_pattern() { 520fn infer_const_pattern() {
521 check_mismatches( 521 check(
522 r#" 522 r#"
523enum Option<T> { None } 523enum Option<T> { None }
524use Option::None; 524use Option::None;
@@ -571,48 +571,44 @@ fn main() {
571fn match_ergonomics_in_closure_params() { 571fn match_ergonomics_in_closure_params() {
572 check_infer( 572 check_infer(
573 r#" 573 r#"
574 #[lang = "fn_once"] 574//- minicore: fn
575 trait FnOnce<Args> { 575fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
576 type Output;
577 }
578
579 fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
580 576
581 fn test() { 577fn test() {
582 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics 578 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
583 foo(&(1, "a"), |(x, y)| x); 579 foo(&(1, "a"), |(x, y)| x);
584 } 580}
585 "#, 581"#,
586 expect![[r#" 582 expect![[r#"
587 93..94 't': T 583 32..33 't': T
588 99..100 'f': F 584 38..39 'f': F
589 110..121 '{ loop {} }': U 585 49..60 '{ loop {} }': U
590 112..119 'loop {}': ! 586 51..58 'loop {}': !
591 117..119 '{}': () 587 56..58 '{}': ()
592 133..232 '{ ... x); }': () 588 72..171 '{ ... x); }': ()
593 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 589 78..81 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
594 139..166 'foo(&(...y)| x)': i32 590 78..105 'foo(&(...y)| x)': i32
595 143..152 '&(1, "a")': &(i32, &str) 591 82..91 '&(1, "a")': &(i32, &str)
596 144..152 '(1, "a")': (i32, &str) 592 83..91 '(1, "a")': (i32, &str)
597 145..146 '1': i32 593 84..85 '1': i32
598 148..151 '"a"': &str 594 87..90 '"a"': &str
599 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 595 93..104 '|&(x, y)| x': |&(i32, &str)| -> i32
600 155..162 '&(x, y)': &(i32, &str) 596 94..101 '&(x, y)': &(i32, &str)
601 156..162 '(x, y)': (i32, &str) 597 95..101 '(x, y)': (i32, &str)
602 157..158 'x': i32 598 96..97 'x': i32
603 160..161 'y': &str 599 99..100 'y': &str
604 164..165 'x': i32 600 103..104 'x': i32
605 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 601 142..145 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
606 203..229 'foo(&(...y)| x)': &i32 602 142..168 'foo(&(...y)| x)': &i32
607 207..216 '&(1, "a")': &(i32, &str) 603 146..155 '&(1, "a")': &(i32, &str)
608 208..216 '(1, "a")': (i32, &str) 604 147..155 '(1, "a")': (i32, &str)
609 209..210 '1': i32 605 148..149 '1': i32
610 212..215 '"a"': &str 606 151..154 '"a"': &str
611 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 607 157..167 '|(x, y)| x': |&(i32, &str)| -> &i32
612 219..225 '(x, y)': (i32, &str) 608 158..164 '(x, y)': (i32, &str)
613 220..221 'x': &i32 609 159..160 'x': &i32
614 223..224 'y': &&str 610 162..163 'y': &&str
615 227..228 'x': &i32 611 166..167 'x': &i32
616 "#]], 612 "#]],
617 ); 613 );
618} 614}
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 1019e783b..8c5e8954c 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -1,6 +1,6 @@
1use expect_test::expect; 1use expect_test::expect;
2 2
3use super::{check_infer, check_types}; 3use super::{check_infer, check_no_mismatches, check_types};
4 4
5#[test] 5#[test]
6fn bug_484() { 6fn bug_484() {
@@ -418,55 +418,24 @@ fn issue_2705() {
418fn issue_2683_chars_impl() { 418fn issue_2683_chars_impl() {
419 check_types( 419 check_types(
420 r#" 420 r#"
421//- /main.rs crate:main deps:std 421//- minicore: iterator
422fn test() { 422pub struct Chars<'a> {}
423 let chars: std::str::Chars<'_>; 423impl<'a> Iterator for Chars<'a> {
424 (chars.next(), chars.nth(1)); 424 type Item = char;
425} //^ (Option<char>, Option<char>) 425 fn next(&mut self) -> Option<char> { loop {} }
426
427//- /std.rs crate:std
428#[prelude_import]
429use self::prelude::rust_2018::*;
430pub mod prelude {
431 pub mod rust_2018 {
432 pub use crate::iter::Iterator;
433 pub use crate::option::Option;
434 }
435} 426}
436 427
437pub mod iter { 428fn test() {
438 pub use self::traits::Iterator; 429 let chars: Chars<'_>;
439 pub mod traits { 430 (chars.next(), chars.nth(1));
440 pub use self::iterator::Iterator; 431} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (Option<char>, Option<char>)
441
442 pub mod iterator {
443 pub trait Iterator {
444 type Item;
445 fn next(&mut self) -> Option<Self::Item>;
446 fn nth(&mut self, n: usize) -> Option<Self::Item> {}
447 }
448 }
449 }
450}
451
452pub mod option {
453 pub enum Option<T> {}
454}
455
456pub mod str {
457 pub struct Chars<'a> {}
458 impl<'a> Iterator for Chars<'a> {
459 type Item = char;
460 fn next(&mut self) -> Option<char> {}
461 }
462}
463"#, 432"#,
464 ); 433 );
465} 434}
466 435
467#[test] 436#[test]
468fn issue_3642_bad_macro_stackover() { 437fn issue_3642_bad_macro_stackover() {
469 check_types( 438 check_no_mismatches(
470 r#" 439 r#"
471#[macro_export] 440#[macro_export]
472macro_rules! match_ast { 441macro_rules! match_ast {
@@ -483,7 +452,6 @@ macro_rules! match_ast {
483 452
484fn main() { 453fn main() {
485 let anchor = match_ast! { 454 let anchor = match_ast! {
486 //^ ()
487 match parent { 455 match parent {
488 as => {}, 456 as => {},
489 _ => return None 457 _ => return None
@@ -736,12 +704,8 @@ fn issue_4931() {
736fn issue_4885() { 704fn issue_4885() {
737 check_infer( 705 check_infer(
738 r#" 706 r#"
739 #[lang = "coerce_unsized"] 707 //- minicore: coerce_unsized, future
740 pub trait CoerceUnsized<T> {} 708 use core::future::Future;
741
742 trait Future {
743 type Output;
744 }
745 trait Foo<R> { 709 trait Foo<R> {
746 type Bar; 710 type Bar;
747 } 711 }
@@ -758,13 +722,13 @@ fn issue_4885() {
758 } 722 }
759 "#, 723 "#,
760 expect![[r#" 724 expect![[r#"
761 136..139 'key': &K 725 70..73 'key': &K
762 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar> 726 132..148 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
763 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> 727 138..141 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
764 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> 728 138..146 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
765 208..211 'key': &K 729 142..145 'key': &K
766 228..231 'key': &K 730 162..165 'key': &K
767 290..293 '{ }': () 731 224..227 '{ }': ()
768 "#]], 732 "#]],
769 ); 733 );
770} 734}
@@ -827,6 +791,7 @@ fn issue_4800() {
827fn issue_4966() { 791fn issue_4966() {
828 check_infer( 792 check_infer(
829 r#" 793 r#"
794 //- minicore: deref
830 pub trait IntoIterator { 795 pub trait IntoIterator {
831 type Item; 796 type Item;
832 } 797 }
@@ -837,12 +802,7 @@ fn issue_4966() {
837 802
838 struct Vec<T> {} 803 struct Vec<T> {}
839 804
840 #[lang = "deref"] 805 impl<T> core::ops::Deref for Vec<T> {
841 pub trait Deref {
842 type Target;
843 }
844
845 impl<T> Deref for Vec<T> {
846 type Target = [T]; 806 type Target = [T];
847 } 807 }
848 808
@@ -859,23 +819,23 @@ fn issue_4966() {
859 } 819 }
860 "#, 820 "#,
861 expect![[r#" 821 expect![[r#"
862 270..274 'iter': T 822 225..229 'iter': T
863 289..291 '{}': () 823 244..246 '{}': ()
864 303..447 '{ ...r(); }': () 824 258..402 '{ ...r(); }': ()
865 313..318 'inner': Map<|&f64| -> f64> 825 268..273 'inner': Map<|&f64| -> f64>
866 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> 826 276..300 'Map { ... 0.0 }': Map<|&f64| -> f64>
867 330..343 '|_: &f64| 0.0': |&f64| -> f64 827 285..298 '|_: &f64| 0.0': |&f64| -> f64
868 331..332 '_': &f64 828 286..287 '_': &f64
869 340..343 '0.0': f64 829 295..298 '0.0': f64
870 356..362 'repeat': Repeat<Map<|&f64| -> f64>> 830 311..317 'repeat': Repeat<Map<|&f64| -> f64>>
871 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> 831 320..345 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
872 383..388 'inner': Map<|&f64| -> f64> 832 338..343 'inner': Map<|&f64| -> f64>
873 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 833 356..359 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
874 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 834 362..371 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
875 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 835 362..379 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
876 417..423 'repeat': Repeat<Map<|&f64| -> f64>> 836 372..378 'repeat': Repeat<Map<|&f64| -> f64>>
877 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 837 386..389 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
878 431..444 'vec.foo_bar()': {unknown} 838 386..399 'vec.foo_bar()': {unknown}
879 "#]], 839 "#]],
880 ); 840 );
881} 841}
@@ -884,41 +844,37 @@ fn issue_4966() {
884fn issue_6628() { 844fn issue_6628() {
885 check_infer( 845 check_infer(
886 r#" 846 r#"
887 #[lang = "fn_once"] 847//- minicore: fn
888 pub trait FnOnce<Args> { 848struct S<T>();
889 type Output; 849impl<T> S<T> {
890 } 850 fn f(&self, _t: T) {}
891 851 fn g<F: FnOnce(&T)>(&self, _f: F) {}
892 struct S<T>(); 852}
893 impl<T> S<T> { 853fn main() {
894 fn f(&self, _t: T) {} 854 let s = S();
895 fn g<F: FnOnce(&T)>(&self, _f: F) {} 855 s.g(|_x| {});
896 } 856 s.f(10);
897 fn main() { 857}
898 let s = S(); 858"#,
899 s.g(|_x| {});
900 s.f(10);
901 }
902 "#,
903 expect![[r#" 859 expect![[r#"
904 105..109 'self': &S<T> 860 40..44 'self': &S<T>
905 111..113 '_t': T 861 46..48 '_t': T
906 118..120 '{}': () 862 53..55 '{}': ()
907 146..150 'self': &S<T> 863 81..85 'self': &S<T>
908 152..154 '_f': F 864 87..89 '_f': F
909 159..161 '{}': () 865 94..96 '{}': ()
910 174..225 '{ ...10); }': () 866 109..160 '{ ...10); }': ()
911 184..185 's': S<i32> 867 119..120 's': S<i32>
912 188..189 'S': S<i32>() -> S<i32> 868 123..124 'S': S<i32>() -> S<i32>
913 188..191 'S()': S<i32> 869 123..126 'S()': S<i32>
914 197..198 's': S<i32> 870 132..133 's': S<i32>
915 197..209 's.g(|_x| {})': () 871 132..144 's.g(|_x| {})': ()
916 201..208 '|_x| {}': |&i32| -> () 872 136..143 '|_x| {}': |&i32| -> ()
917 202..204 '_x': &i32 873 137..139 '_x': &i32
918 206..208 '{}': () 874 141..143 '{}': ()
919 215..216 's': S<i32> 875 150..151 's': S<i32>
920 215..222 's.f(10)': () 876 150..157 's.f(10)': ()
921 219..221 '10': i32 877 154..156 '10': i32
922 "#]], 878 "#]],
923 ); 879 );
924} 880}
@@ -927,35 +883,33 @@ fn issue_6628() {
927fn issue_6852() { 883fn issue_6852() {
928 check_infer( 884 check_infer(
929 r#" 885 r#"
930 #[lang = "deref"] 886//- minicore: deref
931 pub trait Deref { 887use core::ops::Deref;
932 type Target;
933 }
934 888
935 struct BufWriter {} 889struct BufWriter {}
936 890
937 struct Mutex<T> {} 891struct Mutex<T> {}
938 struct MutexGuard<'a, T> {} 892struct MutexGuard<'a, T> {}
939 impl<T> Mutex<T> { 893impl<T> Mutex<T> {
940 fn lock(&self) -> MutexGuard<'_, T> {} 894 fn lock(&self) -> MutexGuard<'_, T> {}
941 } 895}
942 impl<'a, T: 'a> Deref for MutexGuard<'a, T> { 896impl<'a, T: 'a> Deref for MutexGuard<'a, T> {
943 type Target = T; 897 type Target = T;
944 } 898}
945 fn flush(&self) { 899fn flush(&self) {
946 let w: &Mutex<BufWriter>; 900 let w: &Mutex<BufWriter>;
947 *(w.lock()); 901 *(w.lock());
948 } 902}
949 "#, 903"#,
950 expect![[r#" 904 expect![[r#"
951 156..160 'self': &Mutex<T> 905 123..127 'self': &Mutex<T>
952 183..185 '{}': () 906 150..152 '{}': ()
953 267..271 'self': &{unknown} 907 234..238 'self': &{unknown}
954 273..323 '{ ...()); }': () 908 240..290 '{ ...()); }': ()
955 283..284 'w': &Mutex<BufWriter> 909 250..251 'w': &Mutex<BufWriter>
956 309..320 '*(w.lock())': BufWriter 910 276..287 '*(w.lock())': BufWriter
957 311..312 'w': &Mutex<BufWriter> 911 278..279 'w': &Mutex<BufWriter>
958 311..319 'w.lock()': MutexGuard<BufWriter> 912 278..286 'w.lock()': MutexGuard<BufWriter>
959 "#]], 913 "#]],
960 ); 914 );
961} 915}
@@ -977,37 +931,33 @@ fn param_overrides_fn() {
977fn lifetime_from_chalk_during_deref() { 931fn lifetime_from_chalk_during_deref() {
978 check_types( 932 check_types(
979 r#" 933 r#"
980 #[lang = "deref"] 934//- minicore: deref
981 pub trait Deref { 935struct Box<T: ?Sized> {}
982 type Target; 936impl<T> core::ops::Deref for Box<T> {
983 } 937 type Target = T;
984
985 struct Box<T: ?Sized> {}
986 impl<T> Deref for Box<T> {
987 type Target = T;
988 938
989 fn deref(&self) -> &Self::Target { 939 fn deref(&self) -> &Self::Target {
990 loop {} 940 loop {}
991 } 941 }
992 } 942}
993 943
994 trait Iterator { 944trait Iterator {
995 type Item; 945 type Item;
996 } 946}
997 947
998 pub struct Iter<'a, T: 'a> { 948pub struct Iter<'a, T: 'a> {
999 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>, 949 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>,
1000 } 950}
1001 951
1002 trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> { 952trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> {
1003 fn clone_box(&self); 953 fn clone_box(&self);
1004 } 954}
1005 955
1006 fn clone_iter<T>(s: Iter<T>) { 956fn clone_iter<T>(s: Iter<T>) {
1007 s.inner.clone_box(); 957 s.inner.clone_box();
1008 //^^^^^^^^^^^^^^^^^^^ () 958 //^^^^^^^^^^^^^^^^^^^ ()
1009 } 959}
1010 "#, 960"#,
1011 ) 961 )
1012} 962}
1013 963
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 3418ed21e..b4bcc6d95 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -60,7 +60,7 @@ enum Nat { Succ(Self), Demo(Nat), Zero }
60fn test() { 60fn test() {
61 let foo: Nat = Nat::Zero; 61 let foo: Nat = Nat::Zero;
62 if let Nat::Succ(x) = foo { 62 if let Nat::Succ(x) = foo {
63 x 63 x;
64 } //^ Nat 64 } //^ Nat
65} 65}
66"#, 66"#,
@@ -113,7 +113,7 @@ fn type_alias_in_struct_lit() {
113fn infer_ranges() { 113fn infer_ranges() {
114 check_types( 114 check_types(
115 r#" 115 r#"
116//- /main.rs crate:main deps:core 116//- minicore: range
117fn test() { 117fn test() {
118 let a = ..; 118 let a = ..;
119 let b = 1..; 119 let b = 1..;
@@ -125,32 +125,6 @@ fn test() {
125 let t = (a, b, c, d, e, f); 125 let t = (a, b, c, d, e, f);
126 t; 126 t;
127} //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>) 127} //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)
128
129//- /core.rs crate:core
130#[prelude_import] use prelude::*;
131mod prelude {}
132
133pub mod ops {
134 pub struct Range<Idx> {
135 pub start: Idx,
136 pub end: Idx,
137 }
138 pub struct RangeFrom<Idx> {
139 pub start: Idx,
140 }
141 struct RangeFull;
142 pub struct RangeInclusive<Idx> {
143 start: Idx,
144 end: Idx,
145 is_empty: u8,
146 }
147 pub struct RangeTo<Idx> {
148 pub end: Idx,
149 }
150 pub struct RangeToInclusive<Idx> {
151 pub end: Idx,
152 }
153}
154"#, 128"#,
155 ); 129 );
156} 130}
@@ -164,7 +138,7 @@ enum Option<T> { Some(T), None }
164fn test() { 138fn test() {
165 let foo: Option<f32> = None; 139 let foo: Option<f32> = None;
166 while let Option::Some(x) = foo { 140 while let Option::Some(x) = foo {
167 x 141 x;
168 } //^ f32 142 } //^ f32
169} 143}
170"#, 144"#,
@@ -175,16 +149,17 @@ fn test() {
175fn infer_basics() { 149fn infer_basics() {
176 check_infer( 150 check_infer(
177 r#" 151 r#"
178 fn test(a: u32, b: isize, c: !, d: &str) { 152fn test(a: u32, b: isize, c: !, d: &str) {
179 a; 153 a;
180 b; 154 b;
181 c; 155 c;
182 d; 156 d;
183 1usize; 157 1usize;
184 1isize; 158 1isize;
185 "test"; 159 "test";
186 1.0f32; 160 1.0f32;
187 }"#, 161}
162"#,
188 expect![[r#" 163 expect![[r#"
189 8..9 'a': u32 164 8..9 'a': u32
190 16..17 'b': isize 165 16..17 'b': isize
@@ -207,15 +182,15 @@ fn infer_basics() {
207fn infer_let() { 182fn infer_let() {
208 check_infer( 183 check_infer(
209 r#" 184 r#"
210 fn test() { 185fn test() {
211 let a = 1isize; 186 let a = 1isize;
212 let b: usize = 1; 187 let b: usize = 1;
213 let c = b; 188 let c = b;
214 let d: u32; 189 let d: u32;
215 let e; 190 let e;
216 let f: i32 = e; 191 let f: i32 = e;
217 } 192}
218 "#, 193"#,
219 expect![[r#" 194 expect![[r#"
220 10..117 '{ ...= e; }': () 195 10..117 '{ ...= e; }': ()
221 20..21 'a': isize 196 20..21 'a': isize
@@ -236,17 +211,17 @@ fn infer_let() {
236fn infer_paths() { 211fn infer_paths() {
237 check_infer( 212 check_infer(
238 r#" 213 r#"
239 fn a() -> u32 { 1 } 214fn a() -> u32 { 1 }
240 215
241 mod b { 216mod b {
242 fn c() -> u32 { 1 } 217 fn c() -> u32 { 1 }
243 } 218}
244 219
245 fn test() { 220fn test() {
246 a(); 221 a();
247 b::c(); 222 b::c();
248 } 223}
249 "#, 224"#,
250 expect![[r#" 225 expect![[r#"
251 14..19 '{ 1 }': u32 226 14..19 '{ 1 }': u32
252 16..17 '1': u32 227 16..17 '1': u32
@@ -265,17 +240,17 @@ fn infer_paths() {
265fn infer_path_type() { 240fn infer_path_type() {
266 check_infer( 241 check_infer(
267 r#" 242 r#"
268 struct S; 243struct S;
269 244
270 impl S { 245impl S {
271 fn foo() -> i32 { 1 } 246 fn foo() -> i32 { 1 }
272 } 247}
273 248
274 fn test() { 249fn test() {
275 S::foo(); 250 S::foo();
276 <S>::foo(); 251 <S>::foo();
277 } 252}
278 "#, 253"#,
279 expect![[r#" 254 expect![[r#"
280 40..45 '{ 1 }': i32 255 40..45 '{ 1 }': i32
281 42..43 '1': i32 256 42..43 '1': i32
@@ -292,21 +267,21 @@ fn infer_path_type() {
292fn infer_struct() { 267fn infer_struct() {
293 check_infer( 268 check_infer(
294 r#" 269 r#"
295 struct A { 270struct A {
296 b: B, 271 b: B,
297 c: C, 272 c: C,
298 } 273}
299 struct B; 274struct B;
300 struct C(usize); 275struct C(usize);
301 276
302 fn test() { 277fn test() {
303 let c = C(1); 278 let c = C(1);
304 B; 279 B;
305 let a: A = A { b: B, c: C(1) }; 280 let a: A = A { b: B, c: C(1) };
306 a.b; 281 a.b;
307 a.c; 282 a.c;
308 } 283}
309 "#, 284"#,
310 expect![[r#" 285 expect![[r#"
311 71..153 '{ ...a.c; }': () 286 71..153 '{ ...a.c; }': ()
312 81..82 'c': C 287 81..82 'c': C
@@ -332,14 +307,15 @@ fn infer_struct() {
332fn infer_enum() { 307fn infer_enum() {
333 check_infer( 308 check_infer(
334 r#" 309 r#"
335 enum E { 310enum E {
336 V1 { field: u32 }, 311 V1 { field: u32 },
337 V2 312 V2
338 } 313}
339 fn test() { 314fn test() {
340 E::V1 { field: 1 }; 315 E::V1 { field: 1 };
341 E::V2; 316 E::V2;
342 }"#, 317}
318"#,
343 expect![[r#" 319 expect![[r#"
344 51..89 '{ ...:V2; }': () 320 51..89 '{ ...:V2; }': ()
345 57..75 'E::V1 ...d: 1 }': E 321 57..75 'E::V1 ...d: 1 }': E
@@ -353,23 +329,23 @@ fn infer_enum() {
353fn infer_union() { 329fn infer_union() {
354 check_infer( 330 check_infer(
355 r#" 331 r#"
356 union MyUnion { 332union MyUnion {
357 foo: u32, 333 foo: u32,
358 bar: f32, 334 bar: f32,
359 } 335}
360 336
361 fn test() { 337fn test() {
362 let u = MyUnion { foo: 0 }; 338 let u = MyUnion { foo: 0 };
363 unsafe { baz(u); } 339 unsafe { baz(u); }
364 let u = MyUnion { bar: 0.0 }; 340 let u = MyUnion { bar: 0.0 };
365 unsafe { baz(u); } 341 unsafe { baz(u); }
366 } 342}
367 343
368 unsafe fn baz(u: MyUnion) { 344unsafe fn baz(u: MyUnion) {
369 let inner = u.foo; 345 let inner = u.foo;
370 let inner = u.bar; 346 let inner = u.bar;
371 } 347}
372 "#, 348"#,
373 expect![[r#" 349 expect![[r#"
374 57..172 '{ ...); } }': () 350 57..172 '{ ...); } }': ()
375 67..68 'u': MyUnion 351 67..68 'u': MyUnion
@@ -404,19 +380,19 @@ fn infer_union() {
404fn infer_refs() { 380fn infer_refs() {
405 check_infer( 381 check_infer(
406 r#" 382 r#"
407 fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { 383fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
408 a; 384 a;
409 *a; 385 *a;
410 &a; 386 &a;
411 &mut a; 387 &mut a;
412 b; 388 b;
413 *b; 389 *b;
414 &b; 390 &b;
415 c; 391 c;
416 *c; 392 *c;
417 d; 393 d;
418 *d; 394 *d;
419 } 395}
420 "#, 396 "#,
421 expect![[r#" 397 expect![[r#"
422 8..9 'a': &u32 398 8..9 'a': &u32
@@ -450,11 +426,11 @@ fn infer_refs() {
450fn infer_raw_ref() { 426fn infer_raw_ref() {
451 check_infer( 427 check_infer(
452 r#" 428 r#"
453 fn test(a: i32) { 429fn test(a: i32) {
454 &raw mut a; 430 &raw mut a;
455 &raw const a; 431 &raw const a;
456 } 432}
457 "#, 433"#,
458 expect![[r#" 434 expect![[r#"
459 8..9 'a': i32 435 8..9 'a': i32
460 16..53 '{ ...t a; }': () 436 16..53 '{ ...t a; }': ()
@@ -524,26 +500,26 @@ h";
524fn infer_unary_op() { 500fn infer_unary_op() {
525 check_infer( 501 check_infer(
526 r#" 502 r#"
527 enum SomeType {} 503enum SomeType {}
528 504
529 fn test(x: SomeType) { 505fn test(x: SomeType) {
530 let b = false; 506 let b = false;
531 let c = !b; 507 let c = !b;
532 let a = 100; 508 let a = 100;
533 let d: i128 = -a; 509 let d: i128 = -a;
534 let e = -100; 510 let e = -100;
535 let f = !!!true; 511 let f = !!!true;
536 let g = !42; 512 let g = !42;
537 let h = !10u32; 513 let h = !10u32;
538 let j = !a; 514 let j = !a;
539 -3.14; 515 -3.14;