@@ -29,6 +29,7 @@ use crate::literal::Lit;
2929use crate :: stdlib:: Stdlib ;
3030use crate :: tuple:: Tuple ;
3131use crate :: type_alias:: TypeAliasData ;
32+ use crate :: type_alias:: TypeAliasRef ;
3233use crate :: type_output:: DisplayOutput ;
3334use crate :: type_output:: OutputWithLocations ;
3435use crate :: type_output:: TypeOutput ;
@@ -849,12 +850,19 @@ impl<'a> TypeDisplayContext<'a> {
849850 AnyStyle :: Explicit => self . maybe_fmt_with_module ( "typing" , "Any" , output) ,
850851 AnyStyle :: Implicit | AnyStyle :: Error => output. write_str ( "Unknown" ) ,
851852 } ,
852- Type :: TypeAlias ( ta) => {
853- if is_toplevel && let TypeAliasData :: Value ( ta) = & * * ta {
853+ Type :: TypeAlias ( ta) => match & * * ta {
854+ TypeAliasData :: Value ( ta) if is_toplevel => {
854855 ta. fmt_with_type ( output, & |t, o| self . fmt_helper_generic ( t, false , o) , None )
855- } else {
856- write ! ( output, "type[{}]" , ta. name( ) )
857856 }
857+ TypeAliasData :: Value ( ta) => write ! ( output, "type[{}]" , ta. name) ,
858+ TypeAliasData :: Ref ( r) => {
859+ output. write_str ( "type[" ) ?;
860+ self . fmt_helper_type_alias_ref ( r, output) ?;
861+ output. write_str ( "]" )
862+ }
863+ } ,
864+ Type :: UntypedAlias ( box TypeAliasData :: Ref ( r) ) => {
865+ self . fmt_helper_type_alias_ref ( r, output)
858866 }
859867 Type :: UntypedAlias ( ta) => output. write_str ( ta. name ( ) . as_str ( ) ) ,
860868 Type :: SuperInstance ( box ( cls, obj) ) => {
@@ -895,6 +903,31 @@ impl<'a> TypeDisplayContext<'a> {
895903 self . fmt_helper_generic ( t, is_toplevel, output)
896904 }
897905
906+ fn fmt_helper_type_alias_ref (
907+ & self ,
908+ r : & TypeAliasRef ,
909+ output : & mut impl TypeOutput ,
910+ ) -> fmt:: Result {
911+ match r {
912+ TypeAliasRef {
913+ name,
914+ args : Some ( args) ,
915+ ..
916+ } => {
917+ output. write_str ( name. as_str ( ) ) ?;
918+ write ! ( output, "[" ) ?;
919+ for ( i, t) in args. as_slice ( ) . iter ( ) . enumerate ( ) {
920+ if i > 0 {
921+ output. write_str ( ", " ) ?;
922+ }
923+ output. write_type ( t) ?;
924+ }
925+ write ! ( output, "]" )
926+ }
927+ _ => output. write_str ( r. name . as_str ( ) ) ,
928+ }
929+ }
930+
898931 /// This method wraps `fmt_helper_generic` with `OutputWithLocations` to track
899932 /// the source location (module and text range) of each type component in the output
900933 /// This is useful for IDE features like goto-type-definition
@@ -1013,6 +1046,7 @@ pub mod tests {
10131046 use crate :: tuple:: Tuple ;
10141047 use crate :: type_alias:: TypeAlias ;
10151048 use crate :: type_alias:: TypeAliasData ;
1049+ use crate :: type_alias:: TypeAliasIndex ;
10161050 use crate :: type_alias:: TypeAliasStyle ;
10171051 use crate :: type_var:: PreInferenceVariance ;
10181052 use crate :: type_var:: Restriction ;
@@ -1528,6 +1562,34 @@ pub mod tests {
15281562 assert_eq ! ( ctx. display( & wrapped) . to_string( ) , "tuple[type[MyAlias]]" ) ;
15291563 }
15301564
1565+ #[ test]
1566+ fn test_display_specialized_untyped_alias ( ) {
1567+ let uniques = UniqueFactory :: new ( ) ;
1568+
1569+ let tparams1 = fake_tparams ( vec ! [ fake_tparam( & uniques, "T" , QuantifiedKind :: TypeVar ) ] ) ;
1570+ let alias1 = Type :: UntypedAlias ( Box :: new ( TypeAliasData :: Ref ( TypeAliasRef {
1571+ name : Name :: new_static ( "X" ) ,
1572+ args : Some ( TArgs :: new ( tparams1, vec ! [ Type :: any_implicit( ) ] ) ) ,
1573+ module : ModuleName :: from_str ( "test" ) ,
1574+ index : TypeAliasIndex ( 0 ) ,
1575+ } ) ) ) ;
1576+
1577+ let tparams2 = fake_tparams ( vec ! [
1578+ fake_tparam( & uniques, "K" , QuantifiedKind :: TypeVar ) ,
1579+ fake_tparam( & uniques, "V" , QuantifiedKind :: TypeVar ) ,
1580+ ] ) ;
1581+ let alias2 = Type :: UntypedAlias ( Box :: new ( TypeAliasData :: Ref ( TypeAliasRef {
1582+ name : Name :: new_static ( "Y" ) ,
1583+ args : Some ( TArgs :: new ( tparams2, vec ! [ Type :: any_implicit( ) , Type :: None ] ) ) ,
1584+ module : ModuleName :: from_str ( "test" ) ,
1585+ index : TypeAliasIndex ( 1 ) ,
1586+ } ) ) ) ;
1587+
1588+ let ctx = TypeDisplayContext :: new ( & [ & alias1, & alias2] ) ;
1589+ assert_eq ! ( ctx. display( & alias1) . to_string( ) , "X[Unknown]" ) ;
1590+ assert_eq ! ( ctx. display( & alias2) . to_string( ) , "Y[Unknown, None]" ) ;
1591+ }
1592+
15311593 #[ test]
15321594 fn test_display_optional_parameter ( ) {
15331595 let param1 = Param :: PosOnly (
0 commit comments