@@ -187,48 +187,59 @@ bool expr_match(pass_opt_t* opt, ast_t* ast)
187187 type = control_type_add_branch (opt , type , cases );
188188 }
189189
190- // analyze exhaustiveness
191- ast_t * exhaustive_at = is_match_exhaustive (opt , expr_type , cases );
192-
193- if (exhaustive_at == NULL )
190+ // If the method definition containing the match site had its body inherited
191+ // from a trait, we don't want to check exhaustiveness here -
192+ // it should only be checked in the context of the original trait.
193+ bool skip_exhaustive = false;
194+ ast_t * body_donor = (ast_t * )ast_data (opt -> check .frame -> method );
195+ if ((body_donor != NULL ) && (ast_id (body_donor ) == TK_TRAIT ) && (ast_id (opt -> check .frame -> type ) != TK_TRAIT ))
196+ skip_exhaustive = true;
197+
198+ if (!skip_exhaustive )
194199 {
195- // match might not be exhaustive
196- if ((ast_id (else_clause ) == TK_NONE ))
197- {
198- // If we have no else clause, and the match is not found to be exhaustive,
199- // we must generate an implicit else clause that returns None as the value.
200- ast_scope (else_clause );
201- ast_setid (else_clause , TK_SEQ );
202-
203- BUILD (ref , else_clause ,
204- NODE (TK_TYPEREF ,
205- NONE
206- ID ("None" )
207- NONE ));
208- ast_add (else_clause , ref );
209-
210- if (!expr_typeref (opt , & ref ) || !expr_seq (opt , else_clause ))
211- return false;
212- }
213- }
214- else
215- {
216- // match is exhaustive
217- if (ast_sibling (exhaustive_at ) != NULL )
200+ // analyze exhaustiveness
201+ ast_t * exhaustive_at = is_match_exhaustive (opt , expr_type , cases );
202+
203+ if (exhaustive_at == NULL )
218204 {
219- // we have unreachable cases
220- ast_error (opt -> check .errors , ast , "match contains unreachable cases" );
221- ast_error_continue (opt -> check .errors , ast_sibling (exhaustive_at ),
222- "first unreachable case expression" );
223- return false;
205+ // match might not be exhaustive
206+ if ((ast_id (else_clause ) == TK_NONE ))
207+ {
208+ // If we have no else clause, and the match is not found to be exhaustive,
209+ // we must generate an implicit else clause that returns None as the value.
210+ ast_scope (else_clause );
211+ ast_setid (else_clause , TK_SEQ );
212+
213+ BUILD (ref , else_clause ,
214+ NODE (TK_TYPEREF ,
215+ NONE
216+ ID ("None" )
217+ NONE ));
218+ ast_add (else_clause , ref );
219+
220+ if (!expr_typeref (opt , & ref ) || !expr_seq (opt , else_clause ))
221+ return false;
222+ }
224223 }
225- else if (( ast_id ( else_clause ) != TK_NONE ))
224+ else
226225 {
227- ast_error (opt -> check .errors , ast ,
228- "match is exhaustive, the else clause is unreachable" );
229- ast_error_continue (opt -> check .errors , else_clause ,
230- "unreachable code" );
231- return false;
226+ // match is exhaustive
227+ if (ast_sibling (exhaustive_at ) != NULL )
228+ {
229+ // we have unreachable cases
230+ ast_error (opt -> check .errors , ast , "match contains unreachable cases" );
231+ ast_error_continue (opt -> check .errors , ast_sibling (exhaustive_at ),
232+ "first unreachable case expression" );
233+ return false;
234+ }
235+ else if ((ast_id (else_clause ) != TK_NONE ))
236+ {
237+ ast_error (opt -> check .errors , ast ,
238+ "match is exhaustive, the else clause is unreachable" );
239+ ast_error_continue (opt -> check .errors , else_clause ,
240+ "unreachable code" );
241+ return false;
242+ }
232243 }
233244 }
234245
@@ -465,10 +476,20 @@ static bool infer_pattern_type(ast_t* pattern, ast_t* match_expr_type,
465476 return coerce_literals (& pattern , match_expr_type , opt );
466477}
467478
479+ typedef struct foo
480+ {
481+ ast_t * body_donor ; // Type body was defined in. NULL if we have no body.
482+ ast_t * trait_ref ;
483+ bool local_define ;
484+ bool failed ;
485+ } foo ;
486+
468487bool expr_case (pass_opt_t * opt , ast_t * ast )
469488{
470489 pony_assert (opt != NULL );
471490 pony_assert (ast_id (ast ) == TK_CASE );
491+ bool ok = true;
492+
472493 AST_GET_CHILDREN (ast , pattern , guard , body );
473494
474495 if ((ast_id (pattern ) == TK_NONE ) && (ast_id (guard ) == TK_NONE ))
@@ -504,83 +525,102 @@ bool expr_case(pass_opt_t* opt, ast_t* ast)
504525
505526 ast_settype (ast , pattern_type );
506527
507- bool ok = true;
508- errorframe_t info = NULL ;
528+ // If the method definition containing the match site had its body inherited
529+ // from a trait, we don't want to check it here -
530+ // it should only be checked in the context of the original trait.
531+ bool skip = false;
532+ ast_t * body_donor = (ast_t * )ast_data (opt -> check .frame -> method );
533+ if ((body_donor != NULL ) && (ast_id (body_donor ) == TK_TRAIT ) && (ast_id (opt -> check .frame -> type ) != TK_TRAIT ))
534+ {
535+ skip = true;
536+ }
537+
538+ // if (ast_id(body_donor) == TK_TRAIT)
539+ // {
540+ // printf("%d %d %d\n", ast_id(opt->check.frame->method), ast_id(body_donor), TK_TRAIT);
541+ // ast_print(opt->check.frame->method
542+ // }
509543
510- switch ( is_matchtype_with_consumed_pattern ( match_type , pattern_type , & info , opt ) )
544+ if (! skip )
511545 {
512- case MATCHTYPE_ACCEPT :
513- break ;
546+ errorframe_t info = NULL ;
514547
515- case MATCHTYPE_REJECT :
548+ switch ( is_matchtype_with_consumed_pattern ( match_type , pattern_type , & info , opt ))
516549 {
517- errorframe_t frame = NULL ;
518- ast_error_frame (& frame , pattern , "this pattern can never match" );
519- ast_error_frame (& frame , match_type , "match type: %s" ,
520- ast_print_type (match_type ));
521- // TODO report unaliased type when body is consume !
522- ast_error_frame (& frame , pattern , "pattern type: %s" ,
523- ast_print_type (pattern_type ));
524- errorframe_append (& frame , & info );
525- errorframe_report (& frame , opt -> check .errors );
526-
527- ok = false;
528- break ;
529- }
550+ case MATCHTYPE_ACCEPT :
551+ break ;
530552
531- case MATCHTYPE_DENY_CAP :
532- {
533- errorframe_t frame = NULL ;
534- ast_error_frame (& frame , pattern ,
535- "this capture violates capabilities, because the match would "
536- "need to differentiate by capability at runtime instead of matching "
537- "on type alone" );
538- ast_error_frame (& frame , match_type , "the match type allows for more than "
539- "one possibility with the same type as pattern type, but different "
540- "capabilities. match type: %s" ,
541- ast_print_type (match_type ));
542- ast_error_frame (& frame , pattern , "pattern type: %s" ,
543- ast_print_type (pattern_type ));
544- errorframe_append (& frame , & info );
545- ast_error_frame (& frame , match_expr ,
546- "the match expression with the inadequate capability is here" );
547- errorframe_report (& frame , opt -> check .errors );
548-
549- ok = false;
550- break ;
551- }
553+ case MATCHTYPE_REJECT :
554+ {
555+ errorframe_t frame = NULL ;
556+ ast_error_frame (& frame , pattern , "this pattern can never match" );
557+ ast_error_frame (& frame , match_type , "match type: %s" ,
558+ ast_print_type (match_type ));
559+ // TODO report unaliased type when body is consume !
560+ ast_error_frame (& frame , pattern , "pattern type: %s" ,
561+ ast_print_type (pattern_type ));
562+ errorframe_append (& frame , & info );
563+ errorframe_report (& frame , opt -> check .errors );
564+
565+ ok = false;
566+ break ;
567+ }
552568
553- case MATCHTYPE_DENY_NODESC :
554- {
555- errorframe_t frame = NULL ;
556- ast_error_frame (& frame , pattern ,
557- "this capture cannot match, since the type %s "
558- "is a struct and lacks a type descriptor" ,
559- ast_print_type (pattern_type ));
560- ast_error_frame (& frame , match_type ,
561- "a struct cannot be part of a union type. match type: %s" ,
562- ast_print_type (match_type ));
563- ast_error_frame (& frame , pattern , "pattern type: %s" ,
564- ast_print_type (pattern_type ));
565- errorframe_append (& frame , & info );
566- errorframe_report (& frame , opt -> check .errors );
567- ok = false;
568- break ;
569- }
570- }
569+ case MATCHTYPE_DENY_CAP :
570+ {
571+ errorframe_t frame = NULL ;
572+ ast_error_frame (& frame , pattern ,
573+ "this capture violates capabilities, because the match would "
574+ "need to differentiate by capability at runtime instead of matching "
575+ "on type alone" );
576+ ast_error_frame (& frame , match_type , "the match type allows for more than "
577+ "one possibility with the same type as pattern type, but different "
578+ "capabilities. match type: %s" ,
579+ ast_print_type (match_type ));
580+ ast_error_frame (& frame , pattern , "pattern type: %s" ,
581+ ast_print_type (pattern_type ));
582+ errorframe_append (& frame , & info );
583+ ast_error_frame (& frame , match_expr ,
584+ "the match expression with the inadequate capability is here" );
585+ errorframe_report (& frame , opt -> check .errors );
586+
587+ ok = false;
588+ break ;
589+ }
571590
572- if (ast_id (guard ) != TK_NONE )
573- {
574- ast_t * guard_type = ast_type (guard );
591+ case MATCHTYPE_DENY_NODESC :
592+ {
593+ errorframe_t frame = NULL ;
594+ ast_error_frame (& frame , pattern ,
595+ "this capture cannot match, since the type %s "
596+ "is a struct and lacks a type descriptor" ,
597+ ast_print_type (pattern_type ));
598+ ast_error_frame (& frame , match_type ,
599+ "a struct cannot be part of a union type. match type: %s" ,
600+ ast_print_type (match_type ));
601+ ast_error_frame (& frame , pattern , "pattern type: %s" ,
602+ ast_print_type (pattern_type ));
603+ errorframe_append (& frame , & info );
604+ errorframe_report (& frame , opt -> check .errors );
605+ ok = false;
606+ break ;
607+ }
608+ }
575609
576- if (is_typecheck_error ( guard_type ) )
610+ if (ast_id ( guard ) != TK_NONE )
577611 {
578- ok = false;
579- } else if (!is_bool (guard_type )) {
580- ast_error (opt -> check .errors , guard ,
581- "guard must be a boolean expression" );
612+ ast_t * guard_type = ast_type (guard );
613+
614+ if (is_typecheck_error (guard_type ))
615+ {
616+ ok = false;
617+ } else if (!is_bool (guard_type )) {
618+ ast_error (opt -> check .errors , guard ,
619+ "guard must be a boolean expression" );
620+ }
582621 }
583622 }
623+
584624 return ok ;
585625}
586626
0 commit comments