From 811d25b7237cfb74a312369a7820bf6fbb81483e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 16 May 2020 18:32:15 +0200 Subject: Allow calling dyn trait super trait methods without the super trait in scope This also removes some vestiges of the old impl trait support which I think aren't currently in use. --- crates/ra_hir_ty/src/lib.rs | 14 +++++------ crates/ra_hir_ty/src/method_resolution.rs | 10 +++----- crates/ra_hir_ty/src/tests/method_resolution.rs | 31 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 15 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index ccc4348f4..daea02f88 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -808,15 +808,13 @@ impl Ty { } } - /// If this is an `impl Trait` or `dyn Trait`, returns that trait. - pub fn inherent_trait(&self) -> Option { + /// If this is a `dyn Trait`, returns that trait. + pub fn dyn_trait(&self) -> Option { match self { - Ty::Dyn(predicates) | Ty::Opaque(predicates) => { - predicates.iter().find_map(|pred| match pred { - GenericPredicate::Implemented(tr) => Some(tr.trait_), - _ => None, - }) - } + Ty::Dyn(predicates) => predicates.iter().find_map(|pred| match pred { + GenericPredicate::Implemented(tr) => Some(tr.trait_), + _ => None, + }), _ => None, } } diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 657284fd0..0851e16a8 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -408,8 +408,9 @@ fn iterate_trait_method_candidates( receiver_ty: Option<&Canonical>, mut callback: impl FnMut(&Ty, AssocItemId) -> Option, ) -> Option { - // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope - let inherent_trait = self_ty.value.inherent_trait().into_iter(); + // if ty is `dyn Trait`, the trait doesn't need to be in scope + let inherent_trait = + self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); let env_traits = if let Ty::Placeholder(_) = self_ty.value { // if we have `T: Trait` in the param env, the trait doesn't need to be in scope env.trait_predicates_for_self_ty(&self_ty.value) @@ -601,11 +602,6 @@ pub fn implements_trait( krate: CrateId, trait_: TraitId, ) -> bool { - if ty.value.inherent_trait() == Some(trait_) { - // FIXME this is a bit of a hack, since Chalk should say the same thing - // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet - return true; - } let goal = generic_implements_goal(db, env, trait_, ty.clone()); let solution = db.trait_solve(krate, goal); diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 67f964ab5..9c2c9e1d2 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs @@ -1096,3 +1096,34 @@ fn test() { (S {}).method()<|>; } ); assert_eq!(t, "()"); } + +#[test] +fn dyn_trait_super_trait_not_in_scope() { + assert_snapshot!( + infer(r#" +mod m { + pub trait SuperTrait { + fn foo(&self) -> u32 { 0 } + } +} +trait Trait: m::SuperTrait {} + +struct S; +impl m::SuperTrait for S {} +impl Trait for S {} + +fn test(d: &dyn Trait) { + d.foo(); +} +"#), + @r###" + 52..56 'self': &Self + 65..70 '{ 0 }': u32 + 67..68 '0': u32 + 177..178 'd': &dyn Trait + 192..208 '{ ...o(); }': () + 198..199 'd': &dyn Trait + 198..205 'd.foo()': u32 + "### + ); +} -- cgit v1.2.3 From 12a3bf3c31d4c9a6d9ee110db174604f688ca0f0 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 17 May 2020 23:37:30 +0800 Subject: Create LowerCtx on the fly --- crates/ra_hir_ty/src/tests/regression.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index 115ad8328..c2168222e 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs @@ -563,6 +563,37 @@ fn main() { ); } +#[test] +fn issue_4465_dollar_crate_at_type() { + assert_snapshot!( + infer(r#" +pub struct Foo {} +pub fn anything() -> T { + loop {} +} +macro_rules! foo { + () => {{ + let r: $crate::Foo = anything(); + r + }}; +} +fn main() { + let _a = foo!(); +} +"#), @r###" + 45..60 '{ loop {} }': T + 51..58 'loop {}': ! + 56..58 '{}': () + !0..31 '{letr:...g();r}': Foo + !4..5 'r': Foo + !18..26 'anything': fn anything() -> Foo + !18..28 'anything()': Foo + !29..30 'r': Foo + 164..188 '{ ...!(); }': () + 174..176 '_a': Foo +"###); +} + #[test] fn issue_4053_diesel_where_clauses() { assert_snapshot!( -- cgit v1.2.3 From 68db49c8534fa99768c7f600455ea76176f61994 Mon Sep 17 00:00:00 2001 From: Hrvoje Ban Date: Mon, 18 May 2020 08:07:31 +0200 Subject: Add more tests for Fn traits --- crates/ra_hir_ty/src/tests/traits.rs | 132 +++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 9d32cbc7a..c49aacf98 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -1616,6 +1616,138 @@ fn test u128>(f: F) { ); } +#[test] +fn fn_ptr_and_item() { + assert_snapshot!( + infer(r#" +#[lang="fn_once"] +trait FnOnce { + type Output; + + fn call_once(self, args: Args) -> Self::Output; +} + +trait Foo { + fn foo(&self) -> T; +} + +struct Bar(T); + +impl R> Foo<(A1, R)> for Bar { + fn foo(&self) -> (A1, R) {} +} + +enum Opt { None, Some(T) } +impl Opt { + fn map U>(self, f: F) -> Opt {} +} + +fn test() { + let bar: Bar u32>; + bar.foo(); + + let opt: Opt; + let f: fn(u8) -> u32; + opt.map(f); +} +"#), + @r###" +75..79 'self': Self +81..85 'args': Args +140..144 'self': &Self +244..248 'self': &Bar +261..263 '{}': () +347..351 'self': Opt +353..354 'f': F +369..371 '{}': () +385..501 '{ ...(f); }': () +395..398 'bar': Bar u32> +424..427 'bar': Bar u32> +424..433 'bar.foo()': {unknown} +444..447 'opt': Opt +466..467 'f': fn(u8) -> u32 +488..491 'opt': Opt +488..498 'opt.map(f)': Opt u32, (u8,)>> +496..497 'f': fn(u8) -> u32 +"### + ); +} + +#[test] +fn fn_trait_deref_with_ty_default() { + assert_snapshot!( + infer(r#" +#[lang = "deref"] +trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +#[lang="fn_once"] +trait FnOnce { + type Output; + + fn call_once(self, args: Args) -> Self::Output; +} + +struct Foo; + +impl Foo { + fn foo(&self) -> usize {} +} + +struct Lazy T>(F); + +impl Lazy { + pub fn new(f: F) -> Lazy {} +} + +impl T> Deref for Lazy { + type Target = T; +} + +fn test() { + let lazy1: Lazy = Lazy::new(|| Foo); + let r1 = lazy1.foo(); + + fn make_foo_fn() -> Foo {} + let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; + let lazy2: Lazy = Lazy::new(make_foo_fn_ptr); + let r2 = lazy2.foo(); +} +"#), + @r###" +65..69 'self': &Self +166..170 'self': Self +172..176 'args': Args +240..244 'self': &Foo +255..257 '{}': () +335..336 'f': F +355..357 '{}': () +444..690 '{ ...o(); }': () +454..459 'lazy1': Lazy T> +476..485 'Lazy::new': fn new T>(fn() -> T) -> Lazy T> +476..493 'Lazy::...| Foo)': Lazy T> +486..492 '|| Foo': || -> T +489..492 'Foo': Foo +503..505 'r1': {unknown} +508..513 'lazy1': Lazy T> +508..519 'lazy1.foo()': {unknown} +561..576 'make_foo_fn_ptr': fn() -> Foo +592..603 'make_foo_fn': fn make_foo_fn() -> Foo +613..618 'lazy2': Lazy T> +635..644 'Lazy::new': fn new T>(fn() -> T) -> Lazy T> +635..661 'Lazy::...n_ptr)': Lazy T> +645..660 'make_foo_fn_ptr': fn() -> Foo +671..673 'r2': {unknown} +676..681 'lazy2': Lazy T> +676..687 'lazy2.foo()': {unknown} +550..552 '{}': () +"### + ); +} + #[test] fn closure_1() { assert_snapshot!( -- cgit v1.2.3 From 0fe876925e59aad4765b415d9caaf262a6d43c4c Mon Sep 17 00:00:00 2001 From: Roland Ruckerbauer Date: Mon, 18 May 2020 23:39:10 +0200 Subject: Infer return type of loops with value breaks. --- crates/ra_hir_ty/src/infer.rs | 1 + crates/ra_hir_ty/src/infer/expr.rs | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 2876cb141..957d6e0b5 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs @@ -218,6 +218,7 @@ struct InferenceContext<'a> { #[derive(Clone, Debug)] struct BreakableContext { pub may_break: bool, + pub break_ty: Ty, } impl<'a> InferenceContext<'a> { diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 0b67d216a..c7aa67fbe 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -93,7 +93,7 @@ impl<'a> InferenceContext<'a> { Ty::Unknown } Expr::Loop { body } => { - self.breakables.push(BreakableContext { may_break: false }); + self.breakables.push(BreakableContext { may_break: false, break_ty: Ty::Unknown }); self.infer_expr(*body, &Expectation::has_type(Ty::unit())); let ctxt = self.breakables.pop().expect("breakable stack broken"); @@ -102,13 +102,13 @@ impl<'a> InferenceContext<'a> { } // FIXME handle break with value if ctxt.may_break { - Ty::unit() + ctxt.break_ty } else { Ty::simple(TypeCtor::Never) } } Expr::While { condition, body } => { - self.breakables.push(BreakableContext { may_break: false }); + self.breakables.push(BreakableContext { may_break: false, break_ty: Ty::Unknown }); // while let is desugared to a match loop, so this is always simple while self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); self.infer_expr(*body, &Expectation::has_type(Ty::unit())); @@ -120,7 +120,7 @@ impl<'a> InferenceContext<'a> { Expr::For { iterable, body, pat } => { let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); - self.breakables.push(BreakableContext { may_break: false }); + self.breakables.push(BreakableContext { may_break: false, break_ty: Ty::Unknown }); let pat_ty = self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item()); @@ -229,12 +229,21 @@ impl<'a> InferenceContext<'a> { } Expr::Continue => Ty::simple(TypeCtor::Never), Expr::Break { expr } => { + let mut has_val_ty = None; + if let Some(expr) = expr { - // FIXME handle break with value - self.infer_expr(*expr, &Expectation::none()); + has_val_ty = Some(self.infer_expr(*expr, &Expectation::none())); } + if let Some(ctxt) = self.breakables.last_mut() { ctxt.may_break = true; + if let Some(val_ty) = has_val_ty { + if ctxt.break_ty == Ty::Unknown { + ctxt.break_ty = val_ty; + } else if ctxt.break_ty != val_ty { + // TODO: Unify partially matching type information (Option<{unknown}> + Option => Option) + } + } } else { self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop { expr: tgt_expr, -- cgit v1.2.3 From 6eaa669da0c7b3730a309db5e320126653b88997 Mon Sep 17 00:00:00 2001 From: Roland Ruckerbauer Date: Tue, 19 May 2020 21:03:59 +0200 Subject: loop return value inference: coerce_merge branches --- crates/ra_hir_ty/src/infer/expr.rs | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index c7aa67fbe..83702ada0 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -93,14 +93,17 @@ impl<'a> InferenceContext<'a> { Ty::Unknown } Expr::Loop { body } => { - self.breakables.push(BreakableContext { may_break: false, break_ty: Ty::Unknown }); + self.breakables.push(BreakableContext { + may_break: false, + break_ty: self.table.new_type_var(), + }); self.infer_expr(*body, &Expectation::has_type(Ty::unit())); let ctxt = self.breakables.pop().expect("breakable stack broken"); if ctxt.may_break { self.diverges = Diverges::Maybe; } - // FIXME handle break with value + if ctxt.may_break { ctxt.break_ty } else { @@ -229,26 +232,31 @@ impl<'a> InferenceContext<'a> { } Expr::Continue => Ty::simple(TypeCtor::Never), Expr::Break { expr } => { - let mut has_val_ty = None; + let val_ty = if let Some(expr) = expr { + self.infer_expr(*expr, &Expectation::none()) + } else { + Ty::unit() + }; - if let Some(expr) = expr { - has_val_ty = Some(self.infer_expr(*expr, &Expectation::none())); - } + let mut has_brkctx = false; - if let Some(ctxt) = self.breakables.last_mut() { - ctxt.may_break = true; - if let Some(val_ty) = has_val_ty { - if ctxt.break_ty == Ty::Unknown { - ctxt.break_ty = val_ty; - } else if ctxt.break_ty != val_ty { - // TODO: Unify partially matching type information (Option<{unknown}> + Option => Option) - } - } + if self.breakables.last().is_some() { + has_brkctx = true; } else { self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop { expr: tgt_expr, }); } + + if has_brkctx { + let last_ty = self.breakables.last().expect("This is a bug").break_ty.clone(); + let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); + + let ctxt = self.breakables.last_mut().expect("This is a bug"); + ctxt.may_break = true; + ctxt.break_ty = merged_type; + } + Ty::simple(TypeCtor::Never) } Expr::Return { expr } => { -- cgit v1.2.3 From 6e36ad3d910ebec5af5f4f208b0f98c613687c41 Mon Sep 17 00:00:00 2001 From: Roland Ruckerbauer Date: Tue, 19 May 2020 21:18:43 +0200 Subject: Move false negative expr_diverges_missing_arm() to working tests --- crates/ra_hir_ty/src/_match.rs | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/_match.rs b/crates/ra_hir_ty/src/_match.rs index 149f65042..3e6e1e333 100644 --- a/crates/ra_hir_ty/src/_match.rs +++ b/crates/ra_hir_ty/src/_match.rs @@ -1946,6 +1946,23 @@ mod tests { check_no_diagnostic(content); } + + #[test] + fn expr_diverges_missing_arm() { + let content = r" + enum Either { + A, + B, + } + fn test_fn() { + match loop {} { + Either::A => (), + } + } + "; + + check_no_diagnostic(content); + } } #[cfg(test)] @@ -1997,26 +2014,6 @@ mod false_negatives { check_no_diagnostic(content); } - #[test] - fn expr_diverges_missing_arm() { - let content = r" - enum Either { - A, - B, - } - fn test_fn() { - match loop {} { - Either::A => (), - } - } - "; - - // This is a false negative. - // Even though the match expression diverges, rustc fails - // to compile here since `Either::B` is missing. - check_no_diagnostic(content); - } - #[test] fn expr_loop_missing_arm() { let content = r" @@ -2035,7 +2032,7 @@ mod false_negatives { // We currently infer the type of `loop { break Foo::A }` to `!`, which // causes us to skip the diagnostic since `Either::A` doesn't type check // with `!`. - check_no_diagnostic(content); + check_diagnostic(content); } #[test] -- cgit v1.2.3 From da09f967469127576d9a87a7c143f754777a4f6b Mon Sep 17 00:00:00 2001 From: Roland Ruckerbauer Date: Tue, 19 May 2020 21:49:45 +0200 Subject: loop return value inference: add tests --- crates/ra_hir_ty/src/tests/simple.rs | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index 72122c070..fd2208af2 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -1860,3 +1860,66 @@ fn test() { "### ); } + +#[test] +fn infer_loop_break_with_val() { + assert_snapshot!( + infer(r#" +enum Option { Some(T), None } +use Option::*; + +fn test() { + let x = loop { + if false { + break None; + } + + break Some(true); + }; +} +"#), + @r###" + 60..169 '{ ... }; }': () + 70..71 'x': Option + 74..166 'loop {... }': Option + 79..166 '{ ... }': () + 89..133 'if fal... }': () + 92..97 'false': bool + 98..133 '{ ... }': () + 112..122 'break None': ! + 118..122 'None': Option + 143..159 'break ...(true)': ! + 149..153 'Some': Some(bool) -> Option + 149..159 'Some(true)': Option + 154..158 'true': bool + "### + ); +} + +#[test] +fn infer_loop_break_without_val() { + assert_snapshot!( + infer(r#" +enum Option { Some(T), None } +use Option::*; + +fn test() { + let x = loop { + if false { + break; + } + }; +} +"#), + @r###" + 60..137 '{ ... }; }': () + 70..71 'x': () + 74..134 'loop {... }': () + 79..134 '{ ... }': () + 89..128 'if fal... }': () + 92..97 'false': bool + 98..128 '{ ... }': () + 112..117 'break': ! + "### + ); +} -- cgit v1.2.3 From 45021cae551826727c32c7499c68ca48d046890f Mon Sep 17 00:00:00 2001 From: Roland Ruckerbauer Date: Tue, 19 May 2020 22:52:15 +0200 Subject: Apply suggestion of @flodiebold: Get rid of multiple unwraps --- crates/ra_hir_ty/src/infer/expr.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 83702ada0..b28724f0e 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -238,25 +238,23 @@ impl<'a> InferenceContext<'a> { Ty::unit() }; - let mut has_brkctx = false; + let last_ty = if let Some(ctxt) = self.breakables.last() { + ctxt.break_ty.clone() + } else { + Ty::Unknown + }; - if self.breakables.last().is_some() { - has_brkctx = true; + let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); + + if let Some(ctxt) = self.breakables.last_mut() { + ctxt.break_ty = merged_type; + ctxt.may_break = true; } else { self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop { expr: tgt_expr, }); } - if has_brkctx { - let last_ty = self.breakables.last().expect("This is a bug").break_ty.clone(); - let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); - - let ctxt = self.breakables.last_mut().expect("This is a bug"); - ctxt.may_break = true; - ctxt.break_ty = merged_type; - } - Ty::simple(TypeCtor::Never) } Expr::Return { expr } => { -- cgit v1.2.3 From ecac5d7de2192873c24b7b06d4964d188d8abe6a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 12:59:20 +0200 Subject: Switch to new magic marks --- crates/ra_hir_ty/src/infer/coerce.rs | 6 +++--- crates/ra_hir_ty/src/infer/pat.rs | 4 ++-- crates/ra_hir_ty/src/infer/unify.rs | 8 ++++---- crates/ra_hir_ty/src/lib.rs | 1 - crates/ra_hir_ty/src/lower.rs | 2 +- crates/ra_hir_ty/src/marks.rs | 12 ------------ crates/ra_hir_ty/src/method_resolution.rs | 2 +- crates/ra_hir_ty/src/tests/coercion.rs | 6 +++--- crates/ra_hir_ty/src/tests/method_resolution.rs | 2 +- crates/ra_hir_ty/src/tests/patterns.rs | 4 ++-- crates/ra_hir_ty/src/tests/regression.rs | 15 +++++++-------- crates/ra_hir_ty/src/tests/traits.rs | 8 ++++---- 12 files changed, 28 insertions(+), 42 deletions(-) delete mode 100644 crates/ra_hir_ty/src/marks.rs (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 173ec59ed..2ee9adb16 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs @@ -5,7 +5,7 @@ //! See: https://doc.rust-lang.org/nomicon/coercions.html use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; -use test_utils::tested_by; +use test_utils::mark; use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; @@ -34,7 +34,7 @@ impl<'a> InferenceContext<'a> { ty1.clone() } else { if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { - tested_by!(coerce_fn_reification); + mark::hit!(coerce_fn_reification); // Special case: two function types. Try to coerce both to // pointers to have a chance at getting a match. See // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 @@ -44,7 +44,7 @@ impl<'a> InferenceContext<'a> { let ptr_ty2 = Ty::fn_ptr(sig2); self.coerce_merge_branch(&ptr_ty1, &ptr_ty2) } else { - tested_by!(coerce_merge_fail_fallback); + mark::hit!(coerce_merge_fail_fallback); // For incompatible types, we use the latter one as result // to be better recovery for `if` without `else`. ty2.clone() diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index 54ec870df..4006f595d 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs @@ -10,7 +10,7 @@ use hir_def::{ FieldId, }; use hir_expand::name::Name; -use test_utils::tested_by; +use test_utils::mark; use super::{BindingMode, Expectation, InferenceContext}; use crate::{utils::variant_data, Substs, Ty, TypeCtor}; @@ -111,7 +111,7 @@ impl<'a> InferenceContext<'a> { } } } else if let Pat::Ref { .. } = &body[pat] { - tested_by!(match_ergonomics_ref); + mark::hit!(match_ergonomics_ref); // When you encounter a `&pat` pattern, reset to Move. // This is so that `w` is by value: `let (_, &w) = &(1, &2);` default_bm = BindingMode::Move; diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs index ab0bc8b70..269495ca0 100644 --- a/crates/ra_hir_ty/src/infer/unify.rs +++ b/crates/ra_hir_ty/src/infer/unify.rs @@ -4,7 +4,7 @@ use std::borrow::Cow; use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; -use test_utils::tested_by; +use test_utils::mark; use super::{InferenceContext, Obligation}; use crate::{ @@ -313,7 +313,7 @@ impl InferenceTable { // more than once for i in 0..3 { if i > 0 { - tested_by!(type_var_resolves_to_int_var); + mark::hit!(type_var_resolves_to_int_var); } match &*ty { Ty::Infer(tv) => { @@ -342,7 +342,7 @@ impl InferenceTable { Ty::Infer(tv) => { let inner = tv.to_inner(); if tv_stack.contains(&inner) { - tested_by!(type_var_cycles_resolve_as_possible); + mark::hit!(type_var_cycles_resolve_as_possible); // recursive type return tv.fallback_value(); } @@ -369,7 +369,7 @@ impl InferenceTable { Ty::Infer(tv) => { let inner = tv.to_inner(); if tv_stack.contains(&inner) { - tested_by!(type_var_cycles_resolve_completely); + mark::hit!(type_var_cycles_resolve_completely); // recursive type return tv.fallback_value(); } diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index daea02f88..c87ee06ce 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -42,7 +42,6 @@ pub mod expr; mod tests; #[cfg(test)] mod test_db; -mod marks; mod _match; use std::ops::Deref; diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 9ad6dbe07..35ac86a46 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -812,7 +812,7 @@ impl TraitEnvironment { // add `Self: Trait` to the environment in trait // function default implementations (and hypothetical code // inside consts or type aliases) - test_utils::tested_by!(trait_self_implements_self); + test_utils::mark::hit!(trait_self_implements_self); let substs = Substs::type_params(db, trait_id); let trait_ref = TraitRef { trait_: trait_id, substs }; let pred = GenericPredicate::Implemented(trait_ref); diff --git a/crates/ra_hir_ty/src/marks.rs b/crates/ra_hir_ty/src/marks.rs deleted file mode 100644 index a39740143..000000000 --- a/crates/ra_hir_ty/src/marks.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! See test_utils/src/marks.rs - -test_utils::marks!( - type_var_cycles_resolve_completely - type_var_cycles_resolve_as_possible - type_var_resolves_to_int_var - impl_self_type_match_without_receiver - match_ergonomics_ref - coerce_merge_fail_fallback - coerce_fn_reification - trait_self_implements_self -); diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 0851e16a8..e19628fdf 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -469,7 +469,7 @@ fn iterate_inherent_methods( // already happens in `is_valid_candidate` above; if not, we // check it here if receiver_ty.is_none() && inherent_impl_substs(db, impl_def, self_ty).is_none() { - test_utils::tested_by!(impl_self_type_match_without_receiver); + test_utils::mark::hit!(impl_self_type_match_without_receiver); continue; } if let Some(result) = callback(&self_ty.value, item) { diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 6dc4b2cd1..2cc4f4bf9 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -1,6 +1,6 @@ use super::infer_with_mismatches; use insta::assert_snapshot; -use test_utils::covers; +use test_utils::mark; // Infer with some common definitions and impls. fn infer(source: &str) -> String { @@ -339,7 +339,7 @@ fn test(i: i32) { #[test] fn coerce_merge_one_by_one1() { - covers!(coerce_merge_fail_fallback); + mark::check!(coerce_merge_fail_fallback); assert_snapshot!( infer(r#" @@ -547,7 +547,7 @@ fn test() { #[test] fn coerce_fn_items_in_match_arms() { - covers!(coerce_fn_reification); + mark::check!(coerce_fn_reification); assert_snapshot!( infer_with_mismatches(r#" fn foo1(x: u32) -> isize { 1 } diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 9c2c9e1d2..558a70022 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs @@ -984,7 +984,7 @@ fn test() { S2.into()<|>; } #[test] fn method_resolution_overloaded_method() { - test_utils::covers!(impl_self_type_match_without_receiver); + test_utils::mark::check!(impl_self_type_match_without_receiver); let t = type_at( r#" //- main.rs diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index d83ff5e0e..0c5f972a2 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs @@ -1,5 +1,5 @@ use insta::assert_snapshot; -use test_utils::covers; +use test_utils::mark; use super::{infer, infer_with_mismatches}; @@ -197,7 +197,7 @@ fn test() { #[test] fn infer_pattern_match_ergonomics_ref() { - covers!(match_ergonomics_ref); + mark::check!(match_ergonomics_ref); assert_snapshot!( infer(r#" fn test() { diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index c2168222e..1f004bd63 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs @@ -1,9 +1,10 @@ use insta::assert_snapshot; -use test_utils::covers; +use ra_db::fixture::WithFixture; +use test_utils::mark; -use super::infer; use crate::test_db::TestDB; -use ra_db::fixture::WithFixture; + +use super::infer; #[test] fn bug_484() { @@ -89,8 +90,8 @@ fn quux() { #[test] fn recursive_vars() { - covers!(type_var_cycles_resolve_completely); - covers!(type_var_cycles_resolve_as_possible); + mark::check!(type_var_cycles_resolve_completely); + mark::check!(type_var_cycles_resolve_as_possible); assert_snapshot!( infer(r#" fn test() { @@ -112,8 +113,6 @@ fn test() { #[test] fn recursive_vars_2() { - covers!(type_var_cycles_resolve_completely); - covers!(type_var_cycles_resolve_as_possible); assert_snapshot!( infer(r#" fn test() { @@ -170,7 +169,7 @@ fn write() { #[test] fn infer_std_crash_2() { - covers!(type_var_resolves_to_int_var); + mark::check!(type_var_resolves_to_int_var); // caused "equating two type variables, ...", taken from std assert_snapshot!( infer(r#" diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index c49aacf98..34f4b9039 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -1,10 +1,11 @@ use insta::assert_snapshot; - use ra_db::fixture::WithFixture; +use test_utils::mark; -use super::{infer, infer_with_mismatches, type_at, type_at_pos}; use crate::test_db::TestDB; +use super::{infer, infer_with_mismatches, type_at, type_at_pos}; + #[test] fn infer_await() { let (db, pos) = TestDB::with_position( @@ -301,7 +302,7 @@ fn test() { #[test] fn trait_default_method_self_bound_implements_trait() { - test_utils::covers!(trait_self_implements_self); + mark::check!(trait_self_implements_self); assert_snapshot!( infer(r#" trait Trait { @@ -324,7 +325,6 @@ trait Trait { #[test] fn trait_default_method_self_bound_implements_super_trait() { - test_utils::covers!(trait_self_implements_self); assert_snapshot!( infer(r#" trait SuperTrait { -- cgit v1.2.3