@@ -133,7 +133,7 @@ impl Check<'_> {
133
133
let place_ty = self . check_place ( typeck_env, place_expression) ?;
134
134
135
135
// Check if the value expression is well-formed.
136
- let value_ty = self . check_value ( typeck_env, value_expression) ?;
136
+ let value_ty = self . check_value ( typeck_env, fn_assumptions , value_expression) ?;
137
137
138
138
// Check that the type of the value is a subtype of the place's type
139
139
self . prove_goal (
@@ -193,7 +193,7 @@ impl Check<'_> {
193
193
next_block,
194
194
} => {
195
195
// Function is part of the value expression, so we will check if the function exists in check_value.
196
- self . check_value ( typeck_env, callee) ?;
196
+ self . check_value ( typeck_env, fn_assumptions , callee) ?;
197
197
198
198
// Get argument information from the callee.
199
199
let Fn ( callee_fn_id) = callee else {
@@ -210,7 +210,11 @@ impl Check<'_> {
210
210
let arguments = zip ( callee_declared_input_tys, actual_arguments) ;
211
211
for ( declared_ty, actual_argument) in arguments {
212
212
// Check if the arguments are well formed.
213
- let actual_ty = self . check_argument_expression ( typeck_env, actual_argument) ?;
213
+ let actual_ty = self . check_argument_expression (
214
+ typeck_env,
215
+ fn_assumptions,
216
+ actual_argument,
217
+ ) ?;
214
218
// Check if the actual argument type passed in is the subtype of expect argument type.
215
219
self . prove_goal (
216
220
& typeck_env. env ,
@@ -247,7 +251,9 @@ impl Check<'_> {
247
251
fallback,
248
252
} => {
249
253
// Check if the value is well-formed.
250
- let value_ty = self . check_value ( typeck_env, switch_value) . unwrap ( ) ;
254
+ let value_ty = self
255
+ . check_value ( typeck_env, fn_assumptions, switch_value)
256
+ . unwrap ( ) ;
251
257
252
258
self . prove_judgment ( & typeck_env. env , & fn_assumptions, value_ty, ty_is_int) ?;
253
259
@@ -320,7 +326,12 @@ impl Check<'_> {
320
326
}
321
327
322
328
// Check if the value expression is well-formed, and return the type of the value expression.
323
- fn check_value ( & self , typeck_env : & mut TypeckEnv , value : & ValueExpression ) -> Fallible < Ty > {
329
+ fn check_value (
330
+ & self ,
331
+ typeck_env : & mut TypeckEnv ,
332
+ fn_assumptions : & Wcs ,
333
+ value : & ValueExpression ,
334
+ ) -> Fallible < Ty > {
324
335
let value_ty;
325
336
match value {
326
337
Load ( place_expression) => {
@@ -370,32 +381,37 @@ impl Check<'_> {
370
381
Ok ( constant. get_ty ( ) )
371
382
}
372
383
Struct ( value_expressions, ty) => {
384
+ // Check if the adt is well-formed.
385
+ self . prove_goal ( & typeck_env. env , & fn_assumptions, ty. well_formed ( ) ) ?;
386
+
373
387
let Some ( adt_id) = ty. get_adt_id ( ) else {
374
388
bail ! ( "The type used in ValueExpression::Struct must be adt" )
375
389
} ;
376
390
377
- // Check the validity of the struct.
391
+ // Make sure that the adt is struct.
378
392
let (
379
393
_,
380
394
AdtDeclBoundData {
381
395
where_clause : _,
382
396
variants,
383
397
} ,
384
398
) = self . decls . adt_decl ( & adt_id) . binder . open ( ) ;
399
+
385
400
let AdtDeclVariant { name, fields } = variants. last ( ) . unwrap ( ) ;
386
401
387
402
if * name != VariantId :: for_struct ( ) {
388
403
bail ! ( "This type used in ValueExpression::Struct should be a struct" )
389
404
}
390
405
391
- let struct_field_ty: Vec < Ty > =
406
+ // Check if the number of value provided match the number of field.
407
+ let struct_field_tys: Vec < Ty > =
392
408
fields. iter ( ) . map ( |field| field. ty . clone ( ) ) . collect ( ) ;
393
409
394
- if value_expressions. len ( ) != struct_field_ty . len ( ) {
410
+ if value_expressions. len ( ) != struct_field_tys . len ( ) {
395
411
bail ! ( "The length of ValueExpression::Tuple does not match the type of the ADT declared" )
396
412
}
397
413
398
- let expression_ty_pair = zip ( value_expressions, struct_field_ty ) ;
414
+ let expression_ty_pair = zip ( value_expressions, struct_field_tys ) ;
399
415
400
416
// FIXME: we only support const in value expression of struct for now, we can add support
401
417
// more in future.
@@ -404,7 +420,7 @@ impl Check<'_> {
404
420
let Constant ( _) = value_expression else {
405
421
bail ! ( "Only Constant is supported in ValueExpression::Struct for now." )
406
422
} ;
407
- let ty = self . check_value ( typeck_env, value_expression) ?;
423
+ let ty = self . check_value ( typeck_env, fn_assumptions , value_expression) ?;
408
424
409
425
// Make sure the type matches the declared adt.
410
426
if ty != declared_ty {
@@ -421,12 +437,13 @@ impl Check<'_> {
421
437
fn check_argument_expression (
422
438
& self ,
423
439
env : & mut TypeckEnv ,
440
+ fn_assumptions : & Wcs ,
424
441
arg_expr : & ArgumentExpression ,
425
442
) -> Fallible < Ty > {
426
443
let ty;
427
444
match arg_expr {
428
445
ByValue ( val_expr) => {
429
- ty = self . check_value ( env, val_expr) ?;
446
+ ty = self . check_value ( env, fn_assumptions , val_expr) ?;
430
447
}
431
448
InPlace ( place_expr) => {
432
449
ty = self . check_place ( env, place_expr) ?;
0 commit comments