@@ -359,7 +359,11 @@ impl Context {
359359 /// 単一化、評価等はここでは行わない、スーパータイプになる **可能性があるか** だけ判定する
360360 /// ので、lhsが(未連携)型変数の場合は単一化せずにtrueを返す
361361 pub ( crate ) fn structural_supertype_of ( & self , lhs : & Type , rhs : & Type ) -> bool {
362- set_recursion_limit ! ( false , 128 ) ;
362+ set_recursion_limit ! (
363+ panic,
364+ "recursion limit exceed: structural_supertype_of({lhs}, {rhs})" ,
365+ 128
366+ ) ;
363367 match ( lhs, rhs) {
364368 // Proc :> Func if params are compatible
365369 // * default params can be omitted (e.g. (Int, x := Int) -> Int <: (Int) -> Int)
@@ -409,45 +413,48 @@ impl Context {
409413 . return_t
410414 . clone ( )
411415 . replace_params ( rs. param_names ( ) , ls. param_names ( ) ) ;
412- let return_t_judge = self . supertype_of ( & ls. return_t , & rhs_ret) ; // covariant
413- let non_defaults_judge = if let Some ( r_var) = rs. var_params . as_deref ( ) {
414- ls. non_default_params
415- . iter ( )
416- . zip ( repeat ( r_var) )
417- . all ( |( l, r) | self . subtype_of ( l. typ ( ) , r. typ ( ) ) )
418- } else {
419- let rs_params = if !ls. is_method ( ) && rs. is_method ( ) {
420- rs. non_default_params
416+ let return_t_judge = || self . supertype_of ( & ls. return_t , & rhs_ret) ; // covariant
417+ let non_defaults_judge = || {
418+ if let Some ( r_var) = rs. var_params . as_deref ( ) {
419+ ls. non_default_params
421420 . iter ( )
422- . skip ( 1 )
423- . chain ( & rs . default_params )
421+ . zip ( repeat ( r_var ) )
422+ . all ( | ( l , r ) | self . subtype_of ( l . typ ( ) , r . typ ( ) ) )
424423 } else {
425- #[ allow( clippy:: iter_skip_zero) ]
426- rs. non_default_params
424+ let rs_params = if !ls. is_method ( ) && rs. is_method ( ) {
425+ rs. non_default_params
426+ . iter ( )
427+ . skip ( 1 )
428+ . chain ( & rs. default_params )
429+ } else {
430+ #[ allow( clippy:: iter_skip_zero) ]
431+ rs. non_default_params
432+ . iter ( )
433+ . skip ( 0 )
434+ . chain ( & rs. default_params )
435+ } ;
436+ ls. non_default_params
427437 . iter ( )
428- . skip ( 0 )
429- . chain ( & rs. default_params )
430- } ;
431- ls. non_default_params
432- . iter ( )
433- . zip ( rs_params)
434- . all ( |( l, r) | self . subtype_of ( l. typ ( ) , r. typ ( ) ) )
438+ . zip ( rs_params)
439+ . all ( |( l, r) | self . subtype_of ( l. typ ( ) , r. typ ( ) ) )
440+ }
441+ } ;
442+ let var_params_judge = || {
443+ ls. var_params
444+ . as_ref ( )
445+ . zip ( rs. var_params . as_ref ( ) )
446+ . map ( |( l, r) | self . subtype_of ( l. typ ( ) , r. typ ( ) ) )
447+ . unwrap_or ( true )
435448 } ;
436- let var_params_judge = ls
437- . var_params
438- . as_ref ( )
439- . zip ( rs. var_params . as_ref ( ) )
440- . map ( |( l, r) | self . subtype_of ( l. typ ( ) , r. typ ( ) ) )
441- . unwrap_or ( true ) ;
442449 len_judge
443- && return_t_judge
444- && non_defaults_judge
445- && var_params_judge
450+ && return_t_judge ( )
451+ && non_defaults_judge ( )
452+ && var_params_judge ( )
446453 && default_check ( ) // contravariant
447454 }
448455 // {Int} <: Obj -> Int
449- ( Subr ( _) | Quantified ( _) , Refinement ( refine ) )
450- if rhs. singleton_value ( ) . is_some ( ) && self . subtype_of ( & refine . t , & ClassType ) =>
456+ ( Subr ( _) | Quantified ( _) , Refinement ( _refine ) )
457+ if rhs. singleton_value ( ) . is_some ( ) && rhs . is_singleton_refinement_type ( ) =>
451458 {
452459 let Ok ( typ) = self . convert_tp_into_type ( rhs. singleton_value ( ) . unwrap ( ) . clone ( ) )
453460 else {
@@ -457,7 +464,8 @@ impl Context {
457464 return false ;
458465 } ;
459466 if let Some ( ( _, __call__) ) = ctx. get_class_attr ( "__call__" ) {
460- self . supertype_of ( lhs, & __call__. t )
467+ let call_t = __call__. t . clone ( ) . undoable_root ( ) ;
468+ self . supertype_of ( lhs, & call_t)
461469 } else {
462470 false
463471 }
@@ -767,10 +775,14 @@ impl Context {
767775 // Bool :> {2} == false
768776 // [2, 3]: {A: List(Nat) | A.prod() == 6}
769777 // List({1, 2}, _) :> {[3, 4]} == false
778+ // T :> {None} == T :> NoneType
770779 ( l, Refinement ( r) ) => {
771780 // Type / {S: Set(Str) | S == {"a", "b"}}
772781 // TODO: GeneralEq
773782 if let Pred :: Equal { rhs, .. } = r. pred . as_ref ( ) {
783+ if rhs. is_none ( ) {
784+ return self . supertype_of ( lhs, & NoneType ) ;
785+ }
774786 if self . subtype_of ( l, & Type ) && self . convert_tp_into_type ( rhs. clone ( ) ) . is_ok ( ) {
775787 return true ;
776788 }
@@ -937,6 +949,11 @@ impl Context {
937949 }
938950 }
939951
952+ /// ```erg
953+ /// Int.fields() == { imag: Int, real: Int, abs: (self: Int) -> Nat, ... }
954+ /// ?T(<: Int).fields() == Int.fields()
955+ /// Structural({ .x = Int }).fields() == { x: Int }
956+ /// ```
940957 pub fn fields ( & self , t : & Type ) -> Dict < Field , Type > {
941958 match t {
942959 Type :: FreeVar ( fv) if fv. is_linked ( ) => self . fields ( & fv. unwrap_linked ( ) ) ,
0 commit comments