@@ -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" ) ]
@@ -310,8 +313,8 @@ impl<'a> BlockContext<'a> {
310
313
self . info [ handle] . ty . inner_with ( self . types )
311
314
}
312
315
313
- fn inner_type < ' t > ( & ' t self , ty : & ' t TypeResolution ) -> & ' t crate :: TypeInner {
314
- ty . inner_with ( self . types )
316
+ fn compare_types ( & self , lhs : & TypeResolution , rhs : & TypeResolution ) -> bool {
317
+ crate :: proc :: compare_types ( lhs , rhs , self . types )
315
318
}
316
319
}
317
320
@@ -338,8 +341,7 @@ impl super::Validator {
338
341
CallError :: Argument { index, source }
339
342
. with_span_handle ( expr, context. expressions )
340
343
} ) ?;
341
- let arg_inner = & context. types [ arg. ty ] . inner ;
342
- if !ty. inner_with ( context. types ) . non_struct_equivalent ( arg_inner, context. types ) {
344
+ if !context. compare_types ( & TypeResolution :: Handle ( arg. ty ) , ty) {
343
345
return Err ( CallError :: ArgumentType {
344
346
index,
345
347
required : arg. ty ,
@@ -964,13 +966,12 @@ impl super::Validator {
964
966
let value_ty = value
965
967
. map ( |expr| context. resolve_type ( expr, & self . valid_expression_set ) )
966
968
. transpose ( ) ?;
967
- let expected_ty = context. return_type . map ( |ty| & context. types [ ty] . inner ) ;
968
969
// We can't return pointers, but it seems best not to embed that
969
970
// assumption here, so use `TypeInner::equivalent` for comparison.
970
- let okay = match ( value_ty, expected_ty ) {
971
+ let okay = match ( value_ty, context . return_type ) {
971
972
( None , None ) => true ,
972
- ( Some ( value_inner) , Some ( expected_inner ) ) => {
973
- value_inner . inner_with ( context. types ) . non_struct_equivalent ( expected_inner , context . types )
973
+ ( Some ( value_inner) , Some ( expected_ty ) ) => {
974
+ context. compare_types ( value_inner , & TypeResolution :: Handle ( expected_ty ) )
974
975
}
975
976
( _, _) => false ,
976
977
} ;
@@ -979,14 +980,20 @@ impl super::Validator {
979
980
log:: error!(
980
981
"Returning {:?} where {:?} is expected" ,
981
982
value_ty,
982
- expected_ty
983
+ context . return_type ,
983
984
) ;
984
985
if let Some ( handle) = value {
985
- return Err ( FunctionError :: InvalidReturnType ( value)
986
- . with_span_handle ( handle, context. expressions ) ) ;
986
+ return Err ( FunctionError :: InvalidReturnType {
987
+ expression : value,
988
+ expected_ty : context. return_type ,
989
+ }
990
+ . with_span_handle ( handle, context. expressions ) ) ;
987
991
} else {
988
- return Err ( FunctionError :: InvalidReturnType ( value)
989
- . with_span_static ( span, "invalid return" ) ) ;
992
+ return Err ( FunctionError :: InvalidReturnType {
993
+ expression : value,
994
+ expected_ty : context. return_type ,
995
+ }
996
+ . with_span_static ( span, "invalid return" ) ) ;
990
997
}
991
998
}
992
999
finished = true ;
@@ -1036,7 +1043,8 @@ impl super::Validator {
1036
1043
}
1037
1044
}
1038
1045
1039
- let value_ty = context. resolve_type_inner ( value, & self . valid_expression_set ) ?;
1046
+ let value_tr = context. resolve_type ( value, & self . valid_expression_set ) ?;
1047
+ let value_ty = value_tr. inner_with ( context. types ) ;
1040
1048
match * value_ty {
1041
1049
Ti :: Image { .. } | Ti :: Sampler { .. } => {
1042
1050
return Err ( FunctionError :: InvalidStoreTexture {
@@ -1053,16 +1061,19 @@ impl super::Validator {
1053
1061
}
1054
1062
1055
1063
let pointer_ty = context. resolve_pointer_type ( pointer) ;
1056
- let good = match pointer_ty
1057
- . pointer_base_type ( )
1064
+ let pointer_base_tr = pointer_ty. pointer_base_type ( ) ;
1065
+ let pointer_base_ty = pointer_base_tr
1058
1066
. as_ref ( )
1059
- . map ( |ty| context . inner_type ( ty ) )
1060
- {
1067
+ . map ( |ty| ty . inner_with ( context . types ) ) ;
1068
+ let good = if let Some ( & Ti :: Atomic ( ref scalar ) ) = pointer_base_ty {
1061
1069
// The Naga IR allows storing a scalar to an atomic.
1062
- Some ( & Ti :: Atomic ( ref scalar) ) => * value_ty == Ti :: Scalar ( * scalar) ,
1063
- Some ( other) => * value_ty == * other,
1064
- None => false ,
1070
+ * value_ty == Ti :: Scalar ( * scalar)
1071
+ } else if let Some ( tr) = pointer_base_tr {
1072
+ context. compare_types ( value_tr, & tr)
1073
+ } else {
1074
+ false
1065
1075
} ;
1076
+
1066
1077
if !good {
1067
1078
return Err ( FunctionError :: InvalidStoreTypes { pointer, value }
1068
1079
. with_span ( )
@@ -1640,9 +1651,7 @@ impl super::Validator {
1640
1651
}
1641
1652
1642
1653
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 ) {
1654
+ if !gctx. compare_types ( & TypeResolution :: Handle ( var. ty ) , & fun_info[ init] . ty ) {
1646
1655
return Err ( LocalVariableError :: InitializerType ) ;
1647
1656
}
1648
1657
0 commit comments