@@ -120,8 +120,11 @@ pub enum FunctionError {
120
120
ContinueOutsideOfLoop ,
121
121
#[ error( "The `return` is called within a `continuing` block" ) ]
122
122
InvalidReturnSpot ,
123
- #[ error( "The `return` value {0:?} does not match the function return value" ) ]
124
- InvalidReturnType ( Option < Handle < crate :: Expression > > ) ,
123
+ #[ error( "The `return` expression {expression:?} does not match the declared return type {expected_ty:?}" ) ]
124
+ InvalidReturnType {
125
+ expression : Option < Handle < crate :: Expression > > ,
126
+ expected_ty : Option < Handle < crate :: Type > > ,
127
+ } ,
125
128
#[ error( "The `if` condition {0:?} is not a boolean scalar" ) ]
126
129
InvalidIfType ( Handle < crate :: Expression > ) ,
127
130
#[ error( "The `switch` value {0:?} is not an integer scalar" ) ]
@@ -313,6 +316,14 @@ impl<'a> BlockContext<'a> {
313
316
fn inner_type < ' t > ( & ' t self , ty : & ' t TypeResolution ) -> & ' t crate :: TypeInner {
314
317
ty. inner_with ( self . types )
315
318
}
319
+
320
+ fn compare_types < L : Into < TypeResolution > , R : Into < TypeResolution > > (
321
+ & self ,
322
+ lhs : L ,
323
+ rhs : R ,
324
+ ) -> bool {
325
+ crate :: proc:: compare_types ( lhs, rhs, self . types )
326
+ }
316
327
}
317
328
318
329
impl super :: Validator {
@@ -338,8 +349,7 @@ impl super::Validator {
338
349
CallError :: Argument { index, source }
339
350
. with_span_handle ( expr, context. expressions )
340
351
} ) ?;
341
- let arg_inner = & context. types [ arg. ty ] . inner ;
342
- if !ty. non_struct_equivalent ( arg_inner, context. types ) {
352
+ if !context. compare_types ( arg. ty , ty. clone ( ) ) {
343
353
return Err ( CallError :: ArgumentType {
344
354
index,
345
355
required : arg. ty ,
@@ -964,13 +974,12 @@ impl super::Validator {
964
974
let value_ty = value
965
975
. map ( |expr| context. resolve_type ( expr, & self . valid_expression_set ) )
966
976
. transpose ( ) ?;
967
- let expected_ty = context. return_type . map ( |ty| & context. types [ ty] . inner ) ;
968
977
// We can't return pointers, but it seems best not to embed that
969
978
// assumption here, so use `TypeInner::equivalent` for comparison.
970
- let okay = match ( value_ty, expected_ty ) {
979
+ let okay = match ( value_ty, context . return_type ) {
971
980
( None , None ) => true ,
972
- ( Some ( value_inner) , Some ( expected_inner ) ) => {
973
- value_inner. non_struct_equivalent ( expected_inner , context . types )
981
+ ( Some ( value_inner) , Some ( expected_ty ) ) => {
982
+ context . compare_types ( value_inner. clone ( ) , expected_ty )
974
983
}
975
984
( _, _) => false ,
976
985
} ;
@@ -979,14 +988,20 @@ impl super::Validator {
979
988
log:: error!(
980
989
"Returning {:?} where {:?} is expected" ,
981
990
value_ty,
982
- expected_ty
991
+ context . return_type ,
983
992
) ;
984
993
if let Some ( handle) = value {
985
- return Err ( FunctionError :: InvalidReturnType ( value)
986
- . with_span_handle ( handle, context. expressions ) ) ;
994
+ return Err ( FunctionError :: InvalidReturnType {
995
+ expression : value,
996
+ expected_ty : context. return_type ,
997
+ }
998
+ . with_span_handle ( handle, context. expressions ) ) ;
987
999
} else {
988
- return Err ( FunctionError :: InvalidReturnType ( value)
989
- . with_span_static ( span, "invalid return" ) ) ;
1000
+ return Err ( FunctionError :: InvalidReturnType {
1001
+ expression : value,
1002
+ expected_ty : context. return_type ,
1003
+ }
1004
+ . with_span_static ( span, "invalid return" ) ) ;
990
1005
}
991
1006
}
992
1007
finished = true ;
@@ -1640,9 +1655,7 @@ impl super::Validator {
1640
1655
}
1641
1656
1642
1657
if let Some ( init) = var. init {
1643
- let decl_ty = & gctx. types [ var. ty ] . inner ;
1644
- let init_ty = fun_info[ init] . ty . inner_with ( gctx. types ) ;
1645
- if !decl_ty. non_struct_equivalent ( init_ty, gctx. types ) {
1658
+ if !gctx. compare_types ( var. ty , fun_info[ init] . ty . clone ( ) ) {
1646
1659
return Err ( LocalVariableError :: InitializerType ) ;
1647
1660
}
1648
1661
0 commit comments