@@ -19,24 +19,22 @@ use crate::internal::source_location::SourceLocation;
1919use crate :: internal:: test_outcome:: TestAssertionFailure ;
2020use crate :: matchers:: __internal_unstable_do_not_depend_on_these:: ConjunctionMatcher ;
2121use crate :: matchers:: __internal_unstable_do_not_depend_on_these:: DisjunctionMatcher ;
22+ pub use googletest_macro:: MatcherExt ;
2223use std:: fmt:: Debug ;
2324
2425/// An interface for checking an arbitrary condition on a datum.
2526///
2627/// This trait is automatically implemented for a reference of any type
2728/// implementing `Matcher`. This simplifies reusing a matcher in different
2829/// assertions.
29- pub trait Matcher {
30- /// The type against which this matcher matches.
31- type ActualT : Debug + ?Sized ;
32-
30+ pub trait Matcher < ActualT : Debug + ?Sized > {
3331 /// Returns whether the condition matches the datum `actual`.
3432 ///
3533 /// The trait implementation defines what it means to "match". Often the
3634 /// matching condition is based on data stored in the matcher. For example,
3735 /// `eq` matches when its stored expected value is equal (in the sense of
3836 /// the `==` operator) to the value `actual`.
39- fn matches ( & self , actual : & Self :: ActualT ) -> MatcherResult ;
37+ fn matches ( & self , actual : & ActualT ) -> MatcherResult ;
4038
4139 /// Returns a description of `self` or a negative description if
4240 /// `matcher_result` is `DoesNotMatch`.
@@ -137,10 +135,22 @@ pub trait Matcher {
137135 /// .nested(self.expected.explain_match(actual.deref()))
138136 /// }
139137 /// ```
140- fn explain_match ( & self , actual : & Self :: ActualT ) -> Description {
138+ fn explain_match ( & self , actual : & ActualT ) -> Description {
141139 format ! ( "which {}" , self . describe( self . matches( actual) ) ) . into ( )
142140 }
141+ }
143142
143+ /// Trait extension for matchers. It is highly recommended to implement it for
144+ /// each type implementing `Matcher`.
145+ // The `and` and `or` functions cannot be part of the `Matcher` traits since it
146+ // is parametric. Consider that `and` and `or` are part of the `Matcher` trait
147+ // and `MyMatcher` implements both `Matcher<A>` and `Matcher<B>`.
148+ // Then `MyMatcher{...}.and(...)` can be either:
149+ // * `Matcher::<A>::and(MyMatcher{...}, ...)` or
150+ // * `Matcher::<B>::and(MyMatcher{...}, ...)`.
151+ // Moving the `and` and `or` functions in a non-generic trait remove this
152+ // confusion by making `and` and `or` unique for a given type.
153+ pub trait MatcherExt {
144154 /// Constructs a matcher that matches both `self` and `right`.
145155 ///
146156 /// ```
@@ -164,10 +174,7 @@ pub trait Matcher {
164174 // TODO(b/264518763): Replace the return type with impl Matcher and reduce
165175 // visibility of ConjunctionMatcher once impl in return position in trait
166176 // methods is stable.
167- fn and < Right : Matcher < ActualT = Self :: ActualT > > (
168- self ,
169- right : Right ,
170- ) -> ConjunctionMatcher < Self , Right >
177+ fn and < Right > ( self , right : Right ) -> ConjunctionMatcher < Self , Right >
171178 where
172179 Self : Sized ,
173180 {
@@ -194,10 +201,7 @@ pub trait Matcher {
194201 // TODO(b/264518763): Replace the return type with impl Matcher and reduce
195202 // visibility of DisjunctionMatcher once impl in return position in trait
196203 // methods is stable.
197- fn or < Right : Matcher < ActualT = Self :: ActualT > > (
198- self ,
199- right : Right ,
200- ) -> DisjunctionMatcher < Self , Right >
204+ fn or < Right > ( self , right : Right ) -> DisjunctionMatcher < Self , Right >
201205 where
202206 Self : Sized ,
203207 {
@@ -215,7 +219,7 @@ const PRETTY_PRINT_LENGTH_THRESHOLD: usize = 60;
215219/// The parameter `actual_expr` contains the expression which was evaluated to
216220/// obtain `actual`.
217221pub ( crate ) fn create_assertion_failure < T : Debug + ?Sized > (
218- matcher : & impl Matcher < ActualT = T > ,
222+ matcher : & impl Matcher < T > ,
219223 actual : & T ,
220224 actual_expr : & ' static str ,
221225 source_location : SourceLocation ,
@@ -273,18 +277,18 @@ impl MatcherResult {
273277 }
274278}
275279
276- impl < M : Matcher > Matcher for & M {
277- type ActualT = M :: ActualT ;
280+ impl < M : ?Sized + MatcherExt > MatcherExt for & M { }
278281
279- fn matches ( & self , actual : & Self :: ActualT ) -> MatcherResult {
282+ impl < T : Debug + ?Sized , M : Matcher < T > > Matcher < T > for & M {
283+ fn matches ( & self , actual : & T ) -> MatcherResult {
280284 ( * self ) . matches ( actual)
281285 }
282286
283287 fn describe ( & self , matcher_result : MatcherResult ) -> Description {
284288 ( * self ) . describe ( matcher_result)
285289 }
286290
287- fn explain_match ( & self , actual : & Self :: ActualT ) -> Description {
291+ fn explain_match ( & self , actual : & T ) -> Description {
288292 ( * self ) . explain_match ( actual)
289293 }
290294}
0 commit comments