@@ -28,15 +28,24 @@ pub enum BoundType {
2828
2929impl BoundType {
3030 pub fn need_isa ( & self ) -> bool {
31- matches ! ( * self , BoundType :: IsA ( _) )
31+ matches ! ( * self , Self :: IsA ( _) )
32+ }
33+
34+ // TODO: This is just a heuristic for now, based on what we do in codegen!
35+ // Theoretically the surrounding function should determine whether it needs to
36+ // reuse an alias (ie. to use in `call_func::<P, Q, R>`) or not.
37+ // In the latter case an `impl` is generated instead of a type name/alias.
38+ pub fn has_alias ( & self ) -> bool {
39+ matches ! ( * self , Self :: NoWrapper )
3240 }
3341}
3442
3543#[ derive( Clone , Eq , Debug , PartialEq ) ]
3644pub struct Bound {
3745 pub bound_type : BoundType ,
3846 pub parameter_name : String ,
39- pub alias : char ,
47+ /// Bound does not have an alias when `param: impl type_str` is used
48+ pub alias : Option < char > ,
4049 pub type_str : String ,
4150 pub callback_modified : bool ,
4251}
@@ -217,7 +226,9 @@ impl Bounds {
217226 if self . used . iter ( ) . any ( |n| n. parameter_name == name) {
218227 return ;
219228 }
220- let alias = self . unused . pop_front ( ) . expect ( "No free type aliases!" ) ;
229+ let alias = bound_type
230+ . has_alias ( )
231+ . then ( || self . unused . pop_front ( ) . expect ( "No free type aliases!" ) ) ;
221232 self . used . push ( Bound {
222233 bound_type,
223234 parameter_name : name. to_owned ( ) ,
@@ -375,15 +386,36 @@ mod tests {
375386 #[ test]
376387 fn get_parameter_bound ( ) {
377388 let mut bounds: Bounds = Default :: default ( ) ;
378- let typ = BoundType :: IsA ( None ) ;
389+ let typ = BoundType :: NoWrapper ;
379390 bounds. add_parameter ( "a" , "" , typ. clone ( ) , false ) ;
380391 bounds. add_parameter ( "b" , "" , typ. clone ( ) , false ) ;
381392 let bound = bounds. get_parameter_bound ( "a" ) . unwrap ( ) ;
382- assert_eq ! ( bound. alias, 'P' ) ;
393+ // `NoWrapper `bounds are expected to have an alias:
394+ assert_eq ! ( bound. alias, Some ( 'P' ) ) ;
383395 assert_eq ! ( bound. bound_type, typ) ;
384396 let bound = bounds. get_parameter_bound ( "b" ) . unwrap ( ) ;
385- assert_eq ! ( bound. alias, 'Q' ) ;
397+ assert_eq ! ( bound. alias, Some ( 'Q' ) ) ;
386398 assert_eq ! ( bound. bound_type, typ) ;
387399 assert_eq ! ( bounds. get_parameter_bound( "c" ) , None ) ;
388400 }
401+
402+ #[ test]
403+ fn impl_bound ( ) {
404+ let mut bounds: Bounds = Default :: default ( ) ;
405+ let typ = BoundType :: IsA ( None ) ;
406+ bounds. add_parameter ( "a" , "" , typ. clone ( ) , false ) ;
407+ bounds. add_parameter ( "b" , "" , typ. clone ( ) , false ) ;
408+ let bound = bounds. get_parameter_bound ( "a" ) . unwrap ( ) ;
409+ // `IsA` is simplified to an inline `foo: impl IsA<Bar>` and
410+ // lacks an alias/type-parameter:
411+ assert_eq ! ( bound. alias, None ) ;
412+ assert_eq ! ( bound. bound_type, typ) ;
413+
414+ let typ = BoundType :: AsRef ( None ) ;
415+ bounds. add_parameter ( "c" , "" , typ. clone ( ) , false ) ;
416+ let bound = bounds. get_parameter_bound ( "c" ) . unwrap ( ) ;
417+ // Same `impl AsRef<Foo>` simplification as `IsA`:
418+ assert_eq ! ( bound. alias, None ) ;
419+ assert_eq ! ( bound. bound_type, typ) ;
420+ }
389421}
0 commit comments