@@ -326,7 +326,7 @@ impl<'a> LowerCtx<'a> { |
| 326 | 326 | is_pointer: false, |
| 327 | 327 | runtime_dim_upper: vec![], |
| 328 | 328 | is_class: false, |
| 329 | | - logical_kind: None, |
| 329 | + logical_kind: None, |
| 330 | 330 | last_dim_assumed_size: false, |
| 331 | 331 | }, |
| 332 | 332 | ); |
@@ -348,7 +348,7 @@ impl<'a> LowerCtx<'a> { |
| 348 | 348 | is_pointer: false, |
| 349 | 349 | runtime_dim_upper: vec![], |
| 350 | 350 | is_class: false, |
| 351 | | - logical_kind: None, |
| 351 | + logical_kind: None, |
| 352 | 352 | last_dim_assumed_size: false, |
| 353 | 353 | }, |
| 354 | 354 | ); |
@@ -671,7 +671,10 @@ fn collect_local_owner_modules(units: &[SpannedUnit]) -> HashSet<String> { |
| 671 | 671 | out |
| 672 | 672 | } |
| 673 | 673 | |
| 674 | | -fn bound_proc_target_is_local_to_owner(layout: &crate::sema::type_layout::TypeLayout, target: &str) -> bool { |
| 674 | +fn bound_proc_target_is_local_to_owner( |
| 675 | + layout: &crate::sema::type_layout::TypeLayout, |
| 676 | + target: &str, |
| 677 | +) -> bool { |
| 675 | 678 | let Some(owner) = layout.owner_module.as_ref() else { |
| 676 | 679 | return false; |
| 677 | 680 | }; |
@@ -688,8 +691,11 @@ fn emit_type_bound_lookup_thunks( |
| 688 | 691 | internal_funcs: &HashMap<String, u32>, |
| 689 | 692 | ) { |
| 690 | 693 | let local_modules = collect_local_owner_modules(units); |
| 691 | | - let available_targets: HashSet<String> = |
| 692 | | - module.functions.iter().map(|func| func.name.clone()).collect(); |
| 694 | + let available_targets: HashSet<String> = module |
| 695 | + .functions |
| 696 | + .iter() |
| 697 | + .map(|func| func.name.clone()) |
| 698 | + .collect(); |
| 693 | 699 | let mut layouts: Vec<_> = type_layouts |
| 694 | 700 | .layouts |
| 695 | 701 | .values() |
@@ -746,12 +752,12 @@ fn emit_type_bound_lookup_thunks( |
| 746 | 752 | } else { |
| 747 | 753 | None |
| 748 | 754 | }; |
| 749 | | - let target_is_external_inherited = |
| 750 | | - !layout.is_abstract |
| 751 | | - && !bound_proc_target_is_local_to_owner(layout, &bp.target_name); |
| 755 | + let target_is_external_inherited = !layout.is_abstract |
| 756 | + && !bound_proc_target_is_local_to_owner(layout, &bp.target_name); |
| 752 | 757 | let addr = if let Some(local_target) = local_target { |
| 753 | 758 | b.global_addr(&local_target, IrType::Int(IntWidth::I8)) |
| 754 | | - } else if available_targets.contains(&bp.target_name) || target_is_external_inherited |
| 759 | + } else if available_targets.contains(&bp.target_name) |
| 760 | + || target_is_external_inherited |
| 755 | 761 | { |
| 756 | 762 | b.global_addr(&bp.target_name, IrType::Int(IntWidth::I8)) |
| 757 | 763 | } else { |
@@ -1032,7 +1038,10 @@ fn function_hidden_result_abi( |
| 1032 | 1038 | // Without this, codegen emits `load %0; ret aggregate` and packs the |
| 1033 | 1039 | // 8 bytes into x0 — caller treats x0 as ptr and memcpy's from it, |
| 1034 | 1040 | // dereferencing the bit pattern of the complex value as an address. |
| 1035 | | - if matches!(return_type, Some(TypeSpec::Complex(_)) | Some(TypeSpec::DoubleComplex)) { |
| 1041 | + if matches!( |
| 1042 | + return_type, |
| 1043 | + Some(TypeSpec::Complex(_)) | Some(TypeSpec::DoubleComplex) |
| 1044 | + ) { |
| 1036 | 1045 | return HiddenResultAbi::ComplexBuffer; |
| 1037 | 1046 | } |
| 1038 | 1047 | HiddenResultAbi::None |
@@ -1396,8 +1405,7 @@ fn arg_uses_descriptor_from_decls(arg_name: &str, decls: &[crate::ast::decl::Spa |
| 1396 | 1405 | ); |
| 1397 | 1406 | return !is_deferred_char_scalar; |
| 1398 | 1407 | } |
| 1399 | | - if specs.is_none() |
| 1400 | | - && matches!(type_spec, TypeSpec::Class(_) | TypeSpec::ClassStar) |
| 1408 | + if specs.is_none() && matches!(type_spec, TypeSpec::Class(_) | TypeSpec::ClassStar) |
| 1401 | 1409 | { |
| 1402 | 1410 | // Scalar polymorphic dummies (`class(name)` and the |
| 1403 | 1411 | // unlimited `class(*)`) are passed by descriptor — |
@@ -1513,7 +1521,7 @@ fn procedure_scope_for_dummy_args_with_host( |
| 1513 | 1521 | && scope_matches_procedure_name(scope, proc_name) |
| 1514 | 1522 | && scope_has_linkable_parent(st, idx) |
| 1515 | 1523 | && scope.arg_order == expected_args) |
| 1516 | | - .then_some(idx) |
| 1524 | + .then_some(idx) |
| 1517 | 1525 | }); |
| 1518 | 1526 | if scoped.is_some() { |
| 1519 | 1527 | return scoped; |
@@ -1603,9 +1611,7 @@ fn smp_parent_interface_scope( |
| 1603 | 1611 | let proc_lc = proc_name.to_lowercase(); |
| 1604 | 1612 | st.all_scopes().iter().enumerate().find_map(|(idx, scope)| { |
| 1605 | 1613 | let matches_name = match &scope.kind { |
| 1606 | | - ScopeKind::Function(n) | ScopeKind::Subroutine(n) => { |
| 1607 | | - n.eq_ignore_ascii_case(&proc_lc) |
| 1608 | | - } |
| 1614 | + ScopeKind::Function(n) | ScopeKind::Subroutine(n) => n.eq_ignore_ascii_case(&proc_lc), |
| 1609 | 1615 | _ => return None, |
| 1610 | 1616 | }; |
| 1611 | 1617 | if !matches_name { |
@@ -1764,8 +1770,7 @@ fn smp_function_result_info( |
| 1764 | 1770 | } |
| 1765 | 1771 | if matches!( |
| 1766 | 1772 | sym.kind, |
| 1767 | | - crate::sema::symtab::SymbolKind::Variable |
| 1768 | | - | crate::sema::symtab::SymbolKind::Parameter |
| 1773 | + crate::sema::symtab::SymbolKind::Variable | crate::sema::symtab::SymbolKind::Parameter |
| 1769 | 1774 | ) { |
| 1770 | 1775 | let name = sym |
| 1771 | 1776 | .name |
@@ -1836,9 +1841,9 @@ fn try_synth_smp_function_unit( |
| 1836 | 1841 | Some(result_sym.attrs.array_spec.clone()) |
| 1837 | 1842 | }; |
| 1838 | 1843 | let result_char_len = match result_sym.type_info.as_ref() { |
| 1839 | | - Some(crate::sema::symtab::TypeInfo::Character { len: Some(n), .. }) => Some( |
| 1840 | | - crate::ast::decl::LenSpec::Expr(synth_int_literal_expr(*n)), |
| 1841 | | - ), |
| 1844 | + Some(crate::sema::symtab::TypeInfo::Character { len: Some(n), .. }) => { |
| 1845 | + Some(crate::ast::decl::LenSpec::Expr(synth_int_literal_expr(*n))) |
| 1846 | + } |
| 1842 | 1847 | Some(crate::sema::symtab::TypeInfo::Character { len: None, .. }) => { |
| 1843 | 1848 | Some(crate::ast::decl::LenSpec::Star) |
| 1844 | 1849 | } |
@@ -1928,9 +1933,9 @@ fn synthesize_smp_body_args_decls( |
| 1928 | 1933 | Some(sym.attrs.array_spec.clone()) |
| 1929 | 1934 | }; |
| 1930 | 1935 | let char_len = match sym.type_info.as_ref() { |
| 1931 | | - Some(crate::sema::symtab::TypeInfo::Character { len: Some(n), .. }) => Some( |
| 1932 | | - crate::ast::decl::LenSpec::Expr(synth_int_literal_expr(*n)), |
| 1933 | | - ), |
| 1936 | + Some(crate::sema::symtab::TypeInfo::Character { len: Some(n), .. }) => { |
| 1937 | + Some(crate::ast::decl::LenSpec::Expr(synth_int_literal_expr(*n))) |
| 1938 | + } |
| 1934 | 1939 | Some(crate::sema::symtab::TypeInfo::Character { len: None, .. }) => { |
| 1935 | 1940 | Some(crate::ast::decl::LenSpec::Star) |
| 1936 | 1941 | } |
@@ -1979,8 +1984,7 @@ fn arg_uses_descriptor_for_lowering( |
| 1979 | 1984 | .is_some_and(|type_info| { |
| 1980 | 1985 | matches!( |
| 1981 | 1986 | type_info, |
| 1982 | | - crate::sema::symtab::TypeInfo::Class(_) |
| 1983 | | - | crate::sema::symtab::TypeInfo::ClassStar |
| 1987 | + crate::sema::symtab::TypeInfo::Class(_) | crate::sema::symtab::TypeInfo::ClassStar |
| 1984 | 1988 | ) |
| 1985 | 1989 | }) |
| 1986 | 1990 | } |
@@ -2293,7 +2297,7 @@ fn install_common_locals( |
| 2293 | 2297 | is_pointer: false, |
| 2294 | 2298 | runtime_dim_upper: vec![], |
| 2295 | 2299 | is_class: false, |
| 2296 | | - logical_kind: None, |
| 2300 | + logical_kind: None, |
| 2297 | 2301 | last_dim_assumed_size: false, |
| 2298 | 2302 | }, |
| 2299 | 2303 | ); |
@@ -2349,7 +2353,7 @@ fn install_equivalence_locals( |
| 2349 | 2353 | name: String, |
| 2350 | 2354 | elem_ty: IrType, |
| 2351 | 2355 | dims: Vec<(i64, i64)>, |
| 2352 | | - byte_off: i64, // anchor offset within this variable |
| 2356 | + byte_off: i64, // anchor offset within this variable |
| 2353 | 2357 | byte_size: i64, // full byte span of this variable |
| 2354 | 2358 | } |
| 2355 | 2359 | let mut members: Vec<Member> = Vec::new(); |
@@ -2360,12 +2364,11 @@ fn install_equivalence_locals( |
| 2360 | 2364 | let ty = arg_type_from_decls(&key, decls, Some(st)); |
| 2361 | 2365 | let dims = arg_dims_from_decls(&key, decls, visible_param_consts, st); |
| 2362 | 2366 | let elem_size = ir_scalar_byte_size(&ty); |
| 2363 | | - let nelems: i64 = |
| 2364 | | - if dims.is_empty() { |
| 2365 | | - 1 |
| 2366 | | - } else { |
| 2367 | | - dims.iter().map(|(_, ext)| (*ext).max(0)).product() |
| 2368 | | - }; |
| 2367 | + let nelems: i64 = if dims.is_empty() { |
| 2368 | + 1 |
| 2369 | + } else { |
| 2370 | + dims.iter().map(|(_, ext)| (*ext).max(0)).product() |
| 2371 | + }; |
| 2369 | 2372 | let byte_size = elem_size * nelems.max(1); |
| 2370 | 2373 | members.push(Member { |
| 2371 | 2374 | name: key, |
@@ -2397,10 +2400,7 @@ fn install_equivalence_locals( |
| 2397 | 2400 | }; |
| 2398 | 2401 | match s { |
| 2399 | 2402 | Some(v) => { |
| 2400 | | - let (lo, ext) = dims |
| 2401 | | - .get(i) |
| 2402 | | - .copied() |
| 2403 | | - .unwrap_or((1, 1)); |
| 2403 | + let (lo, ext) = dims.get(i).copied().unwrap_or((1, 1)); |
| 2404 | 2404 | linear += (v - lo) * stride; |
| 2405 | 2405 | stride *= ext.max(1); |
| 2406 | 2406 | } |
@@ -2480,7 +2480,7 @@ fn install_equivalence_locals( |
| 2480 | 2480 | is_pointer: false, |
| 2481 | 2481 | runtime_dim_upper: vec![None; m.dims.len()], |
| 2482 | 2482 | is_class: false, |
| 2483 | | - logical_kind: None, |
| 2483 | + logical_kind: None, |
| 2484 | 2484 | last_dim_assumed_size: false, |
| 2485 | 2485 | }, |
| 2486 | 2486 | ); |
@@ -2879,14 +2879,8 @@ fn collect_host_refs_stmt( |
| 2879 | 2879 | Stmt::Return { value: Some(e) } | Stmt::ComputedGoto { selector: e, .. } => { |
| 2880 | 2880 | collect_host_refs_expr(e, host_names, sub_locals, refs); |
| 2881 | 2881 | } |
| 2882 | | - Stmt::Stop { |
| 2883 | | - code: Some(e), |
| 2884 | | - .. |
| 2885 | | - } |
| 2886 | | - | Stmt::ErrorStop { |
| 2887 | | - code: Some(e), |
| 2888 | | - .. |
| 2889 | | - } |
| 2882 | + Stmt::Stop { code: Some(e), .. } |
| 2883 | + | Stmt::ErrorStop { code: Some(e), .. } |
| 2890 | 2884 | | Stmt::ArithmeticIf { expr: e, .. } => { |
| 2891 | 2885 | collect_host_refs_expr(e, host_names, sub_locals, refs); |
| 2892 | 2886 | } |
@@ -3082,7 +3076,7 @@ fn collect_implicit_locals( |
| 3082 | 3076 | is_pointer: false, |
| 3083 | 3077 | runtime_dim_upper: vec![], |
| 3084 | 3078 | is_class: false, |
| 3085 | | - logical_kind: None, |
| 3079 | + logical_kind: None, |
| 3086 | 3080 | last_dim_assumed_size: false, |
| 3087 | 3081 | }, |
| 3088 | 3082 | ); |
@@ -3702,7 +3696,7 @@ fn collect_module_globals( |
| 3702 | 3696 | derived_type: derived_type_name.clone(), |
| 3703 | 3697 | char_kind: global_char_kind.clone(), |
| 3704 | 3698 | external: false, |
| 3705 | | - private: false, |
| 3699 | + private: false, |
| 3706 | 3700 | }, |
| 3707 | 3701 | ); |
| 3708 | 3702 | continue; |
@@ -3711,7 +3705,12 @@ fn collect_module_globals( |
| 3711 | 3705 | if let Some(len) = char_len { |
| 3712 | 3706 | let storage_ty = fixed_char_storage_ir_type(len); |
| 3713 | 3707 | let init = init_expr.and_then(|e| { |
| 3714 | | - eval_const_char_global_init(e, ¶m_consts, ¶m_char_consts, len) |
| 3708 | + eval_const_char_global_init( |
| 3709 | + e, |
| 3710 | + ¶m_consts, |
| 3711 | + ¶m_char_consts, |
| 3712 | + len, |
| 3713 | + ) |
| 3715 | 3714 | }); |
| 3716 | 3715 | module.add_global(Global { |
| 3717 | 3716 | name: symbol.clone(), |
@@ -3730,7 +3729,7 @@ fn collect_module_globals( |
| 3730 | 3729 | derived_type: None, |
| 3731 | 3730 | char_kind: CharKind::Fixed(len), |
| 3732 | 3731 | external: false, |
| 3733 | | - private: false, |
| 3732 | + private: false, |
| 3734 | 3733 | }, |
| 3735 | 3734 | ); |
| 3736 | 3735 | continue; |
@@ -3777,7 +3776,7 @@ fn collect_module_globals( |
| 3777 | 3776 | derived_type: Some(type_name.clone()), |
| 3778 | 3777 | char_kind: CharKind::None, |
| 3779 | 3778 | external: false, |
| 3780 | | - private: false, |
| 3779 | + private: false, |
| 3781 | 3780 | }, |
| 3782 | 3781 | ); |
| 3783 | 3782 | continue; |
@@ -4066,16 +4065,15 @@ fn lower_unit( |
| 4066 | 4065 | ); |
| 4067 | 4066 | ctx.proc_scope_id = { |
| 4068 | 4067 | let raw_name = name.as_deref(); |
| 4069 | | - st.all_scopes() |
| 4070 | | - .iter() |
| 4071 | | - .enumerate() |
| 4072 | | - .find_map(|(idx, scope)| match (&scope.kind, raw_name) { |
| 4068 | + st.all_scopes().iter().enumerate().find_map(|(idx, scope)| { |
| 4069 | + match (&scope.kind, raw_name) { |
| 4073 | 4070 | (crate::sema::symtab::ScopeKind::Program(scope_name), Some(n)) => { |
| 4074 | 4071 | scope_name.eq_ignore_ascii_case(n).then_some(idx) |
| 4075 | 4072 | } |
| 4076 | 4073 | (crate::sema::symtab::ScopeKind::Program(_), None) => Some(idx), |
| 4077 | 4074 | _ => None, |
| 4078 | | - }) |
| 4075 | + } |
| 4076 | + }) |
| 4079 | 4077 | }; |
| 4080 | 4078 | let mut pending_globals: Vec<PendingGlobal> = Vec::new(); |
| 4081 | 4079 | |
@@ -4086,7 +4084,13 @@ fn lower_unit( |
| 4086 | 4084 | { |
| 4087 | 4085 | let mut b = FuncBuilder::new(&mut func); |
| 4088 | 4086 | install_common_locals(&mut b, &mut ctx.locals, decls); |
| 4089 | | - install_equivalence_locals(&mut b, &mut ctx.locals, decls, &visible_param_consts, st); |
| 4087 | + install_equivalence_locals( |
| 4088 | + &mut b, |
| 4089 | + &mut ctx.locals, |
| 4090 | + decls, |
| 4091 | + &visible_param_consts, |
| 4092 | + st, |
| 4093 | + ); |
| 4090 | 4094 | alloc_decls( |
| 4091 | 4095 | &mut b, |
| 4092 | 4096 | &mut ctx.locals, |
@@ -4394,12 +4398,8 @@ fn lower_unit( |
| 4394 | 4398 | b.store(*pid, slot); |
| 4395 | 4399 | ctx.insert_scalar(pname.clone(), slot, elem_ty.clone()); |
| 4396 | 4400 | } else { |
| 4397 | | - let uses_descriptor = arg_uses_descriptor_for_lowering( |
| 4398 | | - pname, |
| 4399 | | - decls, |
| 4400 | | - st, |
| 4401 | | - proc_scope_id, |
| 4402 | | - ); |
| 4401 | + let uses_descriptor = |
| 4402 | + arg_uses_descriptor_for_lowering(pname, decls, st, proc_scope_id); |
| 4403 | 4403 | let uses_string_descriptor = |
| 4404 | 4404 | arg_uses_string_descriptor_from_decls(pname, decls); |
| 4405 | 4405 | let dt_name = arg_derived_type_name(pname, decls); |
@@ -4442,7 +4442,9 @@ fn lower_unit( |
| 4442 | 4442 | Some(&visible_param_consts), |
| 4443 | 4443 | st, |
| 4444 | 4444 | ), |
| 4445 | | - last_dim_assumed_size: arg_last_dim_assumed_size_from_decls(pname, decls), |
| 4445 | + last_dim_assumed_size: arg_last_dim_assumed_size_from_decls( |
| 4446 | + pname, decls, |
| 4447 | + ), |
| 4446 | 4448 | }; |
| 4447 | 4449 | ctx.locals.insert(pname.clone(), info); |
| 4448 | 4450 | if decl_is_optional(pname, decls) { |
@@ -4515,7 +4517,13 @@ fn lower_unit( |
| 4515 | 4517 | ); |
| 4516 | 4518 | |
| 4517 | 4519 | install_common_locals(&mut b, &mut ctx.locals, decls); |
| 4518 | | - install_equivalence_locals(&mut b, &mut ctx.locals, decls, &visible_param_consts, st); |
| 4520 | + install_equivalence_locals( |
| 4521 | + &mut b, |
| 4522 | + &mut ctx.locals, |
| 4523 | + decls, |
| 4524 | + &visible_param_consts, |
| 4525 | + st, |
| 4526 | + ); |
| 4519 | 4527 | // Install host-association by_ref locals before alloc_decls |
| 4520 | 4528 | // so any same-named callee local (shouldn't occur per F |
| 4521 | 4529 | // scoping rules) is short-circuited, and so init_decls has |
@@ -4650,18 +4658,24 @@ fn lower_unit( |
| 4650 | 4658 | HiddenResultAbi::ArrayDescriptor => 384, |
| 4651 | 4659 | HiddenResultAbi::StringDescriptor => 32, |
| 4652 | 4660 | HiddenResultAbi::DerivedAggregate => { |
| 4653 | | - let result_name = result |
| 4654 | | - .as_deref() |
| 4655 | | - .unwrap_or(name.as_str()) |
| 4656 | | - .to_lowercase(); |
| 4661 | + let result_name = result.as_deref().unwrap_or(name.as_str()).to_lowercase(); |
| 4657 | 4662 | derived_type_name_for_result_var(return_type, &result_name, decls) |
| 4658 | | - .and_then(|dt_name| type_layouts.get(&dt_name).map(|layout| layout.size.max(1) as u64)) |
| 4663 | + .and_then(|dt_name| { |
| 4664 | + type_layouts |
| 4665 | + .get(&dt_name) |
| 4666 | + .map(|layout| layout.size.max(1) as u64) |
| 4667 | + }) |
| 4659 | 4668 | .unwrap_or(8) |
| 4660 | 4669 | } |
| 4661 | 4670 | HiddenResultAbi::ComplexBuffer => { |
| 4662 | 4671 | // 8 bytes for complex(sp), 16 for complex(dp). |
| 4663 | | - let kind = complex_result_kind(name, result, return_type.as_ref(), decls, st); |
| 4664 | | - if kind == 8 { 16 } else { 8 } |
| 4672 | + let kind = |
| 4673 | + complex_result_kind(name, result, return_type.as_ref(), decls, st); |
| 4674 | + if kind == 8 { |
| 4675 | + 16 |
| 4676 | + } else { |
| 4677 | + 8 |
| 4678 | + } |
| 4665 | 4679 | } |
| 4666 | 4680 | HiddenResultAbi::None => 0, |
| 4667 | 4681 | }; |
@@ -4867,12 +4881,8 @@ fn lower_unit( |
| 4867 | 4881 | b.store(*pid, slot); |
| 4868 | 4882 | ctx.insert_scalar(pname.clone(), slot, elem_ty.clone()); |
| 4869 | 4883 | } else { |
| 4870 | | - let uses_descriptor = arg_uses_descriptor_for_lowering( |
| 4871 | | - pname, |
| 4872 | | - decls, |
| 4873 | | - st, |
| 4874 | | - proc_scope_id, |
| 4875 | | - ); |
| 4884 | + let uses_descriptor = |
| 4885 | + arg_uses_descriptor_for_lowering(pname, decls, st, proc_scope_id); |
| 4876 | 4886 | let uses_string_descriptor = |
| 4877 | 4887 | arg_uses_string_descriptor_from_decls(pname, decls); |
| 4878 | 4888 | let dt_name = arg_derived_type_name(pname, decls); |
@@ -4916,7 +4926,9 @@ fn lower_unit( |
| 4916 | 4926 | Some(&visible_param_consts), |
| 4917 | 4927 | st, |
| 4918 | 4928 | ), |
| 4919 | | - last_dim_assumed_size: arg_last_dim_assumed_size_from_decls(pname, decls), |
| 4929 | + last_dim_assumed_size: arg_last_dim_assumed_size_from_decls( |
| 4930 | + pname, decls, |
| 4931 | + ), |
| 4920 | 4932 | }, |
| 4921 | 4933 | ); |
| 4922 | 4934 | if decl_is_optional(pname, decls) { |
@@ -5009,17 +5021,14 @@ fn lower_unit( |
| 5009 | 5021 | is_pointer: false, |
| 5010 | 5022 | runtime_dim_upper: vec![], |
| 5011 | 5023 | is_class: false, |
| 5012 | | - logical_kind: None, |
| 5024 | + logical_kind: None, |
| 5013 | 5025 | last_dim_assumed_size: false, |
| 5014 | 5026 | }, |
| 5015 | 5027 | ); |
| 5016 | 5028 | } else if hidden_result_abi == HiddenResultAbi::DerivedAggregate { |
| 5017 | | - let dt_name = derived_type_name_for_result_var( |
| 5018 | | - return_type, |
| 5019 | | - &result_name, |
| 5020 | | - decls, |
| 5021 | | - ) |
| 5022 | | - .expect("derived hidden-result function missing result type"); |
| 5029 | + let dt_name = |
| 5030 | + derived_type_name_for_result_var(return_type, &result_name, decls) |
| 5031 | + .expect("derived hidden-result function missing result type"); |
| 5023 | 5032 | if let Some(layout) = type_layouts.get(&dt_name) { |
| 5024 | 5033 | if derived_layout_needs_runtime_initialization(layout, type_layouts) { |
| 5025 | 5034 | initialize_derived_storage(&mut b, ValueId(0), layout, type_layouts); |
@@ -5040,7 +5049,7 @@ fn lower_unit( |
| 5040 | 5049 | is_pointer: false, |
| 5041 | 5050 | runtime_dim_upper: vec![], |
| 5042 | 5051 | is_class: false, |
| 5043 | | - logical_kind: None, |
| 5052 | + logical_kind: None, |
| 5044 | 5053 | last_dim_assumed_size: false, |
| 5045 | 5054 | }, |
| 5046 | 5055 | ); |
@@ -5063,9 +5072,12 @@ fn lower_unit( |
| 5063 | 5072 | // produces the typed view without changing the runtime |
| 5064 | 5073 | // address. |
| 5065 | 5074 | let kind = complex_result_kind(name, result, return_type.as_ref(), decls, st); |
| 5066 | | - let fw = if kind == 8 { FloatWidth::F64 } else { FloatWidth::F32 }; |
| 5067 | | - let cplx_ty = |
| 5068 | | - IrType::Array(Box::new(IrType::Float(fw)), 2); |
| 5075 | + let fw = if kind == 8 { |
| 5076 | + FloatWidth::F64 |
| 5077 | + } else { |
| 5078 | + FloatWidth::F32 |
| 5079 | + }; |
| 5080 | + let cplx_ty = IrType::Array(Box::new(IrType::Float(fw)), 2); |
| 5069 | 5081 | let zero_off = b.const_i64(0); |
| 5070 | 5082 | let typed_addr = b.gep(ValueId(0), vec![zero_off], cplx_ty.clone()); |
| 5071 | 5083 | ctx.locals.insert( |
@@ -5126,7 +5138,7 @@ fn lower_unit( |
| 5126 | 5138 | is_pointer: true, |
| 5127 | 5139 | runtime_dim_upper: vec![], |
| 5128 | 5140 | is_class: false, |
| 5129 | | - logical_kind: None, |
| 5141 | + logical_kind: None, |
| 5130 | 5142 | last_dim_assumed_size: false, |
| 5131 | 5143 | }, |
| 5132 | 5144 | ); |
@@ -5170,7 +5182,7 @@ fn lower_unit( |
| 5170 | 5182 | is_pointer: false, |
| 5171 | 5183 | runtime_dim_upper: vec![], |
| 5172 | 5184 | is_class: false, |
| 5173 | | - logical_kind: None, |
| 5185 | + logical_kind: None, |
| 5174 | 5186 | last_dim_assumed_size: false, |
| 5175 | 5187 | }, |
| 5176 | 5188 | ); |
@@ -5184,7 +5196,13 @@ fn lower_unit( |
| 5184 | 5196 | } |
| 5185 | 5197 | |
| 5186 | 5198 | install_common_locals(&mut b, &mut ctx.locals, decls); |
| 5187 | | - install_equivalence_locals(&mut b, &mut ctx.locals, decls, &visible_param_consts, st); |
| 5199 | + install_equivalence_locals( |
| 5200 | + &mut b, |
| 5201 | + &mut ctx.locals, |
| 5202 | + decls, |
| 5203 | + &visible_param_consts, |
| 5204 | + st, |
| 5205 | + ); |
| 5188 | 5206 | install_host_ref_locals(&mut b, &mut ctx.locals, &host_ref_infos); |
| 5189 | 5207 | alloc_decls( |
| 5190 | 5208 | &mut b, |
@@ -5257,7 +5275,9 @@ fn lower_unit( |
| 5257 | 5275 | derived_type_name_for_result_var(return_type, &result_name, decls); |
| 5258 | 5276 | let skip = if matches!( |
| 5259 | 5277 | hidden_result_abi, |
| 5260 | | - HiddenResultAbi::ArrayDescriptor | HiddenResultAbi::DerivedAggregate | HiddenResultAbi::ComplexBuffer |
| 5278 | + HiddenResultAbi::ArrayDescriptor |
| 5279 | + | HiddenResultAbi::DerivedAggregate |
| 5280 | + | HiddenResultAbi::ComplexBuffer |
| 5261 | 5281 | ) { |
| 5262 | 5282 | Some(ValueId(0)) |
| 5263 | 5283 | } else if !result_is_pointer && derived_result_type.is_some() { |
@@ -5456,16 +5476,18 @@ fn lower_unit( |
| 5456 | 5476 | } else { |
| 5457 | 5477 | None |
| 5458 | 5478 | }; |
| 5459 | | - let submod_scope = st.all_scopes().iter().enumerate().find_map(|(idx, scope)| { |
| 5460 | | - match &scope.kind { |
| 5461 | | - crate::sema::symtab::ScopeKind::Submodule(scope_name) |
| 5462 | | - if scope_name.eq_ignore_ascii_case(submodule_name) => |
| 5463 | | - { |
| 5464 | | - Some(idx) |
| 5465 | | - } |
| 5466 | | - _ => None, |
| 5467 | | - } |
| 5468 | | - }); |
| 5479 | + let submod_scope = |
| 5480 | + st.all_scopes() |
| 5481 | + .iter() |
| 5482 | + .enumerate() |
| 5483 | + .find_map(|(idx, scope)| match &scope.kind { |
| 5484 | + crate::sema::symtab::ScopeKind::Submodule(scope_name) |
| 5485 | + if scope_name.eq_ignore_ascii_case(submodule_name) => |
| 5486 | + { |
| 5487 | + Some(idx) |
| 5488 | + } |
| 5489 | + _ => None, |
| 5490 | + }); |
| 5469 | 5491 | lower_unit( |
| 5470 | 5492 | module, |
| 5471 | 5493 | sub, |
@@ -5718,7 +5740,12 @@ fn collect_decl_param_char_consts( |
| 5718 | 5740 | .any(|a| matches!(a, crate::ast::decl::Attribute::Parameter)) => |
| 5719 | 5741 | { |
| 5720 | 5742 | for entity in entities { |
| 5721 | | - install_param_char_component_defaults(type_spec, entity, type_layouts, &mut out); |
| 5743 | + install_param_char_component_defaults( |
| 5744 | + type_spec, |
| 5745 | + entity, |
| 5746 | + type_layouts, |
| 5747 | + &mut out, |
| 5748 | + ); |
| 5722 | 5749 | if let Some(init) = entity.init.as_ref() { |
| 5723 | 5750 | if let Some(bytes) = eval_const_char_bytes(init, param_consts, &out) { |
| 5724 | 5751 | out.insert(entity.name.to_lowercase(), bytes); |
@@ -5792,42 +5819,42 @@ fn declared_char_len( |
| 5792 | 5819 | Some(crate::ast::decl::LenSpec::Expr(e)) => { |
| 5793 | 5820 | eval_const_int_in_scope_or_any_scope(e, param_consts, st) |
| 5794 | 5821 | } |
| 5795 | | - Some(crate::ast::decl::LenSpec::Star) => init_expr |
| 5796 | | - .and_then(|expr| { |
| 5797 | | - eval_const_char_bytes(expr, param_consts, param_char_consts) |
| 5798 | | - .map(|bytes| bytes.len() as i64) |
| 5799 | | - .or_else(|| { |
| 5800 | | - collect_const_char_array_elems(expr, param_consts, param_char_consts) |
| 5801 | | - .map(|elems| { |
| 5802 | | - elems |
| 5803 | | - .iter() |
| 5804 | | - .map(|elem| elem.len() as i64) |
| 5805 | | - .max() |
| 5806 | | - .unwrap_or(0) |
| 5807 | | - }) |
| 5808 | | - }) |
| 5809 | | - .or_else(|| { |
| 5810 | | - // Fallback: when the init is a Name that |
| 5811 | | - // refers to another character parameter |
| 5812 | | - // visible via host/use association (e.g. |
| 5813 | | - // `character(*), parameter :: vtype = type_rsp` |
| 5814 | | - // where type_rsp lives in the parent module), |
| 5815 | | - // extract the length from the symbol table. |
| 5816 | | - if let crate::ast::expr::Expr::Name { name } = &expr.node { |
| 5817 | | - let key = name.to_lowercase(); |
| 5818 | | - if let Some(sym) = st.find_symbol_any_scope(&key) { |
| 5819 | | - if let Some(crate::sema::symtab::TypeInfo::Character { |
| 5820 | | - len: Some(n), |
| 5821 | | - .. |
| 5822 | | - }) = &sym.type_info |
| 5823 | | - { |
| 5824 | | - return Some(*n); |
| 5825 | | - } |
| 5822 | + Some(crate::ast::decl::LenSpec::Star) => init_expr.and_then(|expr| { |
| 5823 | + eval_const_char_bytes(expr, param_consts, param_char_consts) |
| 5824 | + .map(|bytes| bytes.len() as i64) |
| 5825 | + .or_else(|| { |
| 5826 | + collect_const_char_array_elems(expr, param_consts, param_char_consts).map( |
| 5827 | + |elems| { |
| 5828 | + elems |
| 5829 | + .iter() |
| 5830 | + .map(|elem| elem.len() as i64) |
| 5831 | + .max() |
| 5832 | + .unwrap_or(0) |
| 5833 | + }, |
| 5834 | + ) |
| 5835 | + }) |
| 5836 | + .or_else(|| { |
| 5837 | + // Fallback: when the init is a Name that |
| 5838 | + // refers to another character parameter |
| 5839 | + // visible via host/use association (e.g. |
| 5840 | + // `character(*), parameter :: vtype = type_rsp` |
| 5841 | + // where type_rsp lives in the parent module), |
| 5842 | + // extract the length from the symbol table. |
| 5843 | + if let crate::ast::expr::Expr::Name { name } = &expr.node { |
| 5844 | + let key = name.to_lowercase(); |
| 5845 | + if let Some(sym) = st.find_symbol_any_scope(&key) { |
| 5846 | + if let Some(crate::sema::symtab::TypeInfo::Character { |
| 5847 | + len: Some(n), |
| 5848 | + .. |
| 5849 | + }) = &sym.type_info |
| 5850 | + { |
| 5851 | + return Some(*n); |
| 5826 | 5852 | } |
| 5827 | 5853 | } |
| 5828 | | - None |
| 5829 | | - }) |
| 5830 | | - }), |
| 5854 | + } |
| 5855 | + None |
| 5856 | + }) |
| 5857 | + }), |
| 5831 | 5858 | Some(crate::ast::decl::LenSpec::Colon) => None, |
| 5832 | 5859 | None => Some(1), |
| 5833 | 5860 | }, |
@@ -5894,7 +5921,11 @@ fn collect_const_char_array_elems( |
| 5894 | 5921 | if let Expr::Name { name } = &callee.node { |
| 5895 | 5922 | if name.eq_ignore_ascii_case("reshape") && !args.is_empty() { |
| 5896 | 5923 | if let crate::ast::expr::SectionSubscript::Element(src) = &args[0].value { |
| 5897 | | - return collect_const_char_array_elems(src, param_consts, param_char_consts); |
| 5924 | + return collect_const_char_array_elems( |
| 5925 | + src, |
| 5926 | + param_consts, |
| 5927 | + param_char_consts, |
| 5928 | + ); |
| 5898 | 5929 | } |
| 5899 | 5930 | } |
| 5900 | 5931 | } |
@@ -5914,7 +5945,11 @@ fn collect_ac_char_value( |
| 5914 | 5945 | |
| 5915 | 5946 | match value { |
| 5916 | 5947 | AcValue::Expr(expr) => { |
| 5917 | | - out.push(eval_const_char_bytes(expr, param_consts, param_char_consts)?); |
| 5948 | + out.push(eval_const_char_bytes( |
| 5949 | + expr, |
| 5950 | + param_consts, |
| 5951 | + param_char_consts, |
| 5952 | + )?); |
| 5918 | 5953 | Some(()) |
| 5919 | 5954 | } |
| 5920 | 5955 | AcValue::ImpliedDo(ido) => { |
@@ -6540,18 +6575,9 @@ fn eval_const_scalar( |
| 6540 | 6575 | // without folding here the const ends up at runtime-zero |
| 6541 | 6576 | // because there is no module-level evaluator emitting |
| 6542 | 6577 | // the value into storage for non-trivial initializers. |
| 6543 | | - "sqrt" | "dsqrt" |
| 6544 | | - | "exp" | "dexp" |
| 6545 | | - | "log" | "dlog" |
| 6546 | | - | "log10" | "dlog10" |
| 6547 | | - | "sin" | "dsin" |
| 6548 | | - | "cos" | "dcos" |
| 6549 | | - | "tan" | "dtan" |
| 6550 | | - | "asin" | "dasin" |
| 6551 | | - | "acos" | "dacos" |
| 6552 | | - | "atan" | "datan" |
| 6553 | | - | "sinh" | "dsinh" |
| 6554 | | - | "cosh" | "dcosh" |
| 6578 | + "sqrt" | "dsqrt" | "exp" | "dexp" | "log" | "dlog" | "log10" | "dlog10" |
| 6579 | + | "sin" | "dsin" | "cos" | "dcos" | "tan" | "dtan" | "asin" | "dasin" |
| 6580 | + | "acos" | "dacos" | "atan" | "datan" | "sinh" | "dsinh" | "cosh" | "dcosh" |
| 6555 | 6581 | | "tanh" | "dtanh" => { |
| 6556 | 6582 | let v = first_arg?.to_float(); |
| 6557 | 6583 | let r = match key.as_str() { |
@@ -6609,7 +6635,12 @@ fn eval_const_scalar( |
| 6609 | 6635 | // suffix (1.0d0 → 8). Integer literal → 4. Named |
| 6610 | 6636 | // constant — look up in param_consts to recover |
| 6611 | 6637 | // its kind by value range. |
| 6612 | | - enum Kind { F32, F64, I32, I64 } |
| 6638 | + enum Kind { |
| 6639 | + F32, |
| 6640 | + F64, |
| 6641 | + I32, |
| 6642 | + I64, |
| 6643 | + } |
| 6613 | 6644 | let kind = match &e.node { |
| 6614 | 6645 | Expr::RealLiteral { text, kind, .. } => { |
| 6615 | 6646 | let lower = text.to_ascii_lowercase(); |
@@ -6639,7 +6670,9 @@ fn eval_const_scalar( |
| 6639 | 6670 | match (key.as_str(), kind) { |
| 6640 | 6671 | ("epsilon", Kind::F32) => Some(ConstScalar::Float(f32::EPSILON as f64)), |
| 6641 | 6672 | ("epsilon", Kind::F64) => Some(ConstScalar::Float(f64::EPSILON)), |
| 6642 | | - ("tiny", Kind::F32) => Some(ConstScalar::Float(f32::MIN_POSITIVE as f64)), |
| 6673 | + ("tiny", Kind::F32) => { |
| 6674 | + Some(ConstScalar::Float(f32::MIN_POSITIVE as f64)) |
| 6675 | + } |
| 6643 | 6676 | ("tiny", Kind::F64) => Some(ConstScalar::Float(f64::MIN_POSITIVE)), |
| 6644 | 6677 | ("huge", Kind::F32) => Some(ConstScalar::Float(f32::MAX as f64)), |
| 6645 | 6678 | ("huge", Kind::F64) => Some(ConstScalar::Float(f64::MAX)), |
@@ -6759,12 +6792,8 @@ fn collect_decl_param_consts_with_scope( |
| 6759 | 6792 | continue; |
| 6760 | 6793 | } |
| 6761 | 6794 | if let Some(init) = &entity.init { |
| 6762 | | - if let Some(val) = eval_const_scalar_with_decl_scope( |
| 6763 | | - init, |
| 6764 | | - decls, |
| 6765 | | - ¶m_consts, |
| 6766 | | - st, |
| 6767 | | - ) |
| 6795 | + if let Some(val) = |
| 6796 | + eval_const_scalar_with_decl_scope(init, decls, ¶m_consts, st) |
| 6768 | 6797 | { |
| 6769 | 6798 | param_consts.insert(entity.name.to_lowercase(), val); |
| 6770 | 6799 | } |
@@ -6773,12 +6802,8 @@ fn collect_decl_param_consts_with_scope( |
| 6773 | 6802 | } |
| 6774 | 6803 | Decl::ParameterStmt { pairs } => { |
| 6775 | 6804 | for (name, expr) in pairs { |
| 6776 | | - if let Some(val) = eval_const_scalar_with_decl_scope( |
| 6777 | | - expr, |
| 6778 | | - decls, |
| 6779 | | - ¶m_consts, |
| 6780 | | - st, |
| 6781 | | - ) |
| 6805 | + if let Some(val) = |
| 6806 | + eval_const_scalar_with_decl_scope(expr, decls, ¶m_consts, st) |
| 6782 | 6807 | { |
| 6783 | 6808 | param_consts.insert(name.to_lowercase(), val); |
| 6784 | 6809 | } |
@@ -6802,7 +6827,10 @@ fn declared_type_spec_for_name<'a>( |
| 6802 | 6827 | .. |
| 6803 | 6828 | } = &decl.node |
| 6804 | 6829 | { |
| 6805 | | - if entities.iter().any(|entity| entity.name.to_lowercase() == key) { |
| 6830 | + if entities |
| 6831 | + .iter() |
| 6832 | + .any(|entity| entity.name.to_lowercase() == key) |
| 6833 | + { |
| 6806 | 6834 | return Some(type_spec); |
| 6807 | 6835 | } |
| 6808 | 6836 | } |
@@ -6874,7 +6902,7 @@ fn install_host_param_consts( |
| 6874 | 6902 | is_pointer: false, |
| 6875 | 6903 | runtime_dim_upper: vec![], |
| 6876 | 6904 | is_class: false, |
| 6877 | | - logical_kind: None, |
| 6905 | + logical_kind: None, |
| 6878 | 6906 | last_dim_assumed_size: false, |
| 6879 | 6907 | }, |
| 6880 | 6908 | ); |
@@ -7748,7 +7776,7 @@ fn install_globals_as_locals_in( |
| 7748 | 7776 | is_pointer: false, |
| 7749 | 7777 | runtime_dim_upper: vec![], |
| 7750 | 7778 | is_class: false, |
| 7751 | | - logical_kind: None, |
| 7779 | + logical_kind: None, |
| 7752 | 7780 | last_dim_assumed_size: false, |
| 7753 | 7781 | }, |
| 7754 | 7782 | ); |
@@ -7772,7 +7800,7 @@ fn install_globals_as_locals_in( |
| 7772 | 7800 | is_pointer: false, |
| 7773 | 7801 | runtime_dim_upper: vec![], |
| 7774 | 7802 | is_class: false, |
| 7775 | | - logical_kind: None, |
| 7803 | + logical_kind: None, |
| 7776 | 7804 | last_dim_assumed_size: false, |
| 7777 | 7805 | }, |
| 7778 | 7806 | ); |
@@ -7952,7 +7980,7 @@ fn alloc_decls( |
| 7952 | 7980 | .map(|specs| vec![None; specs.len()]) |
| 7953 | 7981 | .unwrap_or_default(), |
| 7954 | 7982 | is_class: false, |
| 7955 | | - logical_kind: None, |
| 7983 | + logical_kind: None, |
| 7956 | 7984 | last_dim_assumed_size: false, |
| 7957 | 7985 | }, |
| 7958 | 7986 | ); |
@@ -7989,14 +8017,16 @@ fn alloc_decls( |
| 7989 | 8017 | is_pointer: true, |
| 7990 | 8018 | runtime_dim_upper: vec![], |
| 7991 | 8019 | is_class: false, |
| 7992 | | - logical_kind: None, |
| 8020 | + logical_kind: None, |
| 7993 | 8021 | last_dim_assumed_size: false, |
| 7994 | 8022 | }, |
| 7995 | 8023 | ); |
| 7996 | 8024 | continue; |
| 7997 | 8025 | } |
| 7998 | 8026 | } |
| 7999 | | - if is_pointer_attr && matches!(type_spec, TypeSpec::Class(_)) && array_spec.is_none() |
| 8027 | + if is_pointer_attr |
| 8028 | + && matches!(type_spec, TypeSpec::Class(_)) |
| 8029 | + && array_spec.is_none() |
| 8000 | 8030 | { |
| 8001 | 8031 | if let TypeSpec::Class(ref type_name) = type_spec { |
| 8002 | 8032 | let desc_ty = IrType::Array(Box::new(IrType::Int(IntWidth::I8)), 384); |
@@ -8058,7 +8088,7 @@ fn alloc_decls( |
| 8058 | 8088 | is_pointer: is_pointer_attr, |
| 8059 | 8089 | runtime_dim_upper: vec![], |
| 8060 | 8090 | is_class: false, |
| 8061 | | - logical_kind: None, |
| 8091 | + logical_kind: None, |
| 8062 | 8092 | last_dim_assumed_size: false, |
| 8063 | 8093 | }, |
| 8064 | 8094 | ); |
@@ -8069,12 +8099,8 @@ fn alloc_decls( |
| 8069 | 8099 | if (!matches!(type_spec, TypeSpec::Character(_)) || char_len.is_some()) |
| 8070 | 8100 | && array_spec_has_runtime_bounds(specs, ¶m_consts, Some(st)) |
| 8071 | 8101 | { |
| 8072 | | - let dims = extract_array_dims_with_init( |
| 8073 | | - specs, |
| 8074 | | - init_expr, |
| 8075 | | - ¶m_consts, |
| 8076 | | - Some(st), |
| 8077 | | - ); |
| 8102 | + let dims = |
| 8103 | + extract_array_dims_with_init(specs, init_expr, ¶m_consts, Some(st)); |
| 8078 | 8104 | let (array_elem_ty, array_derived_type, array_char_kind) = if matches!( |
| 8079 | 8105 | type_spec, |
| 8080 | 8106 | TypeSpec::Character(_) |
@@ -8230,7 +8256,7 @@ fn alloc_decls( |
| 8230 | 8256 | is_pointer: false, |
| 8231 | 8257 | runtime_dim_upper: vec![], |
| 8232 | 8258 | is_class: false, |
| 8233 | | - logical_kind: None, |
| 8259 | + logical_kind: None, |
| 8234 | 8260 | last_dim_assumed_size: false, |
| 8235 | 8261 | }, |
| 8236 | 8262 | ); |
@@ -8247,12 +8273,8 @@ fn alloc_decls( |
| 8247 | 8273 | // which is exactly how local `character(len=N), |
| 8248 | 8274 | // parameter :: builtins(...)` ended up crashing fortsh |
| 8249 | 8275 | // `type`/`command` with `0x202020...` memmove faults. |
| 8250 | | - let dims = extract_array_dims_with_init( |
| 8251 | | - specs, |
| 8252 | | - init_expr, |
| 8253 | | - ¶m_consts, |
| 8254 | | - Some(st), |
| 8255 | | - ); |
| 8276 | + let dims = |
| 8277 | + extract_array_dims_with_init(specs, init_expr, ¶m_consts, Some(st)); |
| 8256 | 8278 | let total_size: i64 = dims.iter().map(|(_, size)| *size).product(); |
| 8257 | 8279 | let elem_ty = fixed_char_storage_ir_type(len); |
| 8258 | 8280 | let elem_bytes = ir_scalar_byte_size(&elem_ty); |
@@ -8300,7 +8322,7 @@ fn alloc_decls( |
| 8300 | 8322 | is_pointer: false, |
| 8301 | 8323 | runtime_dim_upper: vec![], |
| 8302 | 8324 | is_class: false, |
| 8303 | | - logical_kind: None, |
| 8325 | + logical_kind: None, |
| 8304 | 8326 | last_dim_assumed_size: false, |
| 8305 | 8327 | }, |
| 8306 | 8328 | ); |
@@ -8328,7 +8350,7 @@ fn alloc_decls( |
| 8328 | 8350 | is_pointer: false, |
| 8329 | 8351 | runtime_dim_upper: vec![], |
| 8330 | 8352 | is_class: false, |
| 8331 | | - logical_kind: None, |
| 8353 | + logical_kind: None, |
| 8332 | 8354 | last_dim_assumed_size: false, |
| 8333 | 8355 | }, |
| 8334 | 8356 | ); |
@@ -8364,7 +8386,7 @@ fn alloc_decls( |
| 8364 | 8386 | is_pointer: true, |
| 8365 | 8387 | runtime_dim_upper: vec![], |
| 8366 | 8388 | is_class: false, |
| 8367 | | - logical_kind: None, |
| 8389 | + logical_kind: None, |
| 8368 | 8390 | last_dim_assumed_size: false, |
| 8369 | 8391 | }, |
| 8370 | 8392 | ); |
@@ -8407,7 +8429,7 @@ fn alloc_decls( |
| 8407 | 8429 | is_pointer: false, |
| 8408 | 8430 | runtime_dim_upper: vec![], |
| 8409 | 8431 | is_class: false, |
| 8410 | | - logical_kind: None, |
| 8432 | + logical_kind: None, |
| 8411 | 8433 | last_dim_assumed_size: false, |
| 8412 | 8434 | }, |
| 8413 | 8435 | ); |
@@ -8468,7 +8490,7 @@ fn alloc_decls( |
| 8468 | 8490 | is_pointer: false, |
| 8469 | 8491 | runtime_dim_upper: vec![], |
| 8470 | 8492 | is_class: false, |
| 8471 | | - logical_kind: None, |
| 8493 | + logical_kind: None, |
| 8472 | 8494 | last_dim_assumed_size: false, |
| 8473 | 8495 | }, |
| 8474 | 8496 | ); |
@@ -8527,21 +8549,22 @@ fn alloc_decls( |
| 8527 | 8549 | .unwrap_or_default(), |
| 8528 | 8550 | is_class: matches!(type_spec, TypeSpec::Class(_)), |
| 8529 | 8551 | logical_kind: if let TypeSpec::Logical(sel) = type_spec { |
| 8530 | | - Some(extract_kind_with_context(sel, 4, Some(¶m_consts), Some(st))) |
| 8552 | + Some(extract_kind_with_context( |
| 8553 | + sel, |
| 8554 | + 4, |
| 8555 | + Some(¶m_consts), |
| 8556 | + Some(st), |
| 8557 | + )) |
| 8531 | 8558 | } else { |
| 8532 | 8559 | None |
| 8533 | 8560 | }, |
| 8534 | | - last_dim_assumed_size: false, |
| 8561 | + last_dim_assumed_size: false, |
| 8535 | 8562 | }, |
| 8536 | 8563 | ); |
| 8537 | 8564 | } else if let Some(specs) = array_spec { |
| 8538 | 8565 | // Fixed-size array variable. |
| 8539 | | - let dims = extract_array_dims_with_init( |
| 8540 | | - specs, |
| 8541 | | - init_expr, |
| 8542 | | - ¶m_consts, |
| 8543 | | - Some(st), |
| 8544 | | - ); |
| 8566 | + let dims = |
| 8567 | + extract_array_dims_with_init(specs, init_expr, ¶m_consts, Some(st)); |
| 8545 | 8568 | let total_size: i64 = dims.iter().map(|(_, size)| *size).product(); |
| 8546 | 8569 | let (array_elem_ty, array_derived_type, array_char_kind) = |
| 8547 | 8570 | if matches!(type_spec, TypeSpec::Character(_)) { |
@@ -8624,11 +8647,16 @@ fn alloc_decls( |
| 8624 | 8647 | runtime_dim_upper: vec![], |
| 8625 | 8648 | is_class: false, |
| 8626 | 8649 | logical_kind: if let TypeSpec::Logical(sel) = type_spec { |
| 8627 | | - Some(extract_kind_with_context(sel, 4, Some(¶m_consts), Some(st))) |
| 8650 | + Some(extract_kind_with_context( |
| 8651 | + sel, |
| 8652 | + 4, |
| 8653 | + Some(¶m_consts), |
| 8654 | + Some(st), |
| 8655 | + )) |
| 8628 | 8656 | } else { |
| 8629 | 8657 | None |
| 8630 | 8658 | }, |
| 8631 | | - last_dim_assumed_size: false, |
| 8659 | + last_dim_assumed_size: false, |
| 8632 | 8660 | }, |
| 8633 | 8661 | ); |
| 8634 | 8662 | } else { |
@@ -8665,8 +8693,12 @@ fn alloc_decls( |
| 8665 | 8693 | is_pointer: false, |
| 8666 | 8694 | runtime_dim_upper: vec![], |
| 8667 | 8695 | is_class: false, |
| 8668 | | - logical_kind: type_spec_logical_kind(type_spec, Some(¶m_consts), Some(st)), |
| 8669 | | - last_dim_assumed_size: false, |
| 8696 | + logical_kind: type_spec_logical_kind( |
| 8697 | + type_spec, |
| 8698 | + Some(¶m_consts), |
| 8699 | + Some(st), |
| 8700 | + ), |
| 8701 | + last_dim_assumed_size: false, |
| 8670 | 8702 | }, |
| 8671 | 8703 | ); |
| 8672 | 8704 | } |
@@ -8696,7 +8728,7 @@ fn alloc_decls( |
| 8696 | 8728 | is_pointer: false, |
| 8697 | 8729 | runtime_dim_upper: vec![], |
| 8698 | 8730 | is_class: false, |
| 8699 | | - logical_kind: None, |
| 8731 | + logical_kind: None, |
| 8700 | 8732 | last_dim_assumed_size: false, |
| 8701 | 8733 | }, |
| 8702 | 8734 | ); |
@@ -8718,7 +8750,7 @@ fn alloc_decls( |
| 8718 | 8750 | is_pointer: false, |
| 8719 | 8751 | runtime_dim_upper: vec![], |
| 8720 | 8752 | is_class: false, |
| 8721 | | - logical_kind: None, |
| 8753 | + logical_kind: None, |
| 8722 | 8754 | last_dim_assumed_size: false, |
| 8723 | 8755 | }, |
| 8724 | 8756 | ); |
@@ -8757,7 +8789,7 @@ fn alloc_decls( |
| 8757 | 8789 | is_pointer: true, |
| 8758 | 8790 | runtime_dim_upper: vec![], |
| 8759 | 8791 | is_class: false, |
| 8760 | | - logical_kind: None, |
| 8792 | + logical_kind: None, |
| 8761 | 8793 | last_dim_assumed_size: false, |
| 8762 | 8794 | }, |
| 8763 | 8795 | ); |
@@ -8799,7 +8831,7 @@ fn alloc_decls( |
| 8799 | 8831 | is_pointer: false, |
| 8800 | 8832 | runtime_dim_upper: vec![], |
| 8801 | 8833 | is_class: false, |
| 8802 | | - logical_kind: None, |
| 8834 | + logical_kind: None, |
| 8803 | 8835 | last_dim_assumed_size: false, |
| 8804 | 8836 | }, |
| 8805 | 8837 | ); |
@@ -8837,8 +8869,12 @@ fn alloc_decls( |
| 8837 | 8869 | is_pointer: false, |
| 8838 | 8870 | runtime_dim_upper: vec![], |
| 8839 | 8871 | is_class: false, |
| 8840 | | - logical_kind: type_spec_logical_kind(type_spec, Some(¶m_consts), Some(st)), |
| 8841 | | - last_dim_assumed_size: false, |
| 8872 | + logical_kind: type_spec_logical_kind( |
| 8873 | + type_spec, |
| 8874 | + Some(¶m_consts), |
| 8875 | + Some(st), |
| 8876 | + ), |
| 8877 | + last_dim_assumed_size: false, |
| 8842 | 8878 | }, |
| 8843 | 8879 | ); |
| 8844 | 8880 | } else { |
@@ -8858,8 +8894,12 @@ fn alloc_decls( |
| 8858 | 8894 | is_pointer: false, |
| 8859 | 8895 | runtime_dim_upper: vec![], |
| 8860 | 8896 | is_class: false, |
| 8861 | | - logical_kind: type_spec_logical_kind(type_spec, Some(¶m_consts), Some(st)), |
| 8862 | | - last_dim_assumed_size: false, |
| 8897 | + logical_kind: type_spec_logical_kind( |
| 8898 | + type_spec, |
| 8899 | + Some(¶m_consts), |
| 8900 | + Some(st), |
| 8901 | + ), |
| 8902 | + last_dim_assumed_size: false, |
| 8863 | 8903 | }, |
| 8864 | 8904 | ); |
| 8865 | 8905 | } |
@@ -8978,9 +9018,7 @@ fn init_decls( |
| 8978 | 9018 | b.store(val, slot); |
| 8979 | 9019 | } |
| 8980 | 9020 | } |
| 8981 | | - } else if let Some(values) = |
| 8982 | | - extract_reshape_source_ac(&init_expr.node) |
| 8983 | | - { |
| 9021 | + } else if let Some(values) = extract_reshape_source_ac(&init_expr.node) { |
| 8984 | 9022 | // F2018 §16.9.169 RESHAPE used as a declared |
| 8985 | 9023 | // initializer for a fixed-shape stack array. |
| 8986 | 9024 | // The source AC is laid out column-major into |
@@ -9314,8 +9352,7 @@ fn coerce_to_type(b: &mut FuncBuilder, val: ValueId, target: &IrType) -> ValueId |
| 9314 | 9352 | }; |
| 9315 | 9353 | let buf = b.alloca(IrType::Array(Box::new(IrType::Float(fw)), 2)); |
| 9316 | 9354 | let zero_off = b.const_i64(0); |
| 9317 | | - let lane_bytes = |
| 9318 | | - b.const_i64(if fw == FloatWidth::F64 { 8 } else { 4 }); |
| 9355 | + let lane_bytes = b.const_i64(if fw == FloatWidth::F64 { 8 } else { 4 }); |
| 9319 | 9356 | let re_ptr = b.gep(buf, vec![zero_off], IrType::Int(IntWidth::I8)); |
| 9320 | 9357 | let im_ptr = b.gep(buf, vec![lane_bytes], IrType::Int(IntWidth::I8)); |
| 9321 | 9358 | b.store(re, re_ptr); |
@@ -9325,7 +9362,9 @@ fn coerce_to_type(b: &mut FuncBuilder, val: ValueId, target: &IrType) -> ValueId |
| 9325 | 9362 | // Real → Complex (F2018 §10.1.10.1): real becomes real part, |
| 9326 | 9363 | // imaginary part 0. Width-adjusts when source and target |
| 9327 | 9364 | // float widths differ (e.g. real(sp) literal → complex(dp)). |
| 9328 | | - (IrType::Float(src_fw), IrType::Array(elem, 2)) if matches!(elem.as_ref(), IrType::Float(_)) => { |
| 9365 | + (IrType::Float(src_fw), IrType::Array(elem, 2)) |
| 9366 | + if matches!(elem.as_ref(), IrType::Float(_)) => |
| 9367 | + { |
| 9329 | 9368 | let target_fw = match elem.as_ref() { |
| 9330 | 9369 | IrType::Float(fw) => *fw, |
| 9331 | 9370 | _ => unreachable!(), |
@@ -9343,8 +9382,7 @@ fn coerce_to_type(b: &mut FuncBuilder, val: ValueId, target: &IrType) -> ValueId |
| 9343 | 9382 | }; |
| 9344 | 9383 | let buf = b.alloca(IrType::Array(Box::new(IrType::Float(target_fw)), 2)); |
| 9345 | 9384 | let zero_off = b.const_i64(0); |
| 9346 | | - let lane_bytes = |
| 9347 | | - b.const_i64(if target_fw == FloatWidth::F64 { 8 } else { 4 }); |
| 9385 | + let lane_bytes = b.const_i64(if target_fw == FloatWidth::F64 { 8 } else { 4 }); |
| 9348 | 9386 | let re_ptr = b.gep(buf, vec![zero_off], IrType::Int(IntWidth::I8)); |
| 9349 | 9387 | let im_ptr = b.gep(buf, vec![lane_bytes], IrType::Int(IntWidth::I8)); |
| 9350 | 9388 | b.store(re, re_ptr); |
@@ -9517,7 +9555,11 @@ fn extract_array_dims_with_init( |
| 9517 | 9555 | return dims; |
| 9518 | 9556 | }; |
| 9519 | 9557 | |
| 9520 | | - let prefix_extent: i64 = dims.iter().take(last_assumed_idx).map(|(_, extent)| *extent).product(); |
| 9558 | + let prefix_extent: i64 = dims |
| 9559 | + .iter() |
| 9560 | + .take(last_assumed_idx) |
| 9561 | + .map(|(_, extent)| *extent) |
| 9562 | + .product(); |
| 9521 | 9563 | if prefix_extent <= 0 || init_len < 0 || init_len % prefix_extent != 0 { |
| 9522 | 9564 | return dims; |
| 9523 | 9565 | } |
@@ -9753,7 +9795,9 @@ fn decl_scope_const_ir_type( |
| 9753 | 9795 | Expr::IntegerLiteral { kind, .. } => { |
| 9754 | 9796 | let kind_width = kind |
| 9755 | 9797 | .as_deref() |
| 9756 | | - .map(|kind_str| int_kind_to_width_in_context(kind_str, None, Some(param_consts), Some(st))) |
| 9798 | + .map(|kind_str| { |
| 9799 | + int_kind_to_width_in_context(kind_str, None, Some(param_consts), Some(st)) |
| 9800 | + }) |
| 9757 | 9801 | .unwrap_or_else(crate::driver::defaults::default_int_kind); |
| 9758 | 9802 | Some(IrType::int_from_kind(kind_width)) |
| 9759 | 9803 | } |
@@ -10678,24 +10722,21 @@ fn fixed_char_expr_len( |
| 10678 | 10722 | ) -> Option<i64> { |
| 10679 | 10723 | match &expr.node { |
| 10680 | 10724 | Expr::StringLiteral { value, .. } => Some(value.len() as i64), |
| 10681 | | - Expr::Name { name } => { |
| 10682 | | - locals |
| 10683 | | - .get(&name.to_lowercase()) |
| 10684 | | - .and_then(|info| match info.char_kind { |
| 10685 | | - CharKind::Fixed(len) => Some(len), |
| 10686 | | - _ => local_fixed_char_allocatable_scalar_len(info), |
| 10687 | | - }) |
| 10688 | | - .or_else(|| { |
| 10689 | | - st.find_symbol_any_scope(&name.to_lowercase()) |
| 10690 | | - .and_then(|sym| match sym.type_info.as_ref() { |
| 10691 | | - Some(crate::sema::symtab::TypeInfo::Character { |
| 10692 | | - len: Some(len), |
| 10693 | | - .. |
| 10694 | | - }) => Some(*len), |
| 10695 | | - _ => None, |
| 10696 | | - }) |
| 10697 | | - }) |
| 10698 | | - } |
| 10725 | + Expr::Name { name } => locals |
| 10726 | + .get(&name.to_lowercase()) |
| 10727 | + .and_then(|info| match info.char_kind { |
| 10728 | + CharKind::Fixed(len) => Some(len), |
| 10729 | + _ => local_fixed_char_allocatable_scalar_len(info), |
| 10730 | + }) |
| 10731 | + .or_else(|| { |
| 10732 | + st.find_symbol_any_scope(&name.to_lowercase()) |
| 10733 | + .and_then(|sym| match sym.type_info.as_ref() { |
| 10734 | + Some(crate::sema::symtab::TypeInfo::Character { |
| 10735 | + len: Some(len), .. |
| 10736 | + }) => Some(*len), |
| 10737 | + _ => None, |
| 10738 | + }) |
| 10739 | + }), |
| 10699 | 10740 | Expr::ComponentAccess { .. } => { |
| 10700 | 10741 | let tl = type_layouts?; |
| 10701 | 10742 | let (_field_ptr, field) = resolve_component_field_access(b, locals, expr, st, tl)?; |
@@ -10839,23 +10880,21 @@ fn first_array_constructor_type_info( |
| 10839 | 10880 | let first = first_array_constructor_expr(values)?; |
| 10840 | 10881 | operator_expr_type_info(first, locals, st, type_layouts) |
| 10841 | 10882 | .or_else(|| match &first.node { |
| 10842 | | - Expr::FunctionCall { callee, .. } => match &callee.node { |
| 10843 | | - Expr::Name { name } => st.all_scopes().iter().find_map(|scope| { |
| 10844 | | - let sym = scope.symbols.get(&name.to_ascii_lowercase())?; |
| 10845 | | - if matches!(sym.kind, crate::sema::symtab::SymbolKind::DerivedType) { |
| 10846 | | - Some( |
| 10847 | | - sym.type_info |
| 10848 | | - .clone() |
| 10849 | | - .unwrap_or(crate::sema::symtab::TypeInfo::Derived( |
| 10850 | | - sym.name.clone(), |
| 10851 | | - )), |
| 10852 | | - ) |
| 10853 | | - } else { |
| 10854 | | - None |
| 10855 | | - } |
| 10856 | | - }), |
| 10857 | | - _ => None, |
| 10858 | | - }, |
| 10883 | + Expr::FunctionCall { callee, .. } => { |
| 10884 | + match &callee.node { |
| 10885 | + Expr::Name { name } => st.all_scopes().iter().find_map(|scope| { |
| 10886 | + let sym = scope.symbols.get(&name.to_ascii_lowercase())?; |
| 10887 | + if matches!(sym.kind, crate::sema::symtab::SymbolKind::DerivedType) { |
| 10888 | + Some(sym.type_info.clone().unwrap_or( |
| 10889 | + crate::sema::symtab::TypeInfo::Derived(sym.name.clone()), |
| 10890 | + )) |
| 10891 | + } else { |
| 10892 | + None |
| 10893 | + } |
| 10894 | + }), |
| 10895 | + _ => None, |
| 10896 | + } |
| 10897 | + } |
| 10859 | 10898 | _ => None, |
| 10860 | 10899 | }) |
| 10861 | 10900 | .or_else(|| fortran_type_to_type_info(&crate::sema::types::expr_type(first, st))) |
@@ -11373,8 +11412,7 @@ fn lower_logical_reduction_intrinsic_ast( |
| 11373 | 11412 | internal_funcs, |
| 11374 | 11413 | contained_host_refs, |
| 11375 | 11414 | descriptor_params, |
| 11376 | | - ) |
| 11377 | | - { |
| 11415 | + ) { |
| 11378 | 11416 | let runtime = match name { |
| 11379 | 11417 | "any" => "afs_array_any_logical", |
| 11380 | 11418 | "all" => "afs_array_all_logical", |
@@ -11436,8 +11474,7 @@ fn lower_logical_reduction_intrinsic_ast( |
| 11436 | 11474 | match &e.node { |
| 11437 | 11475 | Expr::ArrayConstructor { .. } => true, |
| 11438 | 11476 | Expr::BinaryOp { left, right, .. } => { |
| 11439 | | - contains_array_constructor(left) |
| 11440 | | - || contains_array_constructor(right) |
| 11477 | + contains_array_constructor(left) || contains_array_constructor(right) |
| 11441 | 11478 | } |
| 11442 | 11479 | Expr::UnaryOp { operand, .. } => contains_array_constructor(operand), |
| 11443 | 11480 | Expr::ParenExpr { inner } => contains_array_constructor(inner), |
@@ -11449,9 +11486,7 @@ fn lower_logical_reduction_intrinsic_ast( |
| 11449 | 11486 | let acceptable_for_compare = |t: &FortranType| { |
| 11450 | 11487 | matches!( |
| 11451 | 11488 | t, |
| 11452 | | - FortranType::Integer { .. } |
| 11453 | | - | FortranType::Real { .. } |
| 11454 | | - | FortranType::Unknown |
| 11489 | + FortranType::Integer { .. } | FortranType::Real { .. } | FortranType::Unknown |
| 11455 | 11490 | ) |
| 11456 | 11491 | }; |
| 11457 | 11492 | if !acceptable_for_compare(<) |
@@ -11461,116 +11496,115 @@ fn lower_logical_reduction_intrinsic_ast( |
| 11461 | 11496 | { |
| 11462 | 11497 | // Fall through to the existing match arms. |
| 11463 | 11498 | } else { |
| 11464 | | - let lhs = lower_array_expr_descriptor( |
| 11465 | | - b, |
| 11466 | | - locals, |
| 11467 | | - left, |
| 11468 | | - st, |
| 11469 | | - type_layouts, |
| 11470 | | - internal_funcs, |
| 11471 | | - contained_host_refs, |
| 11472 | | - descriptor_params, |
| 11473 | | - ); |
| 11474 | | - let rhs = lower_array_expr_descriptor( |
| 11475 | | - b, |
| 11476 | | - locals, |
| 11477 | | - right, |
| 11478 | | - st, |
| 11479 | | - type_layouts, |
| 11480 | | - internal_funcs, |
| 11481 | | - contained_host_refs, |
| 11482 | | - descriptor_params, |
| 11483 | | - ); |
| 11484 | | - if lhs.is_some() || rhs.is_some() { |
| 11485 | | - let (source_desc, elem_ty) = lhs |
| 11486 | | - .as_ref() |
| 11487 | | - .map(|(d, t)| (*d, t.clone())) |
| 11488 | | - .or_else(|| rhs.as_ref().map(|(d, t)| (*d, t.clone())))?; |
| 11489 | | - // Only handle wider numeric element types here. Skip I8 |
| 11490 | | - // because that's how character(1) arrays present, where |
| 11491 | | - // a comparison like `s([5,8]) /= '-'` has character-string |
| 11492 | | - // semantics and the existing vector-subscript expansion |
| 11493 | | - // path handles it correctly. Complex and non-scalar shapes |
| 11494 | | - // also need richer handling than this loop. |
| 11495 | | - let scalar_numeric = match elem_ty { |
| 11496 | | - IrType::Int(IntWidth::I8) => false, |
| 11497 | | - IrType::Int(_) | IrType::Float(_) | IrType::Bool => true, |
| 11498 | | - _ => false, |
| 11499 | | - }; |
| 11500 | | - if !scalar_numeric { |
| 11501 | | - return None; |
| 11502 | | - } |
| 11503 | | - |
| 11504 | | - let n = b.call( |
| 11505 | | - FuncRef::External("afs_array_size".into()), |
| 11506 | | - vec![source_desc], |
| 11507 | | - IrType::Int(IntWidth::I64), |
| 11499 | + let lhs = lower_array_expr_descriptor( |
| 11500 | + b, |
| 11501 | + locals, |
| 11502 | + left, |
| 11503 | + st, |
| 11504 | + type_layouts, |
| 11505 | + internal_funcs, |
| 11506 | + contained_host_refs, |
| 11507 | + descriptor_params, |
| 11508 | 11508 | ); |
| 11509 | | - let acc_ty = if name == "count" { |
| 11510 | | - IrType::Int(IntWidth::I32) |
| 11511 | | - } else { |
| 11512 | | - IrType::Bool |
| 11513 | | - }; |
| 11514 | | - let acc_addr = b.alloca(acc_ty); |
| 11515 | | - let acc_init = init_logical_reduction_acc(b, name); |
| 11516 | | - b.store(acc_init, acc_addr); |
| 11517 | | - let i_addr = b.alloca(IrType::Int(IntWidth::I64)); |
| 11518 | | - let zero64 = b.const_i64(0); |
| 11519 | | - b.store(zero64, i_addr); |
| 11520 | | - |
| 11521 | | - let bb_check = b.create_block("any_cmp_check"); |
| 11522 | | - let bb_body = b.create_block("any_cmp_body"); |
| 11523 | | - let bb_exit = b.create_block("any_cmp_exit"); |
| 11524 | | - b.branch(bb_check, vec![]); |
| 11509 | + let rhs = lower_array_expr_descriptor( |
| 11510 | + b, |
| 11511 | + locals, |
| 11512 | + right, |
| 11513 | + st, |
| 11514 | + type_layouts, |
| 11515 | + internal_funcs, |
| 11516 | + contained_host_refs, |
| 11517 | + descriptor_params, |
| 11518 | + ); |
| 11519 | + if lhs.is_some() || rhs.is_some() { |
| 11520 | + let (source_desc, elem_ty) = lhs |
| 11521 | + .as_ref() |
| 11522 | + .map(|(d, t)| (*d, t.clone())) |
| 11523 | + .or_else(|| rhs.as_ref().map(|(d, t)| (*d, t.clone())))?; |
| 11524 | + // Only handle wider numeric element types here. Skip I8 |
| 11525 | + // because that's how character(1) arrays present, where |
| 11526 | + // a comparison like `s([5,8]) /= '-'` has character-string |
| 11527 | + // semantics and the existing vector-subscript expansion |
| 11528 | + // path handles it correctly. Complex and non-scalar shapes |
| 11529 | + // also need richer handling than this loop. |
| 11530 | + let scalar_numeric = match elem_ty { |
| 11531 | + IrType::Int(IntWidth::I8) => false, |
| 11532 | + IrType::Int(_) | IrType::Float(_) | IrType::Bool => true, |
| 11533 | + _ => false, |
| 11534 | + }; |
| 11535 | + if !scalar_numeric { |
| 11536 | + return None; |
| 11537 | + } |
| 11525 | 11538 | |
| 11526 | | - b.set_block(bb_check); |
| 11527 | | - let i = b.load(i_addr); |
| 11528 | | - let done = b.icmp(CmpOp::Ge, i, n); |
| 11529 | | - b.cond_branch(done, bb_exit, vec![], bb_body, vec![]); |
| 11530 | | - |
| 11531 | | - b.set_block(bb_body); |
| 11532 | | - let idx = b.load(i_addr); |
| 11533 | | - |
| 11534 | | - let load_side = |b: &mut FuncBuilder, |
| 11535 | | - side: &Option<(ValueId, IrType)>, |
| 11536 | | - side_expr: &crate::ast::expr::SpannedExpr| |
| 11537 | | - -> ValueId { |
| 11538 | | - if let Some((desc, _)) = side { |
| 11539 | | - let elem_ptr = |
| 11540 | | - rank1_array_desc_elem_ptr(b, *desc, &elem_ty, idx); |
| 11541 | | - b.load_typed(elem_ptr, elem_ty.clone()) |
| 11539 | + let n = b.call( |
| 11540 | + FuncRef::External("afs_array_size".into()), |
| 11541 | + vec![source_desc], |
| 11542 | + IrType::Int(IntWidth::I64), |
| 11543 | + ); |
| 11544 | + let acc_ty = if name == "count" { |
| 11545 | + IrType::Int(IntWidth::I32) |
| 11542 | 11546 | } else { |
| 11543 | | - let raw = lower_expr_full( |
| 11544 | | - b, |
| 11545 | | - locals, |
| 11546 | | - side_expr, |
| 11547 | | - st, |
| 11548 | | - type_layouts, |
| 11549 | | - internal_funcs, |
| 11550 | | - contained_host_refs, |
| 11551 | | - descriptor_params, |
| 11552 | | - ); |
| 11553 | | - coerce_to_type(b, raw, &elem_ty) |
| 11554 | | - } |
| 11555 | | - }; |
| 11556 | | - let lv = load_side(b, &lhs, left); |
| 11557 | | - let rv = load_side(b, &rhs, right); |
| 11558 | | - let pred = match &elem_ty { |
| 11559 | | - IrType::Float(_) => b.fcmp(cmp, lv, rv), |
| 11560 | | - _ => b.icmp(cmp, lv, rv), |
| 11561 | | - }; |
| 11562 | | - let acc = b.load(acc_addr); |
| 11563 | | - let new_acc = step_logical_reduction_acc(b, name, acc, pred); |
| 11564 | | - b.store(new_acc, acc_addr); |
| 11547 | + IrType::Bool |
| 11548 | + }; |
| 11549 | + let acc_addr = b.alloca(acc_ty); |
| 11550 | + let acc_init = init_logical_reduction_acc(b, name); |
| 11551 | + b.store(acc_init, acc_addr); |
| 11552 | + let i_addr = b.alloca(IrType::Int(IntWidth::I64)); |
| 11553 | + let zero64 = b.const_i64(0); |
| 11554 | + b.store(zero64, i_addr); |
| 11565 | 11555 | |
| 11566 | | - let one = b.const_i64(1); |
| 11567 | | - let next = b.iadd(idx, one); |
| 11568 | | - b.store(next, i_addr); |
| 11569 | | - b.branch(bb_check, vec![]); |
| 11556 | + let bb_check = b.create_block("any_cmp_check"); |
| 11557 | + let bb_body = b.create_block("any_cmp_body"); |
| 11558 | + let bb_exit = b.create_block("any_cmp_exit"); |
| 11559 | + b.branch(bb_check, vec![]); |
| 11570 | 11560 | |
| 11571 | | - b.set_block(bb_exit); |
| 11572 | | - return Some(b.load(acc_addr)); |
| 11573 | | - } |
| 11561 | + b.set_block(bb_check); |
| 11562 | + let i = b.load(i_addr); |
| 11563 | + let done = b.icmp(CmpOp::Ge, i, n); |
| 11564 | + b.cond_branch(done, bb_exit, vec![], bb_body, vec![]); |
| 11565 | + |
| 11566 | + b.set_block(bb_body); |
| 11567 | + let idx = b.load(i_addr); |
| 11568 | + |
| 11569 | + let load_side = |b: &mut FuncBuilder, |
| 11570 | + side: &Option<(ValueId, IrType)>, |
| 11571 | + side_expr: &crate::ast::expr::SpannedExpr| |
| 11572 | + -> ValueId { |
| 11573 | + if let Some((desc, _)) = side { |
| 11574 | + let elem_ptr = rank1_array_desc_elem_ptr(b, *desc, &elem_ty, idx); |
| 11575 | + b.load_typed(elem_ptr, elem_ty.clone()) |
| 11576 | + } else { |
| 11577 | + let raw = lower_expr_full( |
| 11578 | + b, |
| 11579 | + locals, |
| 11580 | + side_expr, |
| 11581 | + st, |
| 11582 | + type_layouts, |
| 11583 | + internal_funcs, |
| 11584 | + contained_host_refs, |
| 11585 | + descriptor_params, |
| 11586 | + ); |
| 11587 | + coerce_to_type(b, raw, &elem_ty) |
| 11588 | + } |
| 11589 | + }; |
| 11590 | + let lv = load_side(b, &lhs, left); |
| 11591 | + let rv = load_side(b, &rhs, right); |
| 11592 | + let pred = match &elem_ty { |
| 11593 | + IrType::Float(_) => b.fcmp(cmp, lv, rv), |
| 11594 | + _ => b.icmp(cmp, lv, rv), |
| 11595 | + }; |
| 11596 | + let acc = b.load(acc_addr); |
| 11597 | + let new_acc = step_logical_reduction_acc(b, name, acc, pred); |
| 11598 | + b.store(new_acc, acc_addr); |
| 11599 | + |
| 11600 | + let one = b.const_i64(1); |
| 11601 | + let next = b.iadd(idx, one); |
| 11602 | + b.store(next, i_addr); |
| 11603 | + b.branch(bb_check, vec![]); |
| 11604 | + |
| 11605 | + b.set_block(bb_exit); |
| 11606 | + return Some(b.load(acc_addr)); |
| 11607 | + } |
| 11574 | 11608 | } |
| 11575 | 11609 | } |
| 11576 | 11610 | } |
@@ -11663,8 +11697,14 @@ fn lower_logical_reduction_intrinsic_ast( |
| 11663 | 11697 | } |
| 11664 | 11698 | let unfolded_left = unfold_array_ctor_binop(left); |
| 11665 | 11699 | let unfolded_right = unfold_array_ctor_binop(right); |
| 11666 | | - let left_node = unfolded_left.as_ref().map(|e| &e.node).unwrap_or(&left.node); |
| 11667 | | - let right_node = unfolded_right.as_ref().map(|e| &e.node).unwrap_or(&right.node); |
| 11700 | + let left_node = unfolded_left |
| 11701 | + .as_ref() |
| 11702 | + .map(|e| &e.node) |
| 11703 | + .unwrap_or(&left.node); |
| 11704 | + let right_node = unfolded_right |
| 11705 | + .as_ref() |
| 11706 | + .map(|e| &e.node) |
| 11707 | + .unwrap_or(&right.node); |
| 11668 | 11708 | match (left_node, right_node) { |
| 11669 | 11709 | (Expr::ArrayConstructor { values, .. }, _) => { |
| 11670 | 11710 | let mut acc = init_logical_reduction_acc(b, name); |
@@ -11755,7 +11795,7 @@ fn lower_logical_reduction_intrinsic_ast( |
| 11755 | 11795 | is_pointer: false, |
| 11756 | 11796 | runtime_dim_upper: vec![], |
| 11757 | 11797 | is_class: false, |
| 11758 | | - logical_kind: None, |
| 11798 | + logical_kind: None, |
| 11759 | 11799 | last_dim_assumed_size: false, |
| 11760 | 11800 | }, |
| 11761 | 11801 | ); |
@@ -11862,7 +11902,7 @@ fn lower_logical_reduction_intrinsic_ast( |
| 11862 | 11902 | is_pointer: false, |
| 11863 | 11903 | runtime_dim_upper: vec![], |
| 11864 | 11904 | is_class: false, |
| 11865 | | - logical_kind: None, |
| 11905 | + logical_kind: None, |
| 11866 | 11906 | last_dim_assumed_size: false, |
| 11867 | 11907 | }, |
| 11868 | 11908 | ); |
@@ -12556,7 +12596,8 @@ fn lower_intrinsic(b: &mut FuncBuilder, name: &str, args: &[ValueId]) -> Option< |
| 12556 | 12596 | let pos_top = b.isub(bits, shift); |
| 12557 | 12597 | // Pre-fill: -1 if top bit of x is 1, else 0. |
| 12558 | 12598 | let one = int_const_for_width(b, value_width, 1); |
| 12559 | | - let top_bit_pos = int_const_for_width(b, value_width, (value_width.bits() - 1) as i64); |
| 12599 | + let top_bit_pos = |
| 12600 | + int_const_for_width(b, value_width, (value_width.bits() - 1) as i64); |
| 12560 | 12601 | let top_bit = b.lshr(args[0], top_bit_pos); |
| 12561 | 12602 | let sign = b.bit_and(top_bit, one); |
| 12562 | 12603 | let neg_one = int_const_for_width(b, value_width, -1); |
@@ -13638,7 +13679,14 @@ fn generic_candidate_matches_slots_with_formal_skip( |
| 13638 | 13679 | return false; |
| 13639 | 13680 | } |
| 13640 | 13681 | |
| 13641 | | - generic_candidate_matches_slots_with_proc(b, declared_args, arg_slots, supplied, formal_skip, &[]) |
| 13682 | + generic_candidate_matches_slots_with_proc( |
| 13683 | + b, |
| 13684 | + declared_args, |
| 13685 | + arg_slots, |
| 13686 | + supplied, |
| 13687 | + formal_skip, |
| 13688 | + &[], |
| 13689 | + ) |
| 13642 | 13690 | } |
| 13643 | 13691 | |
| 13644 | 13692 | fn generic_candidate_matches_slots_with_proc( |
@@ -13650,7 +13698,13 @@ fn generic_candidate_matches_slots_with_proc( |
| 13650 | 13698 | actual_is_procedure: &[bool], |
| 13651 | 13699 | ) -> bool { |
| 13652 | 13700 | generic_candidate_matches_slots_with_proc_elemental( |
| 13653 | | - b, declared_args, arg_slots, _supplied, formal_skip, actual_is_procedure, false, |
| 13701 | + b, |
| 13702 | + declared_args, |
| 13703 | + arg_slots, |
| 13704 | + _supplied, |
| 13705 | + formal_skip, |
| 13706 | + actual_is_procedure, |
| 13707 | + false, |
| 13654 | 13708 | ) |
| 13655 | 13709 | } |
| 13656 | 13710 | |
@@ -13669,8 +13723,7 @@ fn generic_candidate_matches_slots_with_proc_elemental( |
| 13669 | 13723 | } |
| 13670 | 13724 | match arg_slots.get(idx) { |
| 13671 | 13725 | Some(Some(arg_val)) => { |
| 13672 | | - let actual_is_proc = |
| 13673 | | - actual_is_procedure.get(idx).copied().unwrap_or(false); |
| 13726 | + let actual_is_proc = actual_is_procedure.get(idx).copied().unwrap_or(false); |
| 13674 | 13727 | if actual_is_proc { |
| 13675 | 13728 | continue; |
| 13676 | 13729 | } |
@@ -13744,8 +13797,7 @@ fn reorder_value_slots_by_formal_skip( |
| 13744 | 13797 | let key = kw.to_ascii_lowercase(); |
| 13745 | 13798 | let idx = formal_order |
| 13746 | 13799 | .iter() |
| 13747 | | - .position(|name| name.eq_ignore_ascii_case(&key)) |
| 13748 | | - ?; |
| 13800 | + .position(|name| name.eq_ignore_ascii_case(&key))?; |
| 13749 | 13801 | if idx < last_positional || slots[idx].is_some() { |
| 13750 | 13802 | return None; |
| 13751 | 13803 | } |
@@ -13782,8 +13834,7 @@ fn reorder_semantic_type_slots_by_formal_skip( |
| 13782 | 13834 | let key = kw.to_ascii_lowercase(); |
| 13783 | 13835 | let idx = formal_order |
| 13784 | 13836 | .iter() |
| 13785 | | - .position(|name| name.eq_ignore_ascii_case(&key)) |
| 13786 | | - ?; |
| 13837 | + .position(|name| name.eq_ignore_ascii_case(&key))?; |
| 13787 | 13838 | if idx < last_positional || slots[idx].is_some() { |
| 13788 | 13839 | return None; |
| 13789 | 13840 | } |
@@ -13871,7 +13922,10 @@ fn resolve_generic_call_by_semantics( |
| 13871 | 13922 | continue; |
| 13872 | 13923 | }; |
| 13873 | 13924 | let declared_args = declared_args_for_scope(scope); |
| 13874 | | - let required = declared_args.iter().filter(|sym| !sym.attrs.optional).count(); |
| 13925 | + let required = declared_args |
| 13926 | + .iter() |
| 13927 | + .filter(|sym| !sym.attrs.optional) |
| 13928 | + .count(); |
| 13875 | 13929 | if args.len() < required || args.len() > declared_args.len() { |
| 13876 | 13930 | continue; |
| 13877 | 13931 | } |
@@ -13884,13 +13938,16 @@ fn resolve_generic_call_by_semantics( |
| 13884 | 13938 | continue; |
| 13885 | 13939 | }; |
| 13886 | 13940 | let semantic_match = declared_args.iter().enumerate().all(|(idx, declared_arg)| { |
| 13887 | | - declared_arg.type_info.as_ref().is_some_and(|declared_type| { |
| 13888 | | - generic_declared_semantic_match( |
| 13889 | | - declared_type, |
| 13890 | | - semantic_slots.get(idx).and_then(|slot| slot.as_ref()), |
| 13891 | | - type_layouts, |
| 13892 | | - ) |
| 13893 | | - }) |
| 13941 | + declared_arg |
| 13942 | + .type_info |
| 13943 | + .as_ref() |
| 13944 | + .is_some_and(|declared_type| { |
| 13945 | + generic_declared_semantic_match( |
| 13946 | + declared_type, |
| 13947 | + semantic_slots.get(idx).and_then(|slot| slot.as_ref()), |
| 13948 | + type_layouts, |
| 13949 | + ) |
| 13950 | + }) |
| 13894 | 13951 | }); |
| 13895 | 13952 | if semantic_match { |
| 13896 | 13953 | return Some(candidate.clone()); |
@@ -13950,7 +14007,10 @@ fn resolve_generic_call_actuals( |
| 13950 | 14007 | // call binds to a 2-formal candidate via the slot reorder's |
| 13951 | 14008 | // overflow push, so e.g. `mean(y, 1, mask)` resolves to |
| 13952 | 14009 | // `mean_2_rsp_rsp(x, dim)` ignoring the mask. |
| 13953 | | - let required = declared_args.iter().filter(|sym| !sym.attrs.optional).count(); |
| 14010 | + let required = declared_args |
| 14011 | + .iter() |
| 14012 | + .filter(|sym| !sym.attrs.optional) |
| 14013 | + .count(); |
| 13954 | 14014 | if args.len() < required || args.len() > declared_args.len() { |
| 13955 | 14015 | continue; |
| 13956 | 14016 | } |
@@ -13967,12 +14027,8 @@ fn resolve_generic_call_actuals( |
| 13967 | 14027 | ) else { |
| 13968 | 14028 | continue; |
| 13969 | 14029 | }; |
| 13970 | | - let rank_slots: Vec<Option<usize>> = reorder_actual_ranks_by_formal_skip( |
| 13971 | | - args, |
| 13972 | | - &actual_ranks, |
| 13973 | | - &scope.arg_order, |
| 13974 | | - 0, |
| 13975 | | - ); |
| 14030 | + let rank_slots: Vec<Option<usize>> = |
| 14031 | + reorder_actual_ranks_by_formal_skip(args, &actual_ranks, &scope.arg_order, 0); |
| 13976 | 14032 | let supplied = arg_slots.iter().filter(|slot| slot.is_some()).count(); |
| 13977 | 14033 | // Detect actuals that are procedure references. Such actuals |
| 13978 | 14034 | // bind to `procedure(iface) :: p` formals which the .amod |
@@ -14020,10 +14076,7 @@ fn resolve_generic_call_actuals( |
| 14020 | 14076 | 0, |
| 14021 | 14077 | ); |
| 14022 | 14078 | let semantic_match = declared_args.iter().enumerate().all(|(idx, declared_arg)| { |
| 14023 | | - let actual_is_proc = actual_is_procedure_slots |
| 14024 | | - .get(idx) |
| 14025 | | - .copied() |
| 14026 | | - .unwrap_or(false); |
| 14079 | + let actual_is_proc = actual_is_procedure_slots.get(idx).copied().unwrap_or(false); |
| 14027 | 14080 | // A procedure-name actual binds only to a procedure formal; |
| 14028 | 14081 | // sema rejects any other use, so by the time we reach |
| 14029 | 14082 | // dispatch we can trust that pairing and skip type matching. |
@@ -14100,8 +14153,8 @@ fn formal_declared_rank(decl_sym: &crate::sema::symtab::Symbol) -> Option<usize> |
| 14100 | 14153 | |
| 14101 | 14154 | fn formal_rank_matches_actual(formal: Option<usize>, actual: Option<usize>) -> bool { |
| 14102 | 14155 | match (formal, actual) { |
| 14103 | | - (None, _) => true, // assumed-rank — accepts anything |
| 14104 | | - (Some(_), None) => true, // unknown actual rank — don't penalize |
| 14156 | + (None, _) => true, // assumed-rank — accepts anything |
| 14157 | + (Some(_), None) => true, // unknown actual rank — don't penalize |
| 14105 | 14158 | (Some(f), Some(a)) => f == a, |
| 14106 | 14159 | } |
| 14107 | 14160 | } |
@@ -14156,7 +14209,9 @@ fn actual_expr_rank( |
| 14156 | 14209 | if local_is_array_like(info) { |
| 14157 | 14210 | let n_ranges = args |
| 14158 | 14211 | .iter() |
| 14159 | | - .filter(|a| matches!(a.value, crate::ast::expr::SectionSubscript::Range { .. })) |
| 14212 | + .filter(|a| { |
| 14213 | + matches!(a.value, crate::ast::expr::SectionSubscript::Range { .. }) |
| 14214 | + }) |
| 14160 | 14215 | .count(); |
| 14161 | 14216 | if n_ranges == 0 && !args.is_empty() { |
| 14162 | 14217 | return Some(0); // scalar element access |
@@ -14259,9 +14314,7 @@ fn resolve_bound_proc_actuals<'a>( |
| 14259 | 14314 | let actual_ranks: Vec<Option<usize>> = args |
| 14260 | 14315 | .iter() |
| 14261 | 14316 | .map(|arg| match &arg.value { |
| 14262 | | - crate::ast::expr::SectionSubscript::Element(expr) => { |
| 14263 | | - actual_expr_rank(expr, locals, st) |
| 14264 | | - } |
| 14317 | + crate::ast::expr::SectionSubscript::Element(expr) => actual_expr_rank(expr, locals, st), |
| 14265 | 14318 | _ => None, |
| 14266 | 14319 | }) |
| 14267 | 14320 | .collect(); |
@@ -14297,14 +14350,16 @@ fn resolve_bound_proc_actuals<'a>( |
| 14297 | 14350 | .iter() |
| 14298 | 14351 | .enumerate() |
| 14299 | 14352 | .filter(|(idx, _)| *idx >= formal_skip) |
| 14300 | | - .all(|(idx, declared_arg)| match declared_arg.type_info.as_ref() { |
| 14301 | | - Some(declared_type) => generic_declared_semantic_match( |
| 14302 | | - declared_type, |
| 14303 | | - semantic_slots.get(idx).and_then(|slot| slot.as_ref()), |
| 14304 | | - type_layouts, |
| 14305 | | - ), |
| 14306 | | - None => true, |
| 14307 | | - }); |
| 14353 | + .all( |
| 14354 | + |(idx, declared_arg)| match declared_arg.type_info.as_ref() { |
| 14355 | + Some(declared_type) => generic_declared_semantic_match( |
| 14356 | + declared_type, |
| 14357 | + semantic_slots.get(idx).and_then(|slot| slot.as_ref()), |
| 14358 | + type_layouts, |
| 14359 | + ), |
| 14360 | + None => true, |
| 14361 | + }, |
| 14362 | + ); |
| 14308 | 14363 | let ir_match = generic_candidate_matches_slots_with_formal_skip( |
| 14309 | 14364 | b, |
| 14310 | 14365 | &declared_args, |
@@ -14349,12 +14404,8 @@ fn resolve_bound_proc_actuals<'a>( |
| 14349 | 14404 | }; |
| 14350 | 14405 | let declared_args = declared_args_for_scope(scope); |
| 14351 | 14406 | let formal_skip = if bp.nopass { 0 } else { 1 }; |
| 14352 | | - let rank_slots = reorder_actual_ranks_by_formal_skip( |
| 14353 | | - args, |
| 14354 | | - &actual_ranks, |
| 14355 | | - &scope.arg_order, |
| 14356 | | - formal_skip, |
| 14357 | | - ); |
| 14407 | + let rank_slots = |
| 14408 | + reorder_actual_ranks_by_formal_skip(args, &actual_ranks, &scope.arg_order, formal_skip); |
| 14358 | 14409 | let mut all_match = true; |
| 14359 | 14410 | let mut any_constraint = false; |
| 14360 | 14411 | for (idx, declared_arg) in declared_args.iter().enumerate() { |
@@ -14413,7 +14464,16 @@ fn resolved_bound_proc_for_call<'a>( |
| 14413 | 14464 | _ => b.const_i32(0), |
| 14414 | 14465 | }) |
| 14415 | 14466 | .collect(); |
| 14416 | | - resolve_bound_proc_actuals(st, b, locals, layout, component, args, &probe_vals, type_layouts) |
| 14467 | + resolve_bound_proc_actuals( |
| 14468 | + st, |
| 14469 | + b, |
| 14470 | + locals, |
| 14471 | + layout, |
| 14472 | + component, |
| 14473 | + args, |
| 14474 | + &probe_vals, |
| 14475 | + type_layouts, |
| 14476 | + ) |
| 14417 | 14477 | } |
| 14418 | 14478 | |
| 14419 | 14479 | fn fail_unmatched_bound_proc_resolution( |
@@ -14533,24 +14593,23 @@ fn assignment_expr_type_info( |
| 14533 | 14593 | }; |
| 14534 | 14594 | let arg_set: std::collections::HashSet<String> = |
| 14535 | 14595 | scope.arg_order.iter().map(|n| n.to_lowercase()).collect(); |
| 14536 | | - let result_ti = scope |
| 14537 | | - .symbols |
| 14538 | | - .iter() |
| 14539 | | - .find_map(|(key, s)| { |
| 14540 | | - if arg_set.contains(key) { |
| 14541 | | - return None; |
| 14542 | | - } |
| 14543 | | - if matches!( |
| 14544 | | - s.kind, |
| 14545 | | - crate::sema::symtab::SymbolKind::Variable |
| 14546 | | - | crate::sema::symtab::SymbolKind::Parameter |
| 14547 | | - ) { |
| 14548 | | - s.type_info.clone() |
| 14549 | | - } else { |
| 14550 | | - None |
| 14551 | | - } |
| 14552 | | - }); |
| 14553 | | - let Some(t) = result_ti else { return None; }; |
| 14596 | + let result_ti = scope.symbols.iter().find_map(|(key, s)| { |
| 14597 | + if arg_set.contains(key) { |
| 14598 | + return None; |
| 14599 | + } |
| 14600 | + if matches!( |
| 14601 | + s.kind, |
| 14602 | + crate::sema::symtab::SymbolKind::Variable |
| 14603 | + | crate::sema::symtab::SymbolKind::Parameter |
| 14604 | + ) { |
| 14605 | + s.type_info.clone() |
| 14606 | + } else { |
| 14607 | + None |
| 14608 | + } |
| 14609 | + }); |
| 14610 | + let Some(t) = result_ti else { |
| 14611 | + return None; |
| 14612 | + }; |
| 14554 | 14613 | match &common { |
| 14555 | 14614 | None => common = Some(t), |
| 14556 | 14615 | Some(c) => { |
@@ -14571,10 +14630,7 @@ fn assignment_expr_type_info( |
| 14571 | 14630 | } |
| 14572 | 14631 | } |
| 14573 | 14632 | |
| 14574 | | -fn same_type_info( |
| 14575 | | - a: &crate::sema::symtab::TypeInfo, |
| 14576 | | - b: &crate::sema::symtab::TypeInfo, |
| 14577 | | -) -> bool { |
| 14633 | +fn same_type_info(a: &crate::sema::symtab::TypeInfo, b: &crate::sema::symtab::TypeInfo) -> bool { |
| 14578 | 14634 | use crate::sema::symtab::TypeInfo; |
| 14579 | 14635 | match (a, b) { |
| 14580 | 14636 | (TypeInfo::Derived(a), TypeInfo::Derived(b)) => a.eq_ignore_ascii_case(b), |
@@ -14733,12 +14789,16 @@ fn generic_declared_semantic_match( |
| 14733 | 14789 | }; |
| 14734 | 14790 | |
| 14735 | 14791 | match declared { |
| 14736 | | - TypeInfo::Integer { kind: declared_kind } => matches!( |
| 14792 | + TypeInfo::Integer { |
| 14793 | + kind: declared_kind, |
| 14794 | + } => matches!( |
| 14737 | 14795 | actual, |
| 14738 | 14796 | TypeInfo::Integer { kind: actual_kind } |
| 14739 | 14797 | if intrinsic_kind_matches(*declared_kind, *actual_kind) |
| 14740 | 14798 | ), |
| 14741 | | - TypeInfo::Real { kind: declared_kind } => match actual { |
| 14799 | + TypeInfo::Real { |
| 14800 | + kind: declared_kind, |
| 14801 | + } => match actual { |
| 14742 | 14802 | TypeInfo::Real { kind: actual_kind } => { |
| 14743 | 14803 | intrinsic_kind_matches(*declared_kind, *actual_kind) |
| 14744 | 14804 | } |
@@ -14747,17 +14807,18 @@ fn generic_declared_semantic_match( |
| 14747 | 14807 | }, |
| 14748 | 14808 | TypeInfo::DoublePrecision => matches!( |
| 14749 | 14809 | actual, |
| 14750 | | - TypeInfo::DoublePrecision |
| 14751 | | - | TypeInfo::Real { |
| 14752 | | - kind: Some(8), |
| 14753 | | - } |
| 14810 | + TypeInfo::DoublePrecision | TypeInfo::Real { kind: Some(8) } |
| 14754 | 14811 | ), |
| 14755 | | - TypeInfo::Complex { kind: declared_kind } => matches!( |
| 14812 | + TypeInfo::Complex { |
| 14813 | + kind: declared_kind, |
| 14814 | + } => matches!( |
| 14756 | 14815 | actual, |
| 14757 | 14816 | TypeInfo::Complex { kind: actual_kind } |
| 14758 | 14817 | if intrinsic_kind_matches(*declared_kind, *actual_kind) |
| 14759 | 14818 | ), |
| 14760 | | - TypeInfo::Logical { kind: declared_kind } => matches!( |
| 14819 | + TypeInfo::Logical { |
| 14820 | + kind: declared_kind, |
| 14821 | + } => matches!( |
| 14761 | 14822 | actual, |
| 14762 | 14823 | TypeInfo::Logical { kind: actual_kind } |
| 14763 | 14824 | if intrinsic_kind_matches(*declared_kind, *actual_kind) |
@@ -14770,8 +14831,7 @@ fn generic_declared_semantic_match( |
| 14770 | 14831 | TypeInfo::Class(decl_name) => match actual { |
| 14771 | 14832 | TypeInfo::Derived(actual_name) | TypeInfo::Class(actual_name) => { |
| 14772 | 14833 | actual_name.eq_ignore_ascii_case(decl_name) |
| 14773 | | - || type_layouts |
| 14774 | | - .is_some_and(|tl| is_type_or_extends(actual_name, decl_name, tl)) |
| 14834 | + || type_layouts.is_some_and(|tl| is_type_or_extends(actual_name, decl_name, tl)) |
| 14775 | 14835 | } |
| 14776 | 14836 | _ => false, |
| 14777 | 14837 | }, |
@@ -14789,9 +14849,7 @@ fn generic_declared_semantic_match( |
| 14789 | 14849 | } |
| 14790 | 14850 | } |
| 14791 | 14851 | |
| 14792 | | -fn local_semantic_type_info( |
| 14793 | | - info: &LocalInfo, |
| 14794 | | -) -> Option<crate::sema::symtab::TypeInfo> { |
| 14852 | +fn local_semantic_type_info(info: &LocalInfo) -> Option<crate::sema::symtab::TypeInfo> { |
| 14795 | 14853 | use crate::sema::symtab::TypeInfo; |
| 14796 | 14854 | |
| 14797 | 14855 | if let Some(type_name) = &info.derived_type { |
@@ -14805,10 +14863,7 @@ fn local_semantic_type_info( |
| 14805 | 14863 | CharKind::Fixed(len) => Some(len), |
| 14806 | 14864 | _ => None, |
| 14807 | 14865 | }; |
| 14808 | | - return Some(TypeInfo::Character { |
| 14809 | | - len, |
| 14810 | | - kind: Some(1), |
| 14811 | | - }); |
| 14866 | + return Some(TypeInfo::Character { len, kind: Some(1) }); |
| 14812 | 14867 | } |
| 14813 | 14868 | |
| 14814 | 14869 | // Detect complex element type. Complex values are stored as |
@@ -14896,12 +14951,8 @@ fn name_expr_type_info( |
| 14896 | 14951 | // declared elsewhere in the same compilation unit. |
| 14897 | 14952 | let is_polymorphic_local = info.is_some_and(|i| i.is_class); |
| 14898 | 14953 | match (local_ti, symbol_ti) { |
| 14899 | | - (Some(_), Some(TypeInfo::ClassStar)) if is_polymorphic_local => { |
| 14900 | | - Some(TypeInfo::ClassStar) |
| 14901 | | - } |
| 14902 | | - (Some(_), Some(TypeInfo::TypeStar)) if is_polymorphic_local => { |
| 14903 | | - Some(TypeInfo::TypeStar) |
| 14904 | | - } |
| 14954 | + (Some(_), Some(TypeInfo::ClassStar)) if is_polymorphic_local => Some(TypeInfo::ClassStar), |
| 14955 | + (Some(_), Some(TypeInfo::TypeStar)) if is_polymorphic_local => Some(TypeInfo::TypeStar), |
| 14905 | 14956 | (Some(local), _) => Some(local), |
| 14906 | 14957 | (None, Some(ti)) => Some(ti.clone()), |
| 14907 | 14958 | (None, None) => None, |
@@ -14939,9 +14990,7 @@ fn derived_constructor_type_info( |
| 14939 | 14990 | st: &SymbolTable, |
| 14940 | 14991 | ) -> Option<crate::sema::symtab::TypeInfo> { |
| 14941 | 14992 | let key = callee_name.to_ascii_lowercase(); |
| 14942 | | - let sym = st |
| 14943 | | - .lookup(&key) |
| 14944 | | - .or_else(|| st.find_symbol_any_scope(&key))?; |
| 14993 | + let sym = st.lookup(&key).or_else(|| st.find_symbol_any_scope(&key))?; |
| 14945 | 14994 | if sym.kind == crate::sema::symtab::SymbolKind::DerivedType { |
| 14946 | 14995 | Some( |
| 14947 | 14996 | sym.type_info |
@@ -14992,7 +15041,8 @@ fn operator_expr_type_info( |
| 14992 | 15041 | } |
| 14993 | 15042 | Expr::Name { name } => { |
| 14994 | 15043 | let key = name.to_lowercase(); |
| 14995 | | - let symbol_ti = st.lookup(&key) |
| 15044 | + let symbol_ti = st |
| 15045 | + .lookup(&key) |
| 14996 | 15046 | .and_then(|sym| sym.type_info.clone()) |
| 14997 | 15047 | .or_else(|| { |
| 14998 | 15048 | st.find_symbol_any_scope(&key) |
@@ -15044,9 +15094,7 @@ fn operator_expr_type_info( |
| 15044 | 15094 | .or_else(|| generic_function_call_type_info(expr, locals, st, type_layouts)) |
| 15045 | 15095 | .or_else(|| local_intrinsic_call_type_info(expr, locals, st, type_layouts)) |
| 15046 | 15096 | .or_else(|| derived_constructor_type_info(name, st)) |
| 15047 | | - .or_else(|| { |
| 15048 | | - fortran_type_to_type_info(&crate::sema::types::expr_type(expr, st)) |
| 15049 | | - }) |
| 15097 | + .or_else(|| fortran_type_to_type_info(&crate::sema::types::expr_type(expr, st))) |
| 15050 | 15098 | } else { |
| 15051 | 15099 | None |
| 15052 | 15100 | } |
@@ -15193,7 +15241,8 @@ fn generic_actual_expr_type_info( |
| 15193 | 15241 | match &expr.node { |
| 15194 | 15242 | Expr::Name { name } => { |
| 15195 | 15243 | let key = name.to_lowercase(); |
| 15196 | | - let symbol_ti = st.lookup(&key) |
| 15244 | + let symbol_ti = st |
| 15245 | + .lookup(&key) |
| 15197 | 15246 | .and_then(|sym| sym.type_info.clone()) |
| 15198 | 15247 | .or_else(|| { |
| 15199 | 15248 | st.find_symbol_any_scope(&key) |
@@ -15358,11 +15407,16 @@ fn array_expr_elem_type_only( |
| 15358 | 15407 | if (left_arr.is_some() || right_arr.is_some()) |
| 15359 | 15408 | && matches!( |
| 15360 | 15409 | op, |
| 15361 | | - BinaryOp::Eq | BinaryOp::Ne |
| 15362 | | - | BinaryOp::Lt | BinaryOp::Le |
| 15363 | | - | BinaryOp::Gt | BinaryOp::Ge |
| 15364 | | - | BinaryOp::And | BinaryOp::Or |
| 15365 | | - | BinaryOp::Eqv | BinaryOp::Neqv |
| 15410 | + BinaryOp::Eq |
| 15411 | + | BinaryOp::Ne |
| 15412 | + | BinaryOp::Lt |
| 15413 | + | BinaryOp::Le |
| 15414 | + | BinaryOp::Gt |
| 15415 | + | BinaryOp::Ge |
| 15416 | + | BinaryOp::And |
| 15417 | + | BinaryOp::Or |
| 15418 | + | BinaryOp::Eqv |
| 15419 | + | BinaryOp::Neqv |
| 15366 | 15420 | ) |
| 15367 | 15421 | { |
| 15368 | 15422 | return Some(IrType::Bool); |
@@ -15551,13 +15605,12 @@ fn try_defined_assignment( |
| 15551 | 15605 | // where_at (`set_cwd ` padded to 32, low bytes spaces, hex |
| 15552 | 15606 | // 0x2020...20$). Crashed every fs example via set_cwd's |
| 15553 | 15607 | // error_handling path. |
| 15554 | | - let lhs_val = if lhs_info.by_ref |
| 15555 | | - && (lhs_info.is_class || local_uses_array_descriptor(&lhs_info)) |
| 15556 | | - { |
| 15557 | | - b.load(lhs_info.addr) |
| 15558 | | - } else { |
| 15559 | | - lhs_info.addr |
| 15560 | | - }; |
| 15608 | + let lhs_val = |
| 15609 | + if lhs_info.by_ref && (lhs_info.is_class || local_uses_array_descriptor(&lhs_info)) { |
| 15610 | + b.load(lhs_info.addr) |
| 15611 | + } else { |
| 15612 | + lhs_info.addr |
| 15613 | + }; |
| 15561 | 15614 | |
| 15562 | 15615 | // The semantic_candidates filter above already proved that at |
| 15563 | 15616 | // least one specific in `interface assignment(=)` matches both |
@@ -15699,7 +15752,10 @@ fn try_defined_assignment( |
| 15699 | 15752 | // the slot returns the literal byte pattern instead of the real |
| 15700 | 15753 | // data address. |
| 15701 | 15754 | let mask = cached_param_mask_for_lookup(ctx.st, ctx.char_len_star_params, &rk); |
| 15702 | | - let rhs_is_char_star = mask.as_ref().and_then(|m| m.get(1).copied()).unwrap_or(false); |
| 15755 | + let rhs_is_char_star = mask |
| 15756 | + .as_ref() |
| 15757 | + .and_then(|m| m.get(1).copied()) |
| 15758 | + .unwrap_or(false); |
| 15703 | 15759 | let rhs_for_call_final = if rhs_is_char_star { |
| 15704 | 15760 | lower_char_arg_by_ref( |
| 15705 | 15761 | b, |
@@ -16045,9 +16101,8 @@ fn emit_resolved_operator_call( |
| 16045 | 16101 | first_procedure_lookup(&abi_lookup_keys, |k| callee_class_arg_mask(st, k)); |
| 16046 | 16102 | let callee_char_len_star_args = |
| 16047 | 16103 | first_procedure_lookup(&abi_lookup_keys, |k| callee_char_len_star_mask(st, k)); |
| 16048 | | - let hidden_result = hidden_abi.and_then(|abi| { |
| 16049 | | - allocate_hidden_result_buffer(b, st, type_layouts, &abi_lookup_keys, abi) |
| 16050 | | - }); |
| 16104 | + let hidden_result = hidden_abi |
| 16105 | + .and_then(|abi| allocate_hidden_result_buffer(b, st, type_layouts, &abi_lookup_keys, abi)); |
| 16051 | 16106 | |
| 16052 | 16107 | let mut call_args = Vec::with_capacity(2 + hidden_result.is_some() as usize + 4); |
| 16053 | 16108 | let mut char_actual_lens = [None, None]; |
@@ -16518,10 +16573,7 @@ fn scope_matches_procedure_name(scope: &crate::sema::symtab::Scope, name: &str) |
| 16518 | 16573 | ) |
| 16519 | 16574 | } |
| 16520 | 16575 | |
| 16521 | | -fn scope_has_linkable_parent( |
| 16522 | | - st: &SymbolTable, |
| 16523 | | - scope_id: crate::sema::symtab::ScopeId, |
| 16524 | | -) -> bool { |
| 16576 | +fn scope_has_linkable_parent(st: &SymbolTable, scope_id: crate::sema::symtab::ScopeId) -> bool { |
| 16525 | 16577 | let Some(parent_id) = st.scope(scope_id).parent else { |
| 16526 | 16578 | return false; |
| 16527 | 16579 | }; |
@@ -16570,9 +16622,7 @@ fn find_procedure_scope_id_for_caller( |
| 16570 | 16622 | while let Some(cur_id) = cur { |
| 16571 | 16623 | let cur_scope = st.scope(cur_id); |
| 16572 | 16624 | // Self-match (recursive call to caller itself). |
| 16573 | | - if scope_matches_procedure_name(cur_scope, name) |
| 16574 | | - && scope_has_linkable_parent(st, cur_id) |
| 16575 | | - { |
| 16625 | + if scope_matches_procedure_name(cur_scope, name) && scope_has_linkable_parent(st, cur_id) { |
| 16576 | 16626 | return Some(cur_id); |
| 16577 | 16627 | } |
| 16578 | 16628 | // Sibling/host-contained match: any procedure scope whose |
@@ -16656,9 +16706,7 @@ fn lowered_scope_symbol_name( |
| 16656 | 16706 | .iter() |
| 16657 | 16707 | .find(|u| u.is_submodule_access) |
| 16658 | 16708 | .and_then(|u| match &st.scope(u.source_scope).kind { |
| 16659 | | - crate::sema::symtab::ScopeKind::Module(n) => { |
| 16660 | | - Some(n.to_lowercase()) |
| 16661 | | - } |
| 16709 | + crate::sema::symtab::ScopeKind::Module(n) => Some(n.to_lowercase()), |
| 16662 | 16710 | _ => None, |
| 16663 | 16711 | }); |
| 16664 | 16712 | if let Some(parent_lc) = parent_lc { |
@@ -16701,8 +16749,7 @@ fn same_unit_func_ref( |
| 16701 | 16749 | // in the sort submodule), so `int32_increase_sort`'s introsort |
| 16702 | 16750 | // would silently call into bitset_large_decrease's helpers. |
| 16703 | 16751 | let caller_scope = current_proc_scope(); |
| 16704 | | - let Some(scope_id) = find_procedure_scope_id_for_caller(st, matched_key, caller_scope) |
| 16705 | | - else { |
| 16752 | + let Some(scope_id) = find_procedure_scope_id_for_caller(st, matched_key, caller_scope) else { |
| 16706 | 16753 | return FuncRef::External(fallback_call_name); |
| 16707 | 16754 | }; |
| 16708 | 16755 | let Some(lowered) = lowered_scope_symbol_name(st, internal_funcs, scope_id) else { |
@@ -16733,9 +16780,7 @@ fn symbol_link_name(st: &SymbolTable, sym: &crate::sema::symtab::Symbol) -> Stri |
| 16733 | 16780 | .iter() |
| 16734 | 16781 | .find(|u| u.is_submodule_access) |
| 16735 | 16782 | .and_then(|u| match &st.scope(u.source_scope).kind { |
| 16736 | | - crate::sema::symtab::ScopeKind::Module(n) => { |
| 16737 | | - Some(n.to_lowercase()) |
| 16738 | | - } |
| 16783 | + crate::sema::symtab::ScopeKind::Module(n) => Some(n.to_lowercase()), |
| 16739 | 16784 | _ => None, |
| 16740 | 16785 | }) |
| 16741 | 16786 | { |
@@ -17417,8 +17462,8 @@ fn emit_resolved_bound_proc_call( |
| 17417 | 17462 | // the caller (the memcpy-and-stamp polymorphic |
| 17418 | 17463 | // view would otherwise hide callee writes |
| 17419 | 17464 | // behind a copy). |
| 17420 | | - let force_box = wants_polymorphic_descriptor |
| 17421 | | - && !matches!(e.node, Expr::Name { .. }); |
| 17465 | + let force_box = |
| 17466 | + wants_polymorphic_descriptor && !matches!(e.node, Expr::Name { .. }); |
| 17422 | 17467 | lower_arg_descriptor(b, locals, e, st, type_layouts, force_box) |
| 17423 | 17468 | } else if wants_string_descriptor { |
| 17424 | 17469 | lower_arg_string_descriptor(b, locals, e, st, type_layouts) |
@@ -17527,7 +17572,12 @@ fn emit_resolved_bound_proc_call( |
| 17527 | 17572 | let call_result = b.call(func_ref, call_args, ret_ty); |
| 17528 | 17573 | if let Some(tl) = type_layouts { |
| 17529 | 17574 | if let Some(type_name) = callee_return_stabilized_derived_type_name(st, &target_key) { |
| 17530 | | - return Some(stabilize_derived_call_result(b, tl, &type_name, call_result)); |
| 17575 | + return Some(stabilize_derived_call_result( |
| 17576 | + b, |
| 17577 | + tl, |
| 17578 | + &type_name, |
| 17579 | + call_result, |
| 17580 | + )); |
| 17531 | 17581 | } |
| 17532 | 17582 | } |
| 17533 | 17583 | Some(call_result) |
@@ -17571,21 +17621,19 @@ fn emit_dynamic_bound_proc_lookup_dispatch( |
| 17571 | 17621 | component, |
| 17572 | 17622 | &declared_bp.abi_name, |
| 17573 | 17623 | ); |
| 17574 | | - let slot_index = base_layout |
| 17575 | | - .bound_procs |
| 17576 | | - .iter() |
| 17577 | | - .position(|bp| { |
| 17578 | | - bp.method_name.eq_ignore_ascii_case(component) |
| 17579 | | - && bp.abi_name.eq_ignore_ascii_case(&declared_bp.abi_name) |
| 17580 | | - })? as i64; |
| 17624 | + let slot_index = base_layout.bound_procs.iter().position(|bp| { |
| 17625 | + bp.method_name.eq_ignore_ascii_case(component) |
| 17626 | + && bp.abi_name.eq_ignore_ascii_case(&declared_bp.abi_name) |
| 17627 | + })? as i64; |
| 17581 | 17628 | let call_ret_ty = if let Some(ret_ty) = explicit_ret_ty { |
| 17582 | 17629 | ret_ty |
| 17583 | 17630 | } else { |
| 17584 | 17631 | let target_key = abi_key_for_link_name(st, &declared_bp.target_name) |
| 17585 | 17632 | .unwrap_or_else(|| declared_bp.abi_name.clone()); |
| 17586 | | - first_procedure_lookup(&procedure_abi_lookup_keys(st, &[declared_bp.target_name.as_str(), &target_key]), |k| { |
| 17587 | | - callee_return_ir_type(st, k) |
| 17588 | | - }) |
| 17633 | + first_procedure_lookup( |
| 17634 | + &procedure_abi_lookup_keys(st, &[declared_bp.target_name.as_str(), &target_key]), |
| 17635 | + |k| callee_return_ir_type(st, k), |
| 17636 | + ) |
| 17589 | 17637 | .unwrap_or(IrType::Int(IntWidth::I32)) |
| 17590 | 17638 | }; |
| 17591 | 17639 | let returns_value = call_ret_ty != IrType::Void; |
@@ -17764,21 +17812,14 @@ fn resolve_polymorphic_component_method_base_for_dispatch( |
| 17764 | 17812 | .and_then(|sym| sym.type_info.as_ref()) |
| 17765 | 17813 | })?; |
| 17766 | 17814 | let base_type = match type_info { |
| 17767 | | - crate::sema::symtab::TypeInfo::Class(base_type) => canonical_layout_type_name_for_scope( |
| 17768 | | - st, |
| 17769 | | - proc_scope_id, |
| 17770 | | - base_type, |
| 17771 | | - tl, |
| 17772 | | - ) |
| 17773 | | - .or_else(|| Some(base_type.clone()))?, |
| 17815 | + crate::sema::symtab::TypeInfo::Class(base_type) => { |
| 17816 | + canonical_layout_type_name_for_scope(st, proc_scope_id, base_type, tl) |
| 17817 | + .or_else(|| Some(base_type.clone()))? |
| 17818 | + } |
| 17774 | 17819 | crate::sema::symtab::TypeInfo::Derived(base_type) => { |
| 17775 | | - let layout_name = canonical_layout_type_name_for_scope( |
| 17776 | | - st, |
| 17777 | | - proc_scope_id, |
| 17778 | | - base_type, |
| 17779 | | - tl, |
| 17780 | | - ) |
| 17781 | | - .or_else(|| Some(base_type.clone()))?; |
| 17820 | + let layout_name = |
| 17821 | + canonical_layout_type_name_for_scope(st, proc_scope_id, base_type, tl) |
| 17822 | + .or_else(|| Some(base_type.clone()))?; |
| 17782 | 17823 | tl.get(&layout_name) |
| 17783 | 17824 | .filter(|layout| layout.is_abstract) |
| 17784 | 17825 | .map(|_| layout_name)? |
@@ -17786,7 +17827,8 @@ fn resolve_polymorphic_component_method_base_for_dispatch( |
| 17786 | 17827 | _ => return None, |
| 17787 | 17828 | }; |
| 17788 | 17829 | let desc_addr = array_descriptor_addr(b, info); |
| 17789 | | - let obj_addr = b.load_typed(desc_addr, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 17830 | + let obj_addr = |
| 17831 | + b.load_typed(desc_addr, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 17790 | 17832 | Some((desc_addr, obj_addr, base_type)) |
| 17791 | 17833 | } |
| 17792 | 17834 | Expr::ComponentAccess { .. } => { |
@@ -17799,7 +17841,8 @@ fn resolve_polymorphic_component_method_base_for_dispatch( |
| 17799 | 17841 | return None; |
| 17800 | 17842 | } |
| 17801 | 17843 | let base_type = abstract_layout_base_type(tl, &field.type_info)?; |
| 17802 | | - let obj_addr = b.load_typed(desc_addr, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 17844 | + let obj_addr = |
| 17845 | + b.load_typed(desc_addr, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 17803 | 17846 | Some((desc_addr, obj_addr, base_type)) |
| 17804 | 17847 | } |
| 17805 | 17848 | _ => None, |
@@ -19157,7 +19200,8 @@ fn arg_type_from_decls( |
| 19157 | 19200 | decls: &[crate::ast::decl::SpannedDecl], |
| 19158 | 19201 | st: Option<&SymbolTable>, |
| 19159 | 19202 | ) -> IrType { |
| 19160 | | - let local_param_consts = st.map(|st| collect_decl_param_consts_with_scope(decls, &HashMap::new(), st)); |
| 19203 | + let local_param_consts = |
| 19204 | + st.map(|st| collect_decl_param_consts_with_scope(decls, &HashMap::new(), st)); |
| 19161 | 19205 | if let Some(type_spec) = declared_type_spec_for_name(arg_name, decls) { |
| 19162 | 19206 | return lower_type_spec_with_param_consts(type_spec, local_param_consts.as_ref(), st); |
| 19163 | 19207 | } |
@@ -19369,9 +19413,7 @@ fn install_assumed_shape_lower_overrides( |
| 19369 | 19413 | // because we only redirect `info.addr` to the local copy on |
| 19370 | 19414 | // the present path; the original null stays in the slot when |
| 19371 | 19415 | // absent). |
| 19372 | | - let entity_is_optional = attrs |
| 19373 | | - .iter() |
| 19374 | | - .any(|a| matches!(a, Attribute::Optional)); |
| 19416 | + let entity_is_optional = attrs.iter().any(|a| matches!(a, Attribute::Optional)); |
| 19375 | 19417 | for entity in entities { |
| 19376 | 19418 | let key = entity.name.to_lowercase(); |
| 19377 | 19419 | let Some(info) = locals.get(&key) else { |
@@ -19401,8 +19443,9 @@ fn install_assumed_shape_lower_overrides( |
| 19401 | 19443 | // decls reaching this pass. For non-allocatable, |
| 19402 | 19444 | // non-pointer dummies (already filtered above) this |
| 19403 | 19445 | // means assumed-shape with default lower bound = 1. |
| 19404 | | - ArraySpec::Deferred |
| 19405 | | - | ArraySpec::AssumedShape { lower: None } => Some(LowerTarget::One), |
| 19446 | + ArraySpec::Deferred | ArraySpec::AssumedShape { lower: None } => { |
| 19447 | + Some(LowerTarget::One) |
| 19448 | + } |
| 19406 | 19449 | ArraySpec::AssumedShape { lower: Some(e) } => { |
| 19407 | 19450 | match eval_const_scalar(e, visible_param_consts) { |
| 19408 | 19451 | Some(ConstScalar::Int(1)) => Some(LowerTarget::One), |
@@ -19422,10 +19465,7 @@ fn install_assumed_shape_lower_overrides( |
| 19422 | 19465 | |
| 19423 | 19466 | let slot = info.addr; |
| 19424 | 19467 | let original_desc_ptr = b.load(slot); |
| 19425 | | - let local_desc = b.alloca(IrType::Array( |
| 19426 | | - Box::new(IrType::Int(IntWidth::I8)), |
| 19427 | | - 384, |
| 19428 | | - )); |
| 19468 | + let local_desc = b.alloca(IrType::Array(Box::new(IrType::Int(IntWidth::I8)), 384)); |
| 19429 | 19469 | |
| 19430 | 19470 | // For optional dummies, the actual may be absent — caller |
| 19431 | 19471 | // passes a null descriptor pointer in that case. Guard the |
@@ -19458,13 +19498,8 @@ fn install_assumed_shape_lower_overrides( |
| 19458 | 19498 | let new_lo_i64 = match target { |
| 19459 | 19499 | LowerTarget::One => b.const_i64(1), |
| 19460 | 19500 | LowerTarget::Expr(e) => { |
| 19461 | | - let raw = lower_expr_with_optional_layouts( |
| 19462 | | - b, |
| 19463 | | - locals, |
| 19464 | | - e, |
| 19465 | | - st, |
| 19466 | | - Some(type_layouts), |
| 19467 | | - ); |
| 19501 | + let raw = |
| 19502 | + lower_expr_with_optional_layouts(b, locals, e, st, Some(type_layouts)); |
| 19468 | 19503 | match b.func().value_type(raw) { |
| 19469 | 19504 | Some(IrType::Int(IntWidth::I64)) => raw, |
| 19470 | 19505 | _ => b.int_extend(raw, IntWidth::I64, true), |
@@ -19573,10 +19608,7 @@ fn install_explicit_shape_dummy_rebase( |
| 19573 | 19608 | let rank = specs.len() as i32; |
| 19574 | 19609 | let slot = info.addr; |
| 19575 | 19610 | let original_desc_ptr = b.load(slot); |
| 19576 | | - let local_desc = b.alloca(IrType::Array( |
| 19577 | | - Box::new(IrType::Int(IntWidth::I8)), |
| 19578 | | - 384, |
| 19579 | | - )); |
| 19611 | + let local_desc = b.alloca(IrType::Array(Box::new(IrType::Int(IntWidth::I8)), 384)); |
| 19580 | 19612 | let bytes = b.const_i64(384); |
| 19581 | 19613 | b.call( |
| 19582 | 19614 | FuncRef::External("memcpy".into()), |
@@ -19796,7 +19828,10 @@ fn allocate_runtime_shape_array_result( |
| 19796 | 19828 | |
| 19797 | 19829 | let rank = specs.len() as u64; |
| 19798 | 19830 | let bounds_bytes = rank * 24; |
| 19799 | | - let bounds = b.alloca(IrType::Array(Box::new(IrType::Int(IntWidth::I8)), bounds_bytes)); |
| 19831 | + let bounds = b.alloca(IrType::Array( |
| 19832 | + Box::new(IrType::Int(IntWidth::I8)), |
| 19833 | + bounds_bytes, |
| 19834 | + )); |
| 19800 | 19835 | let one64 = b.const_i64(1); |
| 19801 | 19836 | for (i, (lo, hi)) in lowers.iter().zip(uppers.iter()).enumerate() { |
| 19802 | 19837 | let off_lo = b.const_i64((i as i64) * 24); |
@@ -19847,10 +19882,7 @@ fn arg_derived_type_name( |
| 19847 | 19882 | None |
| 19848 | 19883 | } |
| 19849 | 19884 | |
| 19850 | | -fn decl_is_class( |
| 19851 | | - name: &str, |
| 19852 | | - decls: &[crate::ast::decl::SpannedDecl], |
| 19853 | | -) -> bool { |
| 19885 | +fn decl_is_class(name: &str, decls: &[crate::ast::decl::SpannedDecl]) -> bool { |
| 19854 | 19886 | let key = name.to_lowercase(); |
| 19855 | 19887 | for decl in decls { |
| 19856 | 19888 | if let Decl::TypeDecl { |
@@ -20499,7 +20531,7 @@ fn install_host_ref_locals( |
| 20499 | 20531 | is_pointer: info.is_pointer, |
| 20500 | 20532 | runtime_dim_upper: vec![], |
| 20501 | 20533 | is_class: false, |
| 20502 | | - logical_kind: None, |
| 20534 | + logical_kind: None, |
| 20503 | 20535 | last_dim_assumed_size: false, |
| 20504 | 20536 | }, |
| 20505 | 20537 | ); |
@@ -20509,7 +20541,10 @@ fn install_host_ref_locals( |
| 20509 | 20541 | /// Check if a callee has VALUE-attributed arguments via its scope in the symbol table. |
| 20510 | 20542 | /// Returns a Vec<bool> per argument position — true if that arg is VALUE. |
| 20511 | 20543 | /// Returns None if callee scope not found or no VALUE args. |
| 20512 | | -fn callee_scope_id_for_lookup(st: &SymbolTable, callee_name: &str) -> Option<crate::sema::symtab::ScopeId> { |
| 20544 | +fn callee_scope_id_for_lookup( |
| 20545 | + st: &SymbolTable, |
| 20546 | + callee_name: &str, |
| 20547 | +) -> Option<crate::sema::symtab::ScopeId> { |
| 20513 | 20548 | use crate::sema::symtab::{ScopeKind, SymbolKind}; |
| 20514 | 20549 | |
| 20515 | 20550 | let mut name_match = None; |
@@ -21003,15 +21038,8 @@ fn resolved_named_character_return_abi_for_call( |
| 21003 | 21038 | _ => b.const_i32(0), |
| 21004 | 21039 | }) |
| 21005 | 21040 | .collect(); |
| 21006 | | - let resolved = resolve_generic_call_actuals( |
| 21007 | | - st, |
| 21008 | | - b, |
| 21009 | | - Some(locals), |
| 21010 | | - &key, |
| 21011 | | - args, |
| 21012 | | - &probe_vals, |
| 21013 | | - type_layouts, |
| 21014 | | - )?; |
| 21041 | + let resolved = |
| 21042 | + resolve_generic_call_actuals(st, b, Some(locals), &key, args, &probe_vals, type_layouts)?; |
| 21015 | 21043 | callee_character_return_abi(st, &resolved.name) |
| 21016 | 21044 | } |
| 21017 | 21045 | |
@@ -22030,8 +22058,7 @@ fn lower_string_expr_full( |
| 22030 | 22058 | right, |
| 22031 | 22059 | lhs, |
| 22032 | 22060 | rhs, |
| 22033 | | - ) |
| 22034 | | - { |
| 22061 | + ) { |
| 22035 | 22062 | let specific_key = specific.to_lowercase(); |
| 22036 | 22063 | let char_abi = callee_character_return_abi(st, &specific_key); |
| 22037 | 22064 | let result = emit_resolved_operator_call( |
@@ -22409,14 +22436,13 @@ fn extract_kind_with_context( |
| 22409 | 22436 | use crate::ast::decl::KindSelector; |
| 22410 | 22437 | use crate::ast::expr::Expr; |
| 22411 | 22438 | match sel { |
| 22412 | | - Some(KindSelector::Expr(e)) | Some(KindSelector::Star(e)) => { |
| 22413 | | - match &e.node { |
| 22414 | | - Expr::IntegerLiteral { text, .. } => text.parse().unwrap_or(default), |
| 22415 | | - Expr::Name { name } => named_kind_value(name, None, param_consts, st) |
| 22416 | | - .unwrap_or(default), |
| 22417 | | - _ => default, |
| 22439 | + Some(KindSelector::Expr(e)) | Some(KindSelector::Star(e)) => match &e.node { |
| 22440 | + Expr::IntegerLiteral { text, .. } => text.parse().unwrap_or(default), |
| 22441 | + Expr::Name { name } => { |
| 22442 | + named_kind_value(name, None, param_consts, st).unwrap_or(default) |
| 22418 | 22443 | } |
| 22419 | | - } |
| 22444 | + _ => default, |
| 22445 | + }, |
| 22420 | 22446 | None => default, |
| 22421 | 22447 | } |
| 22422 | 22448 | } |
@@ -22789,13 +22815,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 22789 | 22815 | let alloc_bb = b.create_block("scalar_derived_assign_alloc"); |
| 22790 | 22816 | let copy_bb = b.create_block("scalar_derived_assign_copy"); |
| 22791 | 22817 | let done_bb = b.create_block("scalar_derived_assign_done"); |
| 22792 | | - b.cond_branch( |
| 22793 | | - needs_alloc, |
| 22794 | | - alloc_bb, |
| 22795 | | - vec![], |
| 22796 | | - copy_bb, |
| 22797 | | - vec![], |
| 22798 | | - ); |
| 22818 | + b.cond_branch(needs_alloc, alloc_bb, vec![], copy_bb, vec![]); |
| 22799 | 22819 | |
| 22800 | 22820 | b.set_block(alloc_bb); |
| 22801 | 22821 | if let Some(ref tn) = info.derived_type { |
@@ -22905,15 +22925,17 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 22905 | 22925 | .contains(&s.to_lowercase()) |
| 22906 | 22926 | || ctx |
| 22907 | 22927 | .st |
| 22908 | | - .find_symbol_any_scope(s) |
| 22928 | + .find_symbol_any_scope( |
| 22929 | + s, |
| 22930 | + ) |
| 22909 | 22931 | .is_some_and(|sym| { |
| 22910 | 22932 | sym.attrs.elemental |
| 22911 | 22933 | }) |
| 22912 | 22934 | }) |
| 22913 | 22935 | }) |
| 22914 | 22936 | .unwrap_or(false); |
| 22915 | | - let is_elemental = direct_elemental |
| 22916 | | - || generic_specifics_elemental; |
| 22937 | + let is_elemental = |
| 22938 | + direct_elemental || generic_specifics_elemental; |
| 22917 | 22939 | is_elemental |
| 22918 | 22940 | && call_args.iter().any(|arg| { |
| 22919 | 22941 | matches!( |
@@ -22953,8 +22975,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 22953 | 22975 | // a single complex(4) const-zero |
| 22954 | 22976 | // buffer — wrong shape and wrong kind. |
| 22955 | 22977 | | "cmplx" |
| 22956 | | - ) |
| 22957 | | - || ( |
| 22978 | + ) || ( |
| 22958 | 22979 | // sum(arr, dim) is rank-N-1: route to |
| 22959 | 22980 | // lower_array_assign so the sum-dim arm |
| 22960 | 22981 | // in lower_array_expr_descriptor fills |
@@ -22963,11 +22984,16 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 22963 | 22984 | // assignment falls through to scalar |
| 22964 | 22985 | // broadcast. |
| 22965 | 22986 | lname == "sum" |
| 22966 | | - && call_args.iter().enumerate().any(|(i, a)| { |
| 22967 | | - let kw = a.keyword.as_deref().map(|s| s.to_lowercase()); |
| 22968 | | - matches!(kw.as_deref(), Some("dim")) |
| 22969 | | - || (i == 1 && kw.is_none()) |
| 22970 | | - }) |
| 22987 | + && call_args.iter().enumerate().any( |
| 22988 | + |(i, a)| { |
| 22989 | + let kw = a |
| 22990 | + .keyword |
| 22991 | + .as_deref() |
| 22992 | + .map(|s| s.to_lowercase()); |
| 22993 | + matches!(kw.as_deref(), Some("dim")) |
| 22994 | + || (i == 1 && kw.is_none()) |
| 22995 | + }, |
| 22996 | + ) |
| 22971 | 22997 | ) |
| 22972 | 22998 | } else { |
| 22973 | 22999 | false |
@@ -23012,7 +23038,9 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 23012 | 23038 | b.call( |
| 23013 | 23039 | FuncRef::External("memset".into()), |
| 23014 | 23040 | vec![tmp_desc, zero32, sz384], |
| 23015 | | - IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 23041 | + IrType::Ptr(Box::new(IrType::Int( |
| 23042 | + IntWidth::I8, |
| 23043 | + ))), |
| 23016 | 23044 | ); |
| 23017 | 23045 | lower_alloc_return_call_into_desc( |
| 23018 | 23046 | b, |
@@ -23022,23 +23050,28 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 23022 | 23050 | call_args, |
| 23023 | 23051 | ); |
| 23024 | 23052 | let n = array_total_elems_value(b, &info); |
| 23025 | | - let elem_bytes = b.const_i64( |
| 23026 | | - ir_scalar_byte_size(&info.ty), |
| 23027 | | - ); |
| 23053 | + let elem_bytes = |
| 23054 | + b.const_i64(ir_scalar_byte_size(&info.ty)); |
| 23028 | 23055 | let byte_count = b.imul(n, elem_bytes); |
| 23029 | 23056 | let src_base = b.load_typed( |
| 23030 | 23057 | tmp_desc, |
| 23031 | | - IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 23058 | + IrType::Ptr(Box::new(IrType::Int( |
| 23059 | + IntWidth::I8, |
| 23060 | + ))), |
| 23032 | 23061 | ); |
| 23033 | 23062 | b.call( |
| 23034 | 23063 | FuncRef::External("memcpy".into()), |
| 23035 | 23064 | vec![info.addr, src_base, byte_count], |
| 23036 | | - IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 23065 | + IrType::Ptr(Box::new(IrType::Int( |
| 23066 | + IntWidth::I8, |
| 23067 | + ))), |
| 23037 | 23068 | ); |
| 23038 | 23069 | let stat = b.alloca(IrType::Int(IntWidth::I32)); |
| 23039 | 23070 | b.store(zero32, stat); |
| 23040 | 23071 | b.call( |
| 23041 | | - FuncRef::External("afs_deallocate_array".into()), |
| 23072 | + FuncRef::External( |
| 23073 | + "afs_deallocate_array".into(), |
| 23074 | + ), |
| 23042 | 23075 | vec![tmp_desc, stat], |
| 23043 | 23076 | IrType::Void, |
| 23044 | 23077 | ); |
@@ -23061,18 +23094,21 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 23061 | 23094 | ); |
| 23062 | 23095 | } else { |
| 23063 | 23096 | let n = array_total_elems_value(b, &info); |
| 23064 | | - let elem_bytes = b.const_i64( |
| 23065 | | - ir_scalar_byte_size(&info.ty), |
| 23066 | | - ); |
| 23097 | + let elem_bytes = |
| 23098 | + b.const_i64(ir_scalar_byte_size(&info.ty)); |
| 23067 | 23099 | let byte_count = b.imul(n, elem_bytes); |
| 23068 | 23100 | let src_base = b.load_typed( |
| 23069 | 23101 | src_desc, |
| 23070 | | - IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 23102 | + IrType::Ptr(Box::new(IrType::Int( |
| 23103 | + IntWidth::I8, |
| 23104 | + ))), |
| 23071 | 23105 | ); |
| 23072 | 23106 | b.call( |
| 23073 | 23107 | FuncRef::External("memcpy".into()), |
| 23074 | 23108 | vec![info.addr, src_base, byte_count], |
| 23075 | | - IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 23109 | + IrType::Ptr(Box::new(IrType::Int( |
| 23110 | + IntWidth::I8, |
| 23111 | + ))), |
| 23076 | 23112 | ); |
| 23077 | 23113 | } |
| 23078 | 23114 | let stat = b.alloca(IrType::Int(IntWidth::I32)); |
@@ -23092,24 +23128,29 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 23092 | 23128 | if local_uses_array_descriptor(&info) { |
| 23093 | 23129 | let dest_desc = array_descriptor_addr(b, &info); |
| 23094 | 23130 | b.call( |
| 23095 | | - FuncRef::External("afs_assign_allocatable".into()), |
| 23131 | + FuncRef::External( |
| 23132 | + "afs_assign_allocatable".into(), |
| 23133 | + ), |
| 23096 | 23134 | vec![dest_desc, src_desc], |
| 23097 | 23135 | IrType::Void, |
| 23098 | 23136 | ); |
| 23099 | 23137 | } else { |
| 23100 | 23138 | let n = array_total_elems_value(b, &info); |
| 23101 | | - let elem_bytes = b.const_i64( |
| 23102 | | - ir_scalar_byte_size(&info.ty), |
| 23103 | | - ); |
| 23139 | + let elem_bytes = |
| 23140 | + b.const_i64(ir_scalar_byte_size(&info.ty)); |
| 23104 | 23141 | let byte_count = b.imul(n, elem_bytes); |
| 23105 | 23142 | let src_base = b.load_typed( |
| 23106 | 23143 | src_desc, |
| 23107 | | - IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 23144 | + IrType::Ptr(Box::new(IrType::Int( |
| 23145 | + IntWidth::I8, |
| 23146 | + ))), |
| 23108 | 23147 | ); |
| 23109 | 23148 | b.call( |
| 23110 | 23149 | FuncRef::External("memcpy".into()), |
| 23111 | 23150 | vec![info.addr, src_base, byte_count], |
| 23112 | | - IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 23151 | + IrType::Ptr(Box::new(IrType::Int( |
| 23152 | + IntWidth::I8, |
| 23153 | + ))), |
| 23113 | 23154 | ); |
| 23114 | 23155 | } |
| 23115 | 23156 | let stat = b.alloca(IrType::Int(IntWidth::I32)); |
@@ -23184,7 +23225,8 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 23184 | 23225 | } |
| 23185 | 23226 | } else if info.is_class |
| 23186 | 23227 | && info.dims.is_empty() |
| 23187 | | - && ctx.st |
| 23228 | + && ctx |
| 23229 | + .st |
| 23188 | 23230 | .find_symbol_any_scope(&key) |
| 23189 | 23231 | .map(|s| s.attrs.allocatable) |
| 23190 | 23232 | .unwrap_or(false) |
@@ -23250,8 +23292,9 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 23250 | 23292 | if let crate::ast::expr::SectionSubscript::Element(idx_expr) = |
| 23251 | 23293 | &args[0].value |
| 23252 | 23294 | { |
| 23253 | | - if let Expr::ArrayConstructor { values: idx_values, .. } = |
| 23254 | | - &idx_expr.node |
| 23295 | + if let Expr::ArrayConstructor { |
| 23296 | + values: idx_values, .. |
| 23297 | + } = &idx_expr.node |
| 23255 | 23298 | { |
| 23256 | 23299 | for v in idx_values { |
| 23257 | 23300 | let crate::ast::expr::AcValue::Expr(scalar_idx) = v |
@@ -23299,17 +23342,9 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 23299 | 23342 | &args[0].value |
| 23300 | 23343 | { |
| 23301 | 23344 | if !matches!(idx_expr.node, Expr::ArrayConstructor { .. }) |
| 23302 | | - && expr_returns_array( |
| 23303 | | - idx_expr, |
| 23304 | | - &ctx.locals, |
| 23305 | | - ctx.st, |
| 23306 | | - ) |
| 23345 | + && expr_returns_array(idx_expr, &ctx.locals, ctx.st) |
| 23307 | 23346 | && lower_dynamic_vector_subscript_assign( |
| 23308 | | - b, |
| 23309 | | - ctx, |
| 23310 | | - &info, |
| 23311 | | - idx_expr, |
| 23312 | | - value, |
| 23347 | + b, ctx, &info, idx_expr, value, |
| 23313 | 23348 | ) |
| 23314 | 23349 | { |
| 23315 | 23350 | return; |
@@ -23881,29 +23916,24 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 23881 | 23916 | // Memcpy the source descriptor. RHS is |
| 23882 | 23917 | // expected to be a polymorphic local or |
| 23883 | 23918 | // another class(*) component access. |
| 23884 | | - let src_desc_opt: Option<ValueId> = |
| 23885 | | - match &value.node { |
| 23886 | | - Expr::ComponentAccess { .. } => { |
| 23887 | | - resolve_component_field_access( |
| 23888 | | - b, |
| 23889 | | - &ctx.locals, |
| 23890 | | - value, |
| 23891 | | - ctx.st, |
| 23892 | | - ctx.type_layouts, |
| 23893 | | - ) |
| 23894 | | - .map(|(p, _)| p) |
| 23895 | | - } |
| 23896 | | - Expr::Name { name } => ctx |
| 23897 | | - .locals |
| 23898 | | - .get(&name.to_lowercase()) |
| 23899 | | - .filter(|info| { |
| 23900 | | - info.is_class && info.dims.is_empty() |
| 23901 | | - }) |
| 23902 | | - .map(|info| { |
| 23903 | | - array_descriptor_addr(b, info) |
| 23904 | | - }), |
| 23905 | | - _ => None, |
| 23906 | | - }; |
| 23919 | + let src_desc_opt: Option<ValueId> = match &value.node { |
| 23920 | + Expr::ComponentAccess { .. } => { |
| 23921 | + resolve_component_field_access( |
| 23922 | + b, |
| 23923 | + &ctx.locals, |
| 23924 | + value, |
| 23925 | + ctx.st, |
| 23926 | + ctx.type_layouts, |
| 23927 | + ) |
| 23928 | + .map(|(p, _)| p) |
| 23929 | + } |
| 23930 | + Expr::Name { name } => ctx |
| 23931 | + .locals |
| 23932 | + .get(&name.to_lowercase()) |
| 23933 | + .filter(|info| info.is_class && info.dims.is_empty()) |
| 23934 | + .map(|info| array_descriptor_addr(b, info)), |
| 23935 | + _ => None, |
| 23936 | + }; |
| 23907 | 23937 | if let Some(src) = src_desc_opt { |
| 23908 | 23938 | let sz = b.const_i64(384); |
| 23909 | 23939 | b.call( |
@@ -24214,8 +24244,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 24214 | 24244 | .as_ref() |
| 24215 | 24245 | .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 24216 | 24246 | .unwrap_or(false); |
| 24217 | | - let wants_string_descriptor = |
| 24218 | | - wants_string_descriptor && !wants_bind_c_char; |
| 24247 | + let wants_string_descriptor = wants_string_descriptor && !wants_bind_c_char; |
| 24219 | 24248 | let value = match slot { |
| 24220 | 24249 | Some(arg) => match &arg.value { |
| 24221 | 24250 | crate::ast::expr::SectionSubscript::Element(e) => { |
@@ -24468,8 +24497,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 24468 | 24497 | .as_ref() |
| 24469 | 24498 | .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 24470 | 24499 | .unwrap_or(false); |
| 24471 | | - let wants_string_descriptor = |
| 24472 | | - wants_string_descriptor && !wants_bind_c_char; |
| 24500 | + let wants_string_descriptor = wants_string_descriptor && !wants_bind_c_char; |
| 24473 | 24501 | let value = match slot { |
| 24474 | 24502 | Some(arg) => match &arg.value { |
| 24475 | 24503 | crate::ast::expr::SectionSubscript::Element(e) => { |
@@ -24830,7 +24858,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 24830 | 24858 | is_pointer: false, |
| 24831 | 24859 | runtime_dim_upper: vec![], |
| 24832 | 24860 | is_class: false, |
| 24833 | | - logical_kind: None, |
| 24861 | + logical_kind: None, |
| 24834 | 24862 | last_dim_assumed_size: false, |
| 24835 | 24863 | }, |
| 24836 | 24864 | ); |
@@ -24994,7 +25022,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 24994 | 25022 | is_pointer: false, |
| 24995 | 25023 | runtime_dim_upper: vec![], |
| 24996 | 25024 | is_class: false, |
| 24997 | | - logical_kind: None, |
| 25025 | + logical_kind: None, |
| 24998 | 25026 | last_dim_assumed_size: false, |
| 24999 | 25027 | }, |
| 25000 | 25028 | ); |
@@ -25057,8 +25085,12 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 25057 | 25085 | .. |
| 25058 | 25086 | } => { |
| 25059 | 25087 | let bb_end = b.create_block("select_type_end"); |
| 25060 | | - let selector_type = |
| 25061 | | - operator_expr_type_info(selector, Some(&ctx.locals), ctx.st, Some(ctx.type_layouts)); |
| 25088 | + let selector_type = operator_expr_type_info( |
| 25089 | + selector, |
| 25090 | + Some(&ctx.locals), |
| 25091 | + ctx.st, |
| 25092 | + Some(ctx.type_layouts), |
| 25093 | + ); |
| 25062 | 25094 | let selector_info = associate_alias_local_info(b, ctx, selector); |
| 25063 | 25095 | let dynamic_class_selector = selector_info.as_ref().filter(|info| { |
| 25064 | 25096 | info.derived_type.is_some() |
@@ -25171,46 +25203,31 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 25171 | 25203 | let _ = std::io::stderr().flush(); |
| 25172 | 25204 | std::process::exit(1); |
| 25173 | 25205 | } |
| 25174 | | - let static_type = selector_info.as_ref().and_then(|info| info.derived_type.clone()); |
| 25206 | + let static_type = selector_info |
| 25207 | + .as_ref() |
| 25208 | + .and_then(|info| info.derived_type.clone()); |
| 25175 | 25209 | if let Some(ref type_name) = static_type { |
| 25176 | | - if let Some(layout) = ctx.type_layouts.get(type_name) { |
| 25177 | | - let tag_val = b.const_i64(layout.type_tag as i64); |
| 25178 | | - let default_body = guards.iter().find_map(|guard| match guard { |
| 25179 | | - crate::ast::stmt::TypeGuard::ClassDefault { body } => Some(body), |
| 25180 | | - _ => None, |
| 25181 | | - }); |
| 25182 | | - |
| 25183 | | - for guard in guards { |
| 25184 | | - match guard { |
| 25185 | | - crate::ast::stmt::TypeGuard::TypeIs { |
| 25186 | | - type_name: guard_type, |
| 25187 | | - body, |
| 25188 | | - } => { |
| 25189 | | - if let Some(guard_layout) = ctx.type_layouts.get(guard_type) { |
| 25190 | | - let guard_tag = b.const_i64(guard_layout.type_tag as i64); |
| 25191 | | - let matches = b.icmp(CmpOp::Eq, tag_val, guard_tag); |
| 25192 | | - let bb_match = b.create_block("type_is_match"); |
| 25193 | | - let bb_next = b.create_block("type_is_next"); |
| 25194 | | - b.cond_branch(matches, bb_match, vec![], bb_next, vec![]); |
| 25195 | | - |
| 25196 | | - b.set_block(bb_match); |
| 25197 | | - with_select_type_guard_binding( |
| 25198 | | - b, |
| 25199 | | - ctx, |
| 25200 | | - selector, |
| 25201 | | - assoc_name.as_deref(), |
| 25202 | | - guard_type, |
| 25203 | | - |b, ctx| lower_stmts(b, ctx, body), |
| 25204 | | - ); |
| 25205 | | - if b.func().block(b.current_block()).terminator.is_none() { |
| 25206 | | - b.branch(bb_end, vec![]); |
| 25207 | | - } |
| 25210 | + if let Some(layout) = ctx.type_layouts.get(type_name) { |
| 25211 | + let tag_val = b.const_i64(layout.type_tag as i64); |
| 25212 | + let default_body = guards.iter().find_map(|guard| match guard { |
| 25213 | + crate::ast::stmt::TypeGuard::ClassDefault { body } => Some(body), |
| 25214 | + _ => None, |
| 25215 | + }); |
| 25208 | 25216 | |
| 25209 | | - b.set_block(bb_next); |
| 25210 | | - } else { |
| 25211 | | - // Unknown guard type — skip. |
| 25212 | | - let tag_matches = type_name.eq_ignore_ascii_case(guard_type); |
| 25213 | | - if tag_matches { |
| 25217 | + for guard in guards { |
| 25218 | + match guard { |
| 25219 | + crate::ast::stmt::TypeGuard::TypeIs { |
| 25220 | + type_name: guard_type, |
| 25221 | + body, |
| 25222 | + } => { |
| 25223 | + if let Some(guard_layout) = ctx.type_layouts.get(guard_type) { |
| 25224 | + let guard_tag = b.const_i64(guard_layout.type_tag as i64); |
| 25225 | + let matches = b.icmp(CmpOp::Eq, tag_val, guard_tag); |
| 25226 | + let bb_match = b.create_block("type_is_match"); |
| 25227 | + let bb_next = b.create_block("type_is_next"); |
| 25228 | + b.cond_branch(matches, bb_match, vec![], bb_next, vec![]); |
| 25229 | + |
| 25230 | + b.set_block(bb_match); |
| 25214 | 25231 | with_select_type_guard_binding( |
| 25215 | 25232 | b, |
| 25216 | 25233 | ctx, |
@@ -25222,45 +25239,67 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 25222 | 25239 | if b.func().block(b.current_block()).terminator.is_none() { |
| 25223 | 25240 | b.branch(bb_end, vec![]); |
| 25224 | 25241 | } |
| 25225 | | - break; |
| 25242 | + |
| 25243 | + b.set_block(bb_next); |
| 25244 | + } else { |
| 25245 | + // Unknown guard type — skip. |
| 25246 | + let tag_matches = |
| 25247 | + type_name.eq_ignore_ascii_case(guard_type); |
| 25248 | + if tag_matches { |
| 25249 | + with_select_type_guard_binding( |
| 25250 | + b, |
| 25251 | + ctx, |
| 25252 | + selector, |
| 25253 | + assoc_name.as_deref(), |
| 25254 | + guard_type, |
| 25255 | + |b, ctx| lower_stmts(b, ctx, body), |
| 25256 | + ); |
| 25257 | + if b.func() |
| 25258 | + .block(b.current_block()) |
| 25259 | + .terminator |
| 25260 | + .is_none() |
| 25261 | + { |
| 25262 | + b.branch(bb_end, vec![]); |
| 25263 | + } |
| 25264 | + break; |
| 25265 | + } |
| 25226 | 25266 | } |
| 25227 | 25267 | } |
| 25228 | | - } |
| 25229 | | - crate::ast::stmt::TypeGuard::ClassIs { |
| 25230 | | - type_name: guard_type, |
| 25231 | | - body, |
| 25232 | | - } => { |
| 25233 | | - // CLASS IS matches the type or any extension. |
| 25234 | | - // Check if static type is or extends the guard type. |
| 25235 | | - let is_match = |
| 25236 | | - is_type_or_extends(type_name, guard_type, ctx.type_layouts); |
| 25237 | | - if is_match { |
| 25238 | | - with_select_type_guard_binding( |
| 25239 | | - b, |
| 25240 | | - ctx, |
| 25241 | | - selector, |
| 25242 | | - assoc_name.as_deref(), |
| 25243 | | - guard_type, |
| 25244 | | - |b, ctx| lower_stmts(b, ctx, body), |
| 25245 | | - ); |
| 25246 | | - if b.func().block(b.current_block()).terminator.is_none() { |
| 25247 | | - b.branch(bb_end, vec![]); |
| 25268 | + crate::ast::stmt::TypeGuard::ClassIs { |
| 25269 | + type_name: guard_type, |
| 25270 | + body, |
| 25271 | + } => { |
| 25272 | + // CLASS IS matches the type or any extension. |
| 25273 | + // Check if static type is or extends the guard type. |
| 25274 | + let is_match = |
| 25275 | + is_type_or_extends(type_name, guard_type, ctx.type_layouts); |
| 25276 | + if is_match { |
| 25277 | + with_select_type_guard_binding( |
| 25278 | + b, |
| 25279 | + ctx, |
| 25280 | + selector, |
| 25281 | + assoc_name.as_deref(), |
| 25282 | + guard_type, |
| 25283 | + |b, ctx| lower_stmts(b, ctx, body), |
| 25284 | + ); |
| 25285 | + if b.func().block(b.current_block()).terminator.is_none() { |
| 25286 | + b.branch(bb_end, vec![]); |
| 25287 | + } |
| 25288 | + break; // CLASS IS matched, skip remaining guards. |
| 25248 | 25289 | } |
| 25249 | | - break; // CLASS IS matched, skip remaining guards. |
| 25250 | 25290 | } |
| 25291 | + crate::ast::stmt::TypeGuard::ClassDefault { .. } => {} |
| 25251 | 25292 | } |
| 25252 | | - crate::ast::stmt::TypeGuard::ClassDefault { .. } => {} |
| 25253 | 25293 | } |
| 25254 | | - } |
| 25255 | | - if let Some(body) = default_body { |
| 25256 | | - lower_stmts(b, ctx, body); |
| 25257 | | - if b.func().block(b.current_block()).terminator.is_none() { |
| 25258 | | - b.branch(bb_end, vec![]); |
| 25294 | + if let Some(body) = default_body { |
| 25295 | + lower_stmts(b, ctx, body); |
| 25296 | + if b.func().block(b.current_block()).terminator.is_none() { |
| 25297 | + b.branch(bb_end, vec![]); |
| 25298 | + } |
| 25259 | 25299 | } |
| 25260 | 25300 | } |
| 25261 | 25301 | } |
| 25262 | 25302 | } |
| 25263 | | - } |
| 25264 | 25303 | |
| 25265 | 25304 | if b.func().block(b.current_block()).terminator.is_none() { |
| 25266 | 25305 | b.branch(bb_end, vec![]); |
@@ -25470,7 +25509,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 25470 | 25509 | is_pointer: field.pointer, |
| 25471 | 25510 | runtime_dim_upper: vec![], |
| 25472 | 25511 | is_class: false, |
| 25473 | | - logical_kind: None, |
| 25512 | + logical_kind: None, |
| 25474 | 25513 | last_dim_assumed_size: false, |
| 25475 | 25514 | }; |
| 25476 | 25515 | let source_scalar_layout = if rank == 0 && source_desc.is_none() { |
@@ -25487,16 +25526,14 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 25487 | 25526 | } else { |
| 25488 | 25527 | None |
| 25489 | 25528 | }; |
| 25490 | | - let dynamic_layout = source_scalar_layout |
| 25491 | | - .or(typed_layout) |
| 25492 | | - .or_else(|| { |
| 25529 | + let dynamic_layout = |
| 25530 | + source_scalar_layout.or(typed_layout).or_else(|| { |
| 25493 | 25531 | field_info |
| 25494 | 25532 | .derived_type |
| 25495 | 25533 | .as_deref() |
| 25496 | 25534 | .and_then(|type_name| ctx.type_layouts.get(type_name)) |
| 25497 | 25535 | }); |
| 25498 | | - let scalar_source_copy_plan = |
| 25499 | | - if rank == 0 && source_desc.is_none() { |
| 25536 | + let scalar_source_copy_plan = if rank == 0 && source_desc.is_none() { |
| 25500 | 25537 | source_expr.and_then(|expr| { |
| 25501 | 25538 | expr_scalar_alloc_source_copy_plan( |
| 25502 | 25539 | expr, |
@@ -25704,11 +25741,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 25704 | 25741 | }) |
| 25705 | 25742 | }; |
| 25706 | 25743 | emit_scalar_alloc_polymorphic_metadata_on_success( |
| 25707 | | - b, |
| 25708 | | - stat_addr, |
| 25709 | | - field_ptr, |
| 25710 | | - type_tag, |
| 25711 | | - tbp_lookup, |
| 25744 | + b, stat_addr, field_ptr, type_tag, tbp_lookup, |
| 25712 | 25745 | ); |
| 25713 | 25746 | if let Some(source_desc) = source_desc { |
| 25714 | 25747 | emit_scalar_alloc_source_descriptor_metadata_on_success( |
@@ -25764,7 +25797,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 25764 | 25797 | is_pointer: field.pointer, |
| 25765 | 25798 | runtime_dim_upper: vec![], |
| 25766 | 25799 | is_class: false, |
| 25767 | | - logical_kind: None, |
| 25800 | + logical_kind: None, |
| 25768 | 25801 | last_dim_assumed_size: false, |
| 25769 | 25802 | }; |
| 25770 | 25803 | let elem_size_bytes = |
@@ -25845,15 +25878,13 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 25845 | 25878 | } else { |
| 25846 | 25879 | None |
| 25847 | 25880 | }; |
| 25848 | | - let dynamic_layout = source_scalar_layout |
| 25849 | | - .or(typed_layout) |
| 25850 | | - .or_else(|| { |
| 25881 | + let dynamic_layout = |
| 25882 | + source_scalar_layout.or(typed_layout).or_else(|| { |
| 25851 | 25883 | info.derived_type |
| 25852 | 25884 | .as_deref() |
| 25853 | 25885 | .and_then(|type_name| ctx.type_layouts.get(type_name)) |
| 25854 | 25886 | }); |
| 25855 | | - let scalar_source_copy_plan = |
| 25856 | | - if rank == 0 && source_desc.is_none() { |
| 25887 | + let scalar_source_copy_plan = if rank == 0 && source_desc.is_none() { |
| 25857 | 25888 | source_expr.and_then(|expr| { |
| 25858 | 25889 | expr_scalar_alloc_source_copy_plan( |
| 25859 | 25890 | expr, |
@@ -26067,11 +26098,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 26067 | 26098 | }) |
| 26068 | 26099 | }; |
| 26069 | 26100 | emit_scalar_alloc_polymorphic_metadata_on_success( |
| 26070 | | - b, |
| 26071 | | - stat_addr, |
| 26072 | | - desc, |
| 26073 | | - type_tag, |
| 26074 | | - tbp_lookup, |
| 26101 | + b, stat_addr, desc, type_tag, tbp_lookup, |
| 26075 | 26102 | ); |
| 26076 | 26103 | if let Some(source_desc) = source_desc { |
| 26077 | 26104 | emit_scalar_alloc_source_descriptor_metadata_on_success( |
@@ -26202,10 +26229,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 26202 | 26229 | // never fires for re-deallocated pools |
| 26203 | 26230 | // and recurses until stack overflow. |
| 26204 | 26231 | let null_v = b.const_i64(0); |
| 26205 | | - let null_p = b.int_to_ptr( |
| 26206 | | - null_v, |
| 26207 | | - IrType::Int(IntWidth::I8), |
| 26208 | | - ); |
| 26232 | + let null_p = b.int_to_ptr(null_v, IrType::Int(IntWidth::I8)); |
| 26209 | 26233 | b.store(null_p, field_ptr); |
| 26210 | 26234 | continue; |
| 26211 | 26235 | } |
@@ -26245,10 +26269,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 26245 | 26269 | b.runtime_call(RuntimeFunc::Deallocate, vec![ptr], IrType::Void); |
| 26246 | 26270 | // Null the pointer slot per F2018 §9.7.3.2. |
| 26247 | 26271 | let null_v = b.const_i64(0); |
| 26248 | | - let null_p = b.int_to_ptr( |
| 26249 | | - null_v, |
| 26250 | | - IrType::Int(IntWidth::I8), |
| 26251 | | - ); |
| 26272 | + let null_p = b.int_to_ptr(null_v, IrType::Int(IntWidth::I8)); |
| 26252 | 26273 | b.store(null_p, slot); |
| 26253 | 26274 | } else { |
| 26254 | 26275 | let ptr = b.load_typed( |
@@ -26467,7 +26488,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 26467 | 26488 | is_pointer: false, |
| 26468 | 26489 | runtime_dim_upper: vec![], |
| 26469 | 26490 | is_class: false, |
| 26470 | | - logical_kind: None, |
| 26491 | + logical_kind: None, |
| 26471 | 26492 | last_dim_assumed_size: false, |
| 26472 | 26493 | }, |
| 26473 | 26494 | ); |
@@ -27299,22 +27320,15 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 27299 | 27320 | let is_remap_target = ctx |
| 27300 | 27321 | .locals |
| 27301 | 27322 | .get(&tgt_key) |
| 27302 | | - .map(|info| { |
| 27303 | | - info.is_pointer && local_uses_array_descriptor(info) |
| 27304 | | - }) |
| 27323 | + .map(|info| info.is_pointer && local_uses_array_descriptor(info)) |
| 27305 | 27324 | .unwrap_or(false); |
| 27306 | 27325 | let all_ranges = !args.is_empty() |
| 27307 | 27326 | && args.iter().all(|a| { |
| 27308 | | - matches!( |
| 27309 | | - a.value, |
| 27310 | | - crate::ast::expr::SectionSubscript::Range { .. } |
| 27311 | | - ) |
| 27327 | + matches!(a.value, crate::ast::expr::SectionSubscript::Range { .. }) |
| 27312 | 27328 | }); |
| 27313 | 27329 | if is_remap_target |
| 27314 | 27330 | && all_ranges |
| 27315 | | - && lower_rank_remap_pointer_assignment( |
| 27316 | | - b, ctx, &tgt_key, args, value, |
| 27317 | | - ) |
| 27331 | + && lower_rank_remap_pointer_assignment(b, ctx, &tgt_key, args, value) |
| 27318 | 27332 | { |
| 27319 | 27333 | return; |
| 27320 | 27334 | } |
@@ -27447,7 +27461,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 27447 | 27461 | is_pointer: tgt_field.pointer, |
| 27448 | 27462 | runtime_dim_upper: vec![], |
| 27449 | 27463 | is_class: false, |
| 27450 | | - logical_kind: None, |
| 27464 | + logical_kind: None, |
| 27451 | 27465 | last_dim_assumed_size: false, |
| 27452 | 27466 | }) |
| 27453 | 27467 | .or_else(|| { |
@@ -27762,12 +27776,7 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 27762 | 27776 | static_expr_tbp_lookup_value(b, value, ctx.st, ctx.type_layouts); |
| 27763 | 27777 | let tgt_desc = array_descriptor_addr(b, &tgt_info); |
| 27764 | 27778 | store_scalar_polymorphic_descriptor_view( |
| 27765 | | - b, |
| 27766 | | - tgt_desc, |
| 27767 | | - addr, |
| 27768 | | - elem_size, |
| 27769 | | - type_tag, |
| 27770 | | - tbp_lookup, |
| 27779 | + b, tgt_desc, addr, elem_size, type_tag, tbp_lookup, |
| 27771 | 27780 | ); |
| 27772 | 27781 | } else { |
| 27773 | 27782 | store_scalar_pointer_slot_value(b, &tgt_info, addr); |
@@ -27896,16 +27905,10 @@ fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &SpannedStmt) { |
| 27896 | 27905 | let type_tag = static_expr_type_tag_value(b, value, ctx.st, ctx.type_layouts); |
| 27897 | 27906 | let elem_size = expr_type_layout(value, None, ctx.st, ctx.type_layouts) |
| 27898 | 27907 | .map(|layout| b.const_i64(layout.size as i64)); |
| 27899 | | - let tbp_lookup = |
| 27900 | | - static_expr_tbp_lookup_value(b, value, ctx.st, ctx.type_layouts); |
| 27908 | + let tbp_lookup = static_expr_tbp_lookup_value(b, value, ctx.st, ctx.type_layouts); |
| 27901 | 27909 | let tgt_desc = array_descriptor_addr(b, &tgt_info); |
| 27902 | 27910 | store_scalar_polymorphic_descriptor_view( |
| 27903 | | - b, |
| 27904 | | - tgt_desc, |
| 27905 | | - addr, |
| 27906 | | - elem_size, |
| 27907 | | - type_tag, |
| 27908 | | - tbp_lookup, |
| 27911 | + b, tgt_desc, addr, elem_size, type_tag, tbp_lookup, |
| 27909 | 27912 | ); |
| 27910 | 27913 | } else { |
| 27911 | 27914 | store_scalar_pointer_slot_value(b, &tgt_info, addr); |
@@ -28032,7 +28035,8 @@ fn expr_uses_optional_by_ref_local( |
| 28032 | 28035 | match expr { |
| 28033 | 28036 | Expr::Name { name } => { |
| 28034 | 28037 | let key = name.to_lowercase(); |
| 28035 | | - optional_locals.contains(&key) && locals.get(&key).map(|info| info.by_ref).unwrap_or(false) |
| 28038 | + optional_locals.contains(&key) |
| 28039 | + && locals.get(&key).map(|info| info.by_ref).unwrap_or(false) |
| 28036 | 28040 | } |
| 28037 | 28041 | Expr::BinaryOp { left, right, .. } => { |
| 28038 | 28042 | expr_uses_optional_by_ref_local(&left.node, locals, optional_locals) |
@@ -28427,7 +28431,7 @@ fn lower_do_loop(b: &mut FuncBuilder, ctx: &mut LowerCtx, fields: DoLoopFields) |
| 28427 | 28431 | is_pointer: false, |
| 28428 | 28432 | runtime_dim_upper: vec![], |
| 28429 | 28433 | is_class: false, |
| 28430 | | - logical_kind: None, |
| 28434 | + logical_kind: None, |
| 28431 | 28435 | last_dim_assumed_size: false, |
| 28432 | 28436 | }, |
| 28433 | 28437 | ); |
@@ -29449,7 +29453,9 @@ fn lower_runtime_array_constructor_descriptor( |
| 29449 | 29453 | /// folded here — they fall back to silently skipping init the same |
| 29450 | 29454 | /// way they used to (visible if the user mixes them in declared |
| 29451 | 29455 | /// initializers, which is rare). |
| 29452 | | -fn extract_reshape_source_ac(expr: &crate::ast::expr::Expr) -> Option<&[crate::ast::expr::AcValue]> { |
| 29456 | +fn extract_reshape_source_ac( |
| 29457 | + expr: &crate::ast::expr::Expr, |
| 29458 | +) -> Option<&[crate::ast::expr::AcValue]> { |
| 29453 | 29459 | use crate::ast::expr::{Expr, SectionSubscript}; |
| 29454 | 29460 | let Expr::FunctionCall { callee, args } = expr else { |
| 29455 | 29461 | return None; |
@@ -29686,10 +29692,7 @@ fn store_ac_values_at_off( |
| 29686 | 29692 | // because elem_size==8 matches the scalar store width. |
| 29687 | 29693 | let bytes = complex_byte_size(elem_ty); |
| 29688 | 29694 | let sz = b.const_i64(bytes); |
| 29689 | | - let src_ptr = if matches!( |
| 29690 | | - b.func().value_type(raw), |
| 29691 | | - Some(IrType::Ptr(_)) |
| 29692 | | - ) { |
| 29695 | + let src_ptr = if matches!(b.func().value_type(raw), Some(IrType::Ptr(_))) { |
| 29693 | 29696 | raw |
| 29694 | 29697 | } else { |
| 29695 | 29698 | // Value-form complex (e.g. produced by an |
@@ -29957,10 +29960,7 @@ fn store_ac_implied_do( |
| 29957 | 29960 | // scalar store of an Array(F,2) value drops the imag lane. |
| 29958 | 29961 | let bytes = complex_byte_size(elem_ty); |
| 29959 | 29962 | let sz = b.const_i64(bytes); |
| 29960 | | - let src_ptr = if matches!( |
| 29961 | | - b.func().value_type(raw), |
| 29962 | | - Some(IrType::Ptr(_)) |
| 29963 | | - ) { |
| 29963 | + let src_ptr = if matches!(b.func().value_type(raw), Some(IrType::Ptr(_))) { |
| 29964 | 29964 | raw |
| 29965 | 29965 | } else { |
| 29966 | 29966 | let buf = b.alloca(elem_ty.clone()); |
@@ -33423,7 +33423,10 @@ fn lower_descriptor_actual_from_info( |
| 33423 | 33423 | if info.by_ref { |
| 33424 | 33424 | let caller_slot = |
| 33425 | 33425 | b.load_typed(info.addr, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 33426 | | - b.load_typed(caller_slot, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))) |
| 33426 | + b.load_typed( |
| 33427 | + caller_slot, |
| 33428 | + IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 33429 | + ) |
| 33427 | 33430 | } else { |
| 33428 | 33431 | let load_ty = if info.ty.is_ptr() { |
| 33429 | 33432 | info.ty.clone() |
@@ -33519,8 +33522,7 @@ fn lower_arg_descriptor( |
| 33519 | 33522 | if let Expr::Name { name } = &expr.node { |
| 33520 | 33523 | let key = name.to_lowercase(); |
| 33521 | 33524 | if let Some(info) = locals.get(&key) { |
| 33522 | | - if expr_needs_static_scalar_descriptor_view(expr, info, locals, st, type_layouts) |
| 33523 | | - { |
| 33525 | + if expr_needs_static_scalar_descriptor_view(expr, info, locals, st, type_layouts) { |
| 33524 | 33526 | return lower_descriptor_actual_from_info(b, info, type_layouts, true); |
| 33525 | 33527 | } |
| 33526 | 33528 | } |
@@ -33590,13 +33592,7 @@ fn lower_arg_descriptor( |
| 33590 | 33592 | // error message arg lists like `linalg_state_type`'s a1..a20) |
| 33591 | 33593 | // tolerates unknown-type fallthrough gracefully. |
| 33592 | 33594 | if force_static_scalar_polymorphic_view { |
| 33593 | | - return box_actual_into_class_star_descriptor( |
| 33594 | | - b, |
| 33595 | | - locals, |
| 33596 | | - expr, |
| 33597 | | - st, |
| 33598 | | - type_layouts, |
| 33599 | | - ); |
| 33595 | + return box_actual_into_class_star_descriptor(b, locals, expr, st, type_layouts); |
| 33600 | 33596 | } |
| 33601 | 33597 | b.const_i64(0) |
| 33602 | 33598 | } |
@@ -33625,8 +33621,7 @@ fn box_actual_into_class_star_descriptor( |
| 33625 | 33621 | // to put in the descriptor's base_addr. For scalars we lower the |
| 33626 | 33622 | // expression and store into a temp; for whole-array names we use |
| 33627 | 33623 | // their existing storage. |
| 33628 | | - let (base_ptr, elem_size_bytes): (ValueId, i64) = if let Expr::Name { name } = &expr.node |
| 33629 | | - { |
| 33624 | + let (base_ptr, elem_size_bytes): (ValueId, i64) = if let Expr::Name { name } = &expr.node { |
| 33630 | 33625 | if let Some(info) = locals.get(&name.to_lowercase()) { |
| 33631 | 33626 | let bytes = ir_scalar_byte_size(&info.ty).max(1); |
| 33632 | 33627 | let addr = if info.by_ref { |
@@ -34155,15 +34150,20 @@ fn expr_contains_whole_array_intrinsic(expr: &crate::ast::expr::SpannedExpr) -> |
| 34155 | 34150 | expr_contains_whole_array_intrinsic(e) |
| 34156 | 34151 | } |
| 34157 | 34152 | crate::ast::expr::SectionSubscript::Range { start, end, stride } => { |
| 34158 | | - start.as_ref().is_some_and(expr_contains_whole_array_intrinsic) |
| 34159 | | - || end.as_ref().is_some_and(expr_contains_whole_array_intrinsic) |
| 34160 | | - || stride.as_ref().is_some_and(expr_contains_whole_array_intrinsic) |
| 34153 | + start |
| 34154 | + .as_ref() |
| 34155 | + .is_some_and(expr_contains_whole_array_intrinsic) |
| 34156 | + || end |
| 34157 | + .as_ref() |
| 34158 | + .is_some_and(expr_contains_whole_array_intrinsic) |
| 34159 | + || stride |
| 34160 | + .as_ref() |
| 34161 | + .is_some_and(expr_contains_whole_array_intrinsic) |
| 34161 | 34162 | } |
| 34162 | 34163 | }) |
| 34163 | 34164 | } |
| 34164 | 34165 | Expr::BinaryOp { left, right, .. } => { |
| 34165 | | - expr_contains_whole_array_intrinsic(left) |
| 34166 | | - || expr_contains_whole_array_intrinsic(right) |
| 34166 | + expr_contains_whole_array_intrinsic(left) || expr_contains_whole_array_intrinsic(right) |
| 34167 | 34167 | } |
| 34168 | 34168 | Expr::UnaryOp { operand, .. } => expr_contains_whole_array_intrinsic(operand), |
| 34169 | 34169 | Expr::ParenExpr { inner } => expr_contains_whole_array_intrinsic(inner), |
@@ -34337,16 +34337,12 @@ fn materialize_scalarized_rank1_constructors( |
| 34337 | 34337 | let (desc, elem_ty) = |
| 34338 | 34338 | lower_array_expr_descriptor(b, locals, expr, st, type_layouts, None, None, None)?; |
| 34339 | 34339 | let first = first_array_constructor_expr(values)?; |
| 34340 | | - let derived_type = match first_array_constructor_type_info( |
| 34341 | | - values, |
| 34342 | | - Some(locals), |
| 34343 | | - st, |
| 34344 | | - type_layouts, |
| 34345 | | - ) { |
| 34346 | | - Some(crate::sema::symtab::TypeInfo::Derived(name)) |
| 34347 | | - | Some(crate::sema::symtab::TypeInfo::Class(name)) => Some(name), |
| 34348 | | - _ => None, |
| 34349 | | - }; |
| 34340 | + let derived_type = |
| 34341 | + match first_array_constructor_type_info(values, Some(locals), st, type_layouts) { |
| 34342 | + Some(crate::sema::symtab::TypeInfo::Derived(name)) |
| 34343 | + | Some(crate::sema::symtab::TypeInfo::Class(name)) => Some(name), |
| 34344 | + _ => None, |
| 34345 | + }; |
| 34350 | 34346 | let (local_ty, char_kind) = |
| 34351 | 34347 | if expr_is_character_expr(b, locals, first, st, type_layouts) { |
| 34352 | 34348 | let elem_len = |
@@ -34374,7 +34370,7 @@ fn materialize_scalarized_rank1_constructors( |
| 34374 | 34370 | is_pointer: false, |
| 34375 | 34371 | runtime_dim_upper: vec![], |
| 34376 | 34372 | is_class: false, |
| 34377 | | - logical_kind: None, |
| 34373 | + logical_kind: None, |
| 34378 | 34374 | last_dim_assumed_size: false, |
| 34379 | 34375 | }, |
| 34380 | 34376 | ); |
@@ -35090,8 +35086,7 @@ fn lower_reshape_array_expr_descriptor( |
| 35090 | 35086 | vec![desc, zero32, sz384], |
| 35091 | 35087 | IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 35092 | 35088 | ); |
| 35093 | | - let base_ptr = |
| 35094 | | - b.load_typed(source_desc, IrType::Ptr(Box::new(elem_ty.clone()))); |
| 35089 | + let base_ptr = b.load_typed(source_desc, IrType::Ptr(Box::new(elem_ty.clone()))); |
| 35095 | 35090 | store_byte_aggregate_field( |
| 35096 | 35091 | b, |
| 35097 | 35092 | desc, |
@@ -35110,9 +35105,27 @@ fn lower_reshape_array_expr_descriptor( |
| 35110 | 35105 | let lower = b.const_i64(1); |
| 35111 | 35106 | let upper = b.const_i64(extent); |
| 35112 | 35107 | let stride = b.const_i64(1); |
| 35113 | | - store_byte_aggregate_field(b, desc, base_offset, IrType::Int(IntWidth::I64), lower); |
| 35114 | | - store_byte_aggregate_field(b, desc, base_offset + 8, IrType::Int(IntWidth::I64), upper); |
| 35115 | | - store_byte_aggregate_field(b, desc, base_offset + 16, IrType::Int(IntWidth::I64), stride); |
| 35108 | + store_byte_aggregate_field( |
| 35109 | + b, |
| 35110 | + desc, |
| 35111 | + base_offset, |
| 35112 | + IrType::Int(IntWidth::I64), |
| 35113 | + lower, |
| 35114 | + ); |
| 35115 | + store_byte_aggregate_field( |
| 35116 | + b, |
| 35117 | + desc, |
| 35118 | + base_offset + 8, |
| 35119 | + IrType::Int(IntWidth::I64), |
| 35120 | + upper, |
| 35121 | + ); |
| 35122 | + store_byte_aggregate_field( |
| 35123 | + b, |
| 35124 | + desc, |
| 35125 | + base_offset + 16, |
| 35126 | + IrType::Int(IntWidth::I64), |
| 35127 | + stride, |
| 35128 | + ); |
| 35116 | 35129 | } |
| 35117 | 35130 | return Some((desc, elem_ty)); |
| 35118 | 35131 | } |
@@ -35249,10 +35262,8 @@ fn lower_transfer_array_expr_descriptor( |
| 35249 | 35262 | // operate on it. ArrayConstructors are array-valued by definition; |
| 35250 | 35263 | // expr_returns_array's conservative classifier doesn't cover them |
| 35251 | 35264 | // so we add an explicit check here. |
| 35252 | | - let mold_is_array_constructor = |
| 35253 | | - matches!(mold_expr.node, Expr::ArrayConstructor { .. }); |
| 35254 | | - let mold_is_array = |
| 35255 | | - mold_is_array_constructor || expr_returns_array(mold_expr, locals, st); |
| 35265 | + let mold_is_array_constructor = matches!(mold_expr.node, Expr::ArrayConstructor { .. }); |
| 35266 | + let mold_is_array = mold_is_array_constructor || expr_returns_array(mold_expr, locals, st); |
| 35256 | 35267 | if !mold_is_array && size_expr_opt.is_none() { |
| 35257 | 35268 | return None; |
| 35258 | 35269 | } |
@@ -35281,9 +35292,7 @@ fn lower_transfer_array_expr_descriptor( |
| 35281 | 35292 | // bytes are constant from the constructor length × elem size. |
| 35282 | 35293 | let tl = type_layouts?; |
| 35283 | 35294 | let (src_base, src_total_bytes_v, src_total_bytes_const): (ValueId, ValueId, Option<i64>) = |
| 35284 | | - if let Some(src_info) = |
| 35285 | | - whole_array_expr_local_info(b, locals, src_expr, st, tl) |
| 35286 | | - { |
| 35295 | + if let Some(src_info) = whole_array_expr_local_info(b, locals, src_expr, st, tl) { |
| 35287 | 35296 | let elem_bytes = descriptor_element_size_bytes(&src_info); |
| 35288 | 35297 | if elem_bytes <= 0 { |
| 35289 | 35298 | return None; |
@@ -35310,8 +35319,7 @@ fn lower_transfer_array_expr_descriptor( |
| 35310 | 35319 | contained_host_refs, |
| 35311 | 35320 | descriptor_params, |
| 35312 | 35321 | )?; |
| 35313 | | - let base = |
| 35314 | | - b.load_typed(src_desc, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 35322 | + let base = b.load_typed(src_desc, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 35315 | 35323 | // Constructor length × first-value elem size for compile-time total. |
| 35316 | 35324 | let Expr::ArrayConstructor { values, .. } = &src_expr.node else { |
| 35317 | 35325 | unreachable!() |
@@ -36068,7 +36076,7 @@ fn try_lower_elemental_subroutine_call( |
| 36068 | 36076 | is_pointer: false, |
| 36069 | 36077 | runtime_dim_upper: vec![], |
| 36070 | 36078 | is_class: false, |
| 36071 | | - logical_kind: None, |
| 36079 | + logical_kind: None, |
| 36072 | 36080 | last_dim_assumed_size: false, |
| 36073 | 36081 | }, |
| 36074 | 36082 | ); |
@@ -36332,10 +36340,8 @@ fn lower_rank1_elemental_call_descriptor( |
| 36332 | 36340 | Some(crate::sema::symtab::TypeInfo::Class(name)) => Some(name.clone()), |
| 36333 | 36341 | _ => None, |
| 36334 | 36342 | }; |
| 36335 | | - let is_class_actual = matches!( |
| 36336 | | - actual_type, |
| 36337 | | - Some(crate::sema::symtab::TypeInfo::Class(_)) |
| 36338 | | - ); |
| 36343 | + let is_class_actual = |
| 36344 | + matches!(actual_type, Some(crate::sema::symtab::TypeInfo::Class(_))); |
| 36339 | 36345 | loop_locals.insert( |
| 36340 | 36346 | temp_name.clone(), |
| 36341 | 36347 | LocalInfo { |
@@ -36443,8 +36449,7 @@ fn lower_rank1_elemental_call_descriptor( |
| 36443 | 36449 | // i-th array element into the per-iteration temp slot. |
| 36444 | 36450 | // Loading and re-storing as a value would emit a `[i8 x N]` |
| 36445 | 36451 | // load that codegen can't materialize cleanly. |
| 36446 | | - let src_ptr = |
| 36447 | | - rank1_array_desc_elem_ptr(b, *actual_desc, actual_elem_ty, cur_idx); |
| 36452 | + let src_ptr = rank1_array_desc_elem_ptr(b, *actual_desc, actual_elem_ty, cur_idx); |
| 36448 | 36453 | let elem_bytes = b.const_i64(ir_scalar_byte_size(actual_elem_ty)); |
| 36449 | 36454 | b.call( |
| 36450 | 36455 | FuncRef::External("memcpy".into()), |
@@ -36465,7 +36470,7 @@ fn lower_rank1_elemental_call_descriptor( |
| 36465 | 36470 | is_pointer: false, |
| 36466 | 36471 | runtime_dim_upper: vec![], |
| 36467 | 36472 | is_class: false, |
| 36468 | | - logical_kind: None, |
| 36473 | + logical_kind: None, |
| 36469 | 36474 | last_dim_assumed_size: false, |
| 36470 | 36475 | }; |
| 36471 | 36476 | let (src_ptr, src_len) = |
@@ -36858,8 +36863,14 @@ fn lower_rank1_array_compare_descriptor( |
| 36858 | 36863 | coerce_to_type(b, raw, operand_ty) |
| 36859 | 36864 | } else { |
| 36860 | 36865 | let scalar = lower_expr_full( |
| 36861 | | - b, locals, left, st, type_layouts, |
| 36862 | | - internal_funcs, contained_host_refs, descriptor_params, |
| 36866 | + b, |
| 36867 | + locals, |
| 36868 | + left, |
| 36869 | + st, |
| 36870 | + type_layouts, |
| 36871 | + internal_funcs, |
| 36872 | + contained_host_refs, |
| 36873 | + descriptor_params, |
| 36863 | 36874 | ); |
| 36864 | 36875 | coerce_to_type(b, scalar, operand_ty) |
| 36865 | 36876 | }; |
@@ -36868,8 +36879,14 @@ fn lower_rank1_array_compare_descriptor( |
| 36868 | 36879 | coerce_to_type(b, raw, operand_ty) |
| 36869 | 36880 | } else { |
| 36870 | 36881 | let scalar = lower_expr_full( |
| 36871 | | - b, locals, right, st, type_layouts, |
| 36872 | | - internal_funcs, contained_host_refs, descriptor_params, |
| 36882 | + b, |
| 36883 | + locals, |
| 36884 | + right, |
| 36885 | + st, |
| 36886 | + type_layouts, |
| 36887 | + internal_funcs, |
| 36888 | + contained_host_refs, |
| 36889 | + descriptor_params, |
| 36873 | 36890 | ); |
| 36874 | 36891 | coerce_to_type(b, scalar, operand_ty) |
| 36875 | 36892 | }; |
@@ -36948,7 +36965,8 @@ fn lower_rank1_numeric_array_binary_descriptor( |
| 36948 | 36965 | .as_ref() |
| 36949 | 36966 | .map(|(_, ty)| ty.clone()) |
| 36950 | 36967 | .or_else(|| rhs.as_ref().map(|(_, ty)| ty.clone()))?; |
| 36951 | | - let is_complex_elem = matches!(&elem_ty, IrType::Array(inner, 2) if matches!(inner.as_ref(), IrType::Float(_))); |
| 36968 | + let is_complex_elem = |
| 36969 | + matches!(&elem_ty, IrType::Array(inner, 2) if matches!(inner.as_ref(), IrType::Float(_))); |
| 36952 | 36970 | match &elem_ty { |
| 36953 | 36971 | IrType::Int(_) | IrType::Float(_) | IrType::Bool => {} |
| 36954 | 36972 | _ if is_complex_elem => {} |
@@ -36967,12 +36985,7 @@ fn lower_rank1_numeric_array_binary_descriptor( |
| 36967 | 36985 | // Integer or Real semantic types. |
| 36968 | 36986 | let is_compare_op = matches!( |
| 36969 | 36987 | op, |
| 36970 | | - BinaryOp::Eq |
| 36971 | | - | BinaryOp::Ne |
| 36972 | | - | BinaryOp::Lt |
| 36973 | | - | BinaryOp::Le |
| 36974 | | - | BinaryOp::Gt |
| 36975 | | - | BinaryOp::Ge |
| 36988 | + BinaryOp::Eq | BinaryOp::Ne | BinaryOp::Lt | BinaryOp::Le | BinaryOp::Gt | BinaryOp::Ge |
| 36976 | 36989 | ); |
| 36977 | 36990 | if is_compare_op && !is_complex_elem { |
| 36978 | 36991 | use crate::sema::types::FortranType; |
@@ -36986,9 +36999,7 @@ fn lower_rank1_numeric_array_binary_descriptor( |
| 36986 | 36999 | let is_numeric = |t: &FortranType| { |
| 36987 | 37000 | matches!( |
| 36988 | 37001 | t, |
| 36989 | | - FortranType::Integer { .. } |
| 36990 | | - | FortranType::Real { .. } |
| 36991 | | - | FortranType::Unknown |
| 37002 | + FortranType::Integer { .. } | FortranType::Real { .. } | FortranType::Unknown |
| 36992 | 37003 | ) |
| 36993 | 37004 | }; |
| 36994 | 37005 | if is_numeric(<) && is_numeric(&rt) { |
@@ -37084,7 +37095,10 @@ fn lower_rank1_numeric_array_binary_descriptor( |
| 37084 | 37095 | let lane_bytes = b.const_i64(if fw == FloatWidth::F64 { 8 } else { 4 }); |
| 37085 | 37096 | let zero = b.const_i64(0); |
| 37086 | 37097 | |
| 37087 | | - let load_lanes = |b: &mut FuncBuilder, side: Option<&(ValueId, IrType)>, side_expr: &crate::ast::expr::SpannedExpr| -> (ValueId, ValueId) { |
| 37098 | + let load_lanes = |b: &mut FuncBuilder, |
| 37099 | + side: Option<&(ValueId, IrType)>, |
| 37100 | + side_expr: &crate::ast::expr::SpannedExpr| |
| 37101 | + -> (ValueId, ValueId) { |
| 37088 | 37102 | if let Some((desc, _)) = side { |
| 37089 | 37103 | let elem_ptr = rank1_array_desc_elem_ptr(b, *desc, &elem_ty, idx); |
| 37090 | 37104 | let re_ptr = b.gep(elem_ptr, vec![zero], IrType::Int(IntWidth::I8)); |
@@ -37497,10 +37511,7 @@ fn lower_array_expr_descriptor( |
| 37497 | 37511 | // result as ArrayDescriptor — intrinsics aren't there, |
| 37498 | 37512 | // so the rhs would silently scalarize and emit `isub` |
| 37499 | 37513 | // against the descriptor pointer. |
| 37500 | | - if matches!( |
| 37501 | | - name.to_ascii_lowercase().as_str(), |
| 37502 | | - "matmul" | "transpose" |
| 37503 | | - ) { |
| 37514 | + if matches!(name.to_ascii_lowercase().as_str(), "matmul" | "transpose") { |
| 37504 | 37515 | if let Some(first_arg) = args.first() { |
| 37505 | 37516 | if let crate::ast::expr::SectionSubscript::Element(first_expr) = |
| 37506 | 37517 | &first_arg.value |
@@ -37605,16 +37616,15 @@ fn lower_array_expr_descriptor( |
| 37605 | 37616 | contained_host_refs, |
| 37606 | 37617 | descriptor_params, |
| 37607 | 37618 | ) { |
| 37608 | | - let real_lane = |
| 37609 | | - if let IrType::Array(inner, 2) = &elem_ty { |
| 37610 | | - if let IrType::Float(fw) = inner.as_ref() { |
| 37611 | | - Some(*fw) |
| 37612 | | - } else { |
| 37613 | | - None |
| 37614 | | - } |
| 37619 | + let real_lane = if let IrType::Array(inner, 2) = &elem_ty { |
| 37620 | + if let IrType::Float(fw) = inner.as_ref() { |
| 37621 | + Some(*fw) |
| 37615 | 37622 | } else { |
| 37616 | 37623 | None |
| 37617 | | - }; |
| 37624 | + } |
| 37625 | + } else { |
| 37626 | + None |
| 37627 | + }; |
| 37618 | 37628 | if let Some(fw) = real_lane { |
| 37619 | 37629 | let result_desc = b.alloca(IrType::Array( |
| 37620 | 37630 | Box::new(IrType::Int(IntWidth::I8)), |
@@ -37690,7 +37700,8 @@ fn lower_array_expr_descriptor( |
| 37690 | 37700 | continue; |
| 37691 | 37701 | }; |
| 37692 | 37702 | match a.keyword.as_deref().map(str::to_ascii_lowercase) { |
| 37693 | | - Some(ref kw) if kw == "x" => { /* re — already handled */ } |
| 37703 | + Some(ref kw) if kw == "x" => { /* re — already handled */ |
| 37704 | + } |
| 37694 | 37705 | Some(ref kw) if kw == "y" => im_expr = Some(e), |
| 37695 | 37706 | Some(ref kw) if kw == "kind" => kind_expr = Some(e), |
| 37696 | 37707 | Some(_) => {} |
@@ -37763,8 +37774,7 @@ fn lower_array_expr_descriptor( |
| 37763 | 37774 | } else { |
| 37764 | 37775 | FloatWidth::F32 |
| 37765 | 37776 | }; |
| 37766 | | - let elem_ty = |
| 37767 | | - IrType::Array(Box::new(IrType::Float(out_fw)), 2); |
| 37777 | + let elem_ty = IrType::Array(Box::new(IrType::Float(out_fw)), 2); |
| 37768 | 37778 | return Some((result_desc, elem_ty)); |
| 37769 | 37779 | } |
| 37770 | 37780 | } |
@@ -37792,13 +37802,11 @@ fn lower_array_expr_descriptor( |
| 37792 | 37802 | ) |
| 37793 | 37803 | .is_some() |
| 37794 | 37804 | || locals |
| 37795 | | - .get( |
| 37796 | | - &if let Expr::Name { name } = &first_expr.node { |
| 37797 | | - name.to_lowercase() |
| 37798 | | - } else { |
| 37799 | | - String::new() |
| 37800 | | - }, |
| 37801 | | - ) |
| 37805 | + .get(&if let Expr::Name { name } = &first_expr.node { |
| 37806 | + name.to_lowercase() |
| 37807 | + } else { |
| 37808 | + String::new() |
| 37809 | + }) |
| 37802 | 37810 | .map(local_is_array_like) |
| 37803 | 37811 | .unwrap_or(false) |
| 37804 | 37812 | { |
@@ -37930,9 +37938,9 @@ fn lower_array_expr_descriptor( |
| 37930 | 37938 | Expr::ArrayConstructor { values, type_spec } => { |
| 37931 | 37939 | let first = first_array_constructor_expr(values)?; |
| 37932 | 37940 | let spec_ti = array_constructor_type_spec_info(type_spec.as_deref(), st); |
| 37933 | | - let first_ti = spec_ti |
| 37934 | | - .clone() |
| 37935 | | - .or_else(|| first_array_constructor_type_info(values, Some(locals), st, type_layouts)); |
| 37941 | + let first_ti = spec_ti.clone().or_else(|| { |
| 37942 | + first_array_constructor_type_info(values, Some(locals), st, type_layouts) |
| 37943 | + }); |
| 37936 | 37944 | |
| 37937 | 37945 | if expr_is_character_expr(b, locals, first, st, type_layouts) { |
| 37938 | 37946 | if let Some(elem_len_const) = |
@@ -38145,10 +38153,7 @@ fn expr_returns_array( |
| 38145 | 38153 | if let Some(info) = locals.get(&key) { |
| 38146 | 38154 | if local_is_array_like(info) |
| 38147 | 38155 | && args.iter().any(|a| { |
| 38148 | | - matches!( |
| 38149 | | - a.value, |
| 38150 | | - crate::ast::expr::SectionSubscript::Range { .. } |
| 38151 | | - ) |
| 38156 | + matches!(a.value, crate::ast::expr::SectionSubscript::Range { .. }) |
| 38152 | 38157 | }) |
| 38153 | 38158 | { |
| 38154 | 38159 | return true; |
@@ -38427,9 +38432,9 @@ fn lower_1d_section_assign( |
| 38427 | 38432 | dest_args: &[crate::ast::expr::Argument], |
| 38428 | 38433 | value: &crate::ast::expr::SpannedExpr, |
| 38429 | 38434 | ) -> bool { |
| 38430 | | - let any_range = dest_args.iter().any(|a| { |
| 38431 | | - matches!(a.value, crate::ast::expr::SectionSubscript::Range { .. }) |
| 38432 | | - }); |
| 38435 | + let any_range = dest_args |
| 38436 | + .iter() |
| 38437 | + .any(|a| matches!(a.value, crate::ast::expr::SectionSubscript::Range { .. })); |
| 38433 | 38438 | if !any_range { |
| 38434 | 38439 | return false; |
| 38435 | 38440 | } |
@@ -38478,7 +38483,7 @@ fn lower_1d_section_assign( |
| 38478 | 38483 | is_pointer: false, |
| 38479 | 38484 | runtime_dim_upper: vec![], |
| 38480 | 38485 | is_class: false, |
| 38481 | | - logical_kind: None, |
| 38486 | + logical_kind: None, |
| 38482 | 38487 | last_dim_assumed_size: false, |
| 38483 | 38488 | }, |
| 38484 | 38489 | ); |
@@ -38836,7 +38841,7 @@ fn lower_forall_nested( |
| 38836 | 38841 | is_pointer: false, |
| 38837 | 38842 | runtime_dim_upper: vec![], |
| 38838 | 38843 | is_class: false, |
| 38839 | | - logical_kind: None, |
| 38844 | + logical_kind: None, |
| 38840 | 38845 | last_dim_assumed_size: false, |
| 38841 | 38846 | }, |
| 38842 | 38847 | ); |
@@ -39105,10 +39110,8 @@ fn lower_array_assign( |
| 39105 | 39110 | vec![dest_desc, src_desc, null_stat], |
| 39106 | 39111 | IrType::Void, |
| 39107 | 39112 | ); |
| 39108 | | - let dest_base = b.load_typed( |
| 39109 | | - dest_desc, |
| 39110 | | - IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 39111 | | - ); |
| 39113 | + let dest_base = |
| 39114 | + b.load_typed(dest_desc, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 39112 | 39115 | let dest_n = b.call( |
| 39113 | 39116 | FuncRef::External("afs_array_size".into()), |
| 39114 | 39117 | vec![dest_desc], |
@@ -39143,7 +39146,8 @@ fn lower_array_assign( |
| 39143 | 39146 | // constructor's literal values into the destination. |
| 39144 | 39147 | if let Expr::ArrayConstructor { values, .. } = &value.node { |
| 39145 | 39148 | if let Some(type_name) = dest_info.derived_type.as_deref() { |
| 39146 | | - if local_uses_array_descriptor(dest_info) && (dest_info.allocatable || dest_symbol_allocatable) |
| 39149 | + if local_uses_array_descriptor(dest_info) |
| 39150 | + && (dest_info.allocatable || dest_symbol_allocatable) |
| 39147 | 39151 | { |
| 39148 | 39152 | if let Some((src_desc, _)) = lower_array_expr_descriptor( |
| 39149 | 39153 | b, |
@@ -39393,8 +39397,14 @@ fn lower_array_assign( |
| 39393 | 39397 | && !dest_info.allocatable |
| 39394 | 39398 | { |
| 39395 | 39399 | if let Some((src_desc, src_elem_ty)) = lower_array_expr_descriptor( |
| 39396 | | - b, &ctx.locals, value, ctx.st, Some(ctx.type_layouts), |
| 39397 | | - Some(ctx.internal_funcs), Some(ctx.contained_host_refs), Some(ctx.descriptor_params), |
| 39400 | + b, |
| 39401 | + &ctx.locals, |
| 39402 | + value, |
| 39403 | + ctx.st, |
| 39404 | + Some(ctx.type_layouts), |
| 39405 | + Some(ctx.internal_funcs), |
| 39406 | + Some(ctx.contained_host_refs), |
| 39407 | + Some(ctx.descriptor_params), |
| 39398 | 39408 | ) { |
| 39399 | 39409 | let dest_base = array_base_addr(b, dest_info); |
| 39400 | 39410 | let n = array_total_elems_value(b, dest_info); |
@@ -39567,12 +39577,9 @@ fn rewrite_scalarized_section_refs( |
| 39567 | 39577 | } |
| 39568 | 39578 | } |
| 39569 | 39579 | |
| 39570 | | -fn rewrite_scalarized_section_refs_stmt( |
| 39571 | | - stmt: &SpannedStmt, |
| 39572 | | - scalarized: &[String], |
| 39573 | | -) -> SpannedStmt { |
| 39574 | | - use crate::ast::Spanned; |
| 39580 | +fn rewrite_scalarized_section_refs_stmt(stmt: &SpannedStmt, scalarized: &[String]) -> SpannedStmt { |
| 39575 | 39581 | use crate::ast::stmt::Stmt; |
| 39582 | + use crate::ast::Spanned; |
| 39576 | 39583 | match &stmt.node { |
| 39577 | 39584 | Stmt::Assignment { target, value } => Spanned::new( |
| 39578 | 39585 | Stmt::Assignment { |
@@ -39755,7 +39762,9 @@ fn first_arg_is_complex( |
| 39755 | 39762 | .and_then(|a| { |
| 39756 | 39763 | if let crate::ast::expr::SectionSubscript::Element(e) = &a.value { |
| 39757 | 39764 | if let Expr::Name { name } = &e.node { |
| 39758 | | - locals.get(&name.to_lowercase()).map(|i| is_complex_ty(&i.ty)) |
| 39765 | + locals |
| 39766 | + .get(&name.to_lowercase()) |
| 39767 | + .map(|i| is_complex_ty(&i.ty)) |
| 39759 | 39768 | } else { |
| 39760 | 39769 | None |
| 39761 | 39770 | } |
@@ -40083,7 +40092,7 @@ fn component_intrinsic_local_info( |
| 40083 | 40092 | is_pointer: field.pointer, |
| 40084 | 40093 | runtime_dim_upper: vec![], |
| 40085 | 40094 | is_class: false, |
| 40086 | | - logical_kind: None, |
| 40095 | + logical_kind: None, |
| 40087 | 40096 | last_dim_assumed_size: false, |
| 40088 | 40097 | }) |
| 40089 | 40098 | } |
@@ -40109,7 +40118,7 @@ fn component_field_local_info( |
| 40109 | 40118 | is_pointer: field.pointer, |
| 40110 | 40119 | runtime_dim_upper: vec![], |
| 40111 | 40120 | is_class: false, |
| 40112 | | - logical_kind: None, |
| 40121 | + logical_kind: None, |
| 40113 | 40122 | last_dim_assumed_size: false, |
| 40114 | 40123 | }) |
| 40115 | 40124 | } |
@@ -40125,9 +40134,9 @@ fn associate_alias_local_info( |
| 40125 | 40134 | component_field_local_info(b, &ctx.locals, expr, ctx.st, ctx.type_layouts) |
| 40126 | 40135 | } |
| 40127 | 40136 | Expr::FunctionCall { callee, args } => { |
| 40128 | | - let any_range = args.iter().any(|arg| { |
| 40129 | | - matches!(arg.value, crate::ast::expr::SectionSubscript::Range { .. }) |
| 40130 | | - }); |
| 40137 | + let any_range = args |
| 40138 | + .iter() |
| 40139 | + .any(|arg| matches!(arg.value, crate::ast::expr::SectionSubscript::Range { .. })); |
| 40131 | 40140 | if any_range { |
| 40132 | 40141 | // Array section: bind associate-name to a section descriptor so |
| 40133 | 40142 | // the alias behaves as a rank-N array view of the source storage. |
@@ -40172,7 +40181,7 @@ fn associate_alias_local_info( |
| 40172 | 40181 | is_pointer: false, |
| 40173 | 40182 | runtime_dim_upper: vec![], |
| 40174 | 40183 | is_class: false, |
| 40175 | | - logical_kind: None, |
| 40184 | + logical_kind: None, |
| 40176 | 40185 | last_dim_assumed_size: false, |
| 40177 | 40186 | }); |
| 40178 | 40187 | } |
@@ -40203,7 +40212,7 @@ fn associate_alias_local_info( |
| 40203 | 40212 | is_pointer: false, |
| 40204 | 40213 | runtime_dim_upper: vec![], |
| 40205 | 40214 | is_class: false, |
| 40206 | | - logical_kind: None, |
| 40215 | + logical_kind: None, |
| 40207 | 40216 | last_dim_assumed_size: false, |
| 40208 | 40217 | }); |
| 40209 | 40218 | } |
@@ -40231,7 +40240,7 @@ fn associate_alias_local_info( |
| 40231 | 40240 | is_pointer: false, |
| 40232 | 40241 | runtime_dim_upper: vec![], |
| 40233 | 40242 | is_class: false, |
| 40234 | | - logical_kind: None, |
| 40243 | + logical_kind: None, |
| 40235 | 40244 | last_dim_assumed_size: false, |
| 40236 | 40245 | }); |
| 40237 | 40246 | } |
@@ -40354,25 +40363,27 @@ fn lower_array_intrinsic( |
| 40354 | 40363 | // pick the size_dim runtime entry — a `kind=` keyword arg |
| 40355 | 40364 | // alone (e.g. `size(a, kind=ilp)`) means total size, not |
| 40356 | 40365 | // size-along-dim. Treat positional second arg as dim. |
| 40357 | | - let dim_arg_expr = args.iter().enumerate().find_map(|(i, a)| match a.keyword.as_deref() |
| 40358 | | - { |
| 40359 | | - Some(k) if k.eq_ignore_ascii_case("dim") => { |
| 40360 | | - if let crate::ast::expr::SectionSubscript::Element(e) = &a.value { |
| 40361 | | - Some(e) |
| 40362 | | - } else { |
| 40363 | | - None |
| 40364 | | - } |
| 40365 | | - } |
| 40366 | | - Some(_) => None, // kind= or other — not a dim arg |
| 40367 | | - None if i == 1 => { |
| 40368 | | - if let crate::ast::expr::SectionSubscript::Element(e) = &a.value { |
| 40369 | | - Some(e) |
| 40370 | | - } else { |
| 40371 | | - None |
| 40372 | | - } |
| 40373 | | - } |
| 40374 | | - None => None, |
| 40375 | | - }); |
| 40366 | + let dim_arg_expr = |
| 40367 | + args.iter() |
| 40368 | + .enumerate() |
| 40369 | + .find_map(|(i, a)| match a.keyword.as_deref() { |
| 40370 | + Some(k) if k.eq_ignore_ascii_case("dim") => { |
| 40371 | + if let crate::ast::expr::SectionSubscript::Element(e) = &a.value { |
| 40372 | + Some(e) |
| 40373 | + } else { |
| 40374 | + None |
| 40375 | + } |
| 40376 | + } |
| 40377 | + Some(_) => None, // kind= or other — not a dim arg |
| 40378 | + None if i == 1 => { |
| 40379 | + if let crate::ast::expr::SectionSubscript::Element(e) = &a.value { |
| 40380 | + Some(e) |
| 40381 | + } else { |
| 40382 | + None |
| 40383 | + } |
| 40384 | + } |
| 40385 | + None => None, |
| 40386 | + }); |
| 40376 | 40387 | if let Some(e) = dim_arg_expr { |
| 40377 | 40388 | // SIZE(array, dim) |
| 40378 | 40389 | { |
@@ -41356,13 +41367,7 @@ fn clear_derived_storage_for_intent_out( |
| 41356 | 41367 | for idx in 0..elem_count { |
| 41357 | 41368 | let byte_off = b.const_i64(idx * elem_bytes); |
| 41358 | 41369 | let elem_ptr = b.gep(field_ptr, vec![byte_off], IrType::Int(IntWidth::I8)); |
| 41359 | | - clear_derived_storage_for_intent_out( |
| 41360 | | - b, |
| 41361 | | - elem_ptr, |
| 41362 | | - nested_layout, |
| 41363 | | - registry, |
| 41364 | | - stat_addr, |
| 41365 | | - ); |
| 41370 | + clear_derived_storage_for_intent_out(b, elem_ptr, nested_layout, registry, stat_addr); |
| 41366 | 41371 | } |
| 41367 | 41372 | } |
| 41368 | 41373 | |
@@ -41583,7 +41588,9 @@ fn resolve_component_base( |
| 41583 | 41588 | // Pointer dummies passed by reference add one more layer: |
| 41584 | 41589 | // info.addr points at the caller's pointer slot, whose |
| 41585 | 41590 | // contents then point at the associated struct. |
| 41586 | | - let addr = if info.is_pointer && local_uses_array_descriptor(info) && info.dims.is_empty() |
| 41591 | + let addr = if info.is_pointer |
| 41592 | + && local_uses_array_descriptor(info) |
| 41593 | + && info.dims.is_empty() |
| 41587 | 41594 | { |
| 41588 | 41595 | array_base_addr(b, info) |
| 41589 | 41596 | } else if info.is_pointer { |
@@ -41805,7 +41812,7 @@ fn component_array_local_info( |
| 41805 | 41812 | is_pointer: field.pointer, |
| 41806 | 41813 | runtime_dim_upper: vec![], |
| 41807 | 41814 | is_class: false, |
| 41808 | | - logical_kind: None, |
| 41815 | + logical_kind: None, |
| 41809 | 41816 | last_dim_assumed_size: false, |
| 41810 | 41817 | }) |
| 41811 | 41818 | } |
@@ -42059,7 +42066,7 @@ fn expr_is_character_expr( |
| 42059 | 42066 | is_pointer: field.pointer, |
| 42060 | 42067 | runtime_dim_upper: vec![], |
| 42061 | 42068 | is_class: false, |
| 42062 | | - logical_kind: None, |
| 42069 | + logical_kind: None, |
| 42063 | 42070 | last_dim_assumed_size: false, |
| 42064 | 42071 | }, |
| 42065 | 42072 | ) |
@@ -42131,7 +42138,11 @@ fn allocate_hidden_result_buffer( |
| 42131 | 42138 | IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 42132 | 42139 | ); |
| 42133 | 42140 | let typed = if abi == HiddenResultAbi::ComplexBuffer { |
| 42134 | | - let fw = if bytes == 16 { FloatWidth::F64 } else { FloatWidth::F32 }; |
| 42141 | + let fw = if bytes == 16 { |
| 42142 | + FloatWidth::F64 |
| 42143 | + } else { |
| 42144 | + FloatWidth::F32 |
| 42145 | + }; |
| 42135 | 42146 | let cplx_ty = IrType::Array(Box::new(IrType::Float(fw)), 2); |
| 42136 | 42147 | let zero = b.const_i64(0); |
| 42137 | 42148 | b.gep(raw, vec![zero], cplx_ty) |
@@ -42152,8 +42163,9 @@ fn hidden_result_temp_bytes_for_callee( |
| 42152 | 42163 | HiddenResultAbi::ArrayDescriptor => Some(384), |
| 42153 | 42164 | HiddenResultAbi::StringDescriptor => Some(32), |
| 42154 | 42165 | HiddenResultAbi::DerivedAggregate => { |
| 42155 | | - let type_name = |
| 42156 | | - first_procedure_lookup(abi_lookup_keys, |k| callee_return_derived_type_name(st, k))?; |
| 42166 | + let type_name = first_procedure_lookup(abi_lookup_keys, |k| { |
| 42167 | + callee_return_derived_type_name(st, k) |
| 42168 | + })?; |
| 42157 | 42169 | let layout = type_layouts?.get(&type_name)?; |
| 42158 | 42170 | Some(layout.size.max(1) as u64) |
| 42159 | 42171 | } |
@@ -42163,13 +42175,16 @@ fn hidden_result_temp_bytes_for_callee( |
| 42163 | 42175 | // symbol can't be resolved — same fallback DerivedAggregate |
| 42164 | 42176 | // uses for missing layouts. |
| 42165 | 42177 | use crate::sema::symtab::TypeInfo; |
| 42166 | | - let kind_bytes = abi_lookup_keys.iter().find_map(|k| { |
| 42167 | | - let sym = st.find_symbol_any_scope(&k.to_lowercase())?; |
| 42168 | | - match sym.type_info.as_ref()? { |
| 42169 | | - TypeInfo::Complex { kind } => Some(kind.unwrap_or(4) as u64 * 2), |
| 42170 | | - _ => None, |
| 42171 | | - } |
| 42172 | | - }).unwrap_or(8); |
| 42178 | + let kind_bytes = abi_lookup_keys |
| 42179 | + .iter() |
| 42180 | + .find_map(|k| { |
| 42181 | + let sym = st.find_symbol_any_scope(&k.to_lowercase())?; |
| 42182 | + match sym.type_info.as_ref()? { |
| 42183 | + TypeInfo::Complex { kind } => Some(kind.unwrap_or(4) as u64 * 2), |
| 42184 | + _ => None, |
| 42185 | + } |
| 42186 | + }) |
| 42187 | + .unwrap_or(8); |
| 42173 | 42188 | Some(kind_bytes) |
| 42174 | 42189 | } |
| 42175 | 42190 | } |
@@ -42739,7 +42754,7 @@ fn ensure_hidden_string_result_local( |
| 42739 | 42754 | is_pointer: false, |
| 42740 | 42755 | runtime_dim_upper: vec![], |
| 42741 | 42756 | is_class: false, |
| 42742 | | - logical_kind: None, |
| 42757 | + logical_kind: None, |
| 42743 | 42758 | last_dim_assumed_size: false, |
| 42744 | 42759 | }, |
| 42745 | 42760 | ); |
@@ -42777,7 +42792,7 @@ fn ensure_hidden_string_result_local( |
| 42777 | 42792 | is_pointer: false, |
| 42778 | 42793 | runtime_dim_upper: vec![], |
| 42779 | 42794 | is_class: false, |
| 42780 | | - logical_kind: None, |
| 42795 | + logical_kind: None, |
| 42781 | 42796 | last_dim_assumed_size: false, |
| 42782 | 42797 | }, |
| 42783 | 42798 | ); |
@@ -42829,7 +42844,7 @@ fn ensure_hidden_string_result_local( |
| 42829 | 42844 | is_pointer: false, |
| 42830 | 42845 | runtime_dim_upper: vec![], |
| 42831 | 42846 | is_class: false, |
| 42832 | | - logical_kind: None, |
| 42847 | + logical_kind: None, |
| 42833 | 42848 | last_dim_assumed_size: false, |
| 42834 | 42849 | }, |
| 42835 | 42850 | ); |
@@ -42936,8 +42951,7 @@ fn allocate_status_target_addr(b: &mut FuncBuilder, ctx: &LowerCtx, opts: &[IoCo |
| 42936 | 42951 | "ALLOCATE/DEALLOCATE STAT= must name a scalar integer variable", |
| 42937 | 42952 | ); |
| 42938 | 42953 | }; |
| 42939 | | - let is_scalar_int = info.dims.is_empty() |
| 42940 | | - && matches!(info.ty, IrType::Int(_)); |
| 42954 | + let is_scalar_int = info.dims.is_empty() && matches!(info.ty, IrType::Int(_)); |
| 42941 | 42955 | if !is_scalar_int { |
| 42942 | 42956 | lower_stmt_error( |
| 42943 | 42957 | stat_expr.span, |
@@ -43167,7 +43181,10 @@ fn emit_derived_array_desc_copy( |
| 43167 | 43181 | let dest_stride = load_array_desc_i64_field(b, dest_desc, 24 + 16); |
| 43168 | 43182 | let src_stride = load_array_desc_i64_field(b, source_desc, 24 + 16); |
| 43169 | 43183 | let dest_base = b.load_typed(dest_desc, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 43170 | | - let src_base = b.load_typed(source_desc, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 43184 | + let src_base = b.load_typed( |
| 43185 | + source_desc, |
| 43186 | + IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 43187 | + ); |
| 43171 | 43188 | |
| 43172 | 43189 | if derived_layout_needs_runtime_initialization(layout, type_layouts) { |
| 43173 | 43190 | initialize_derived_array_storage_dynamic(b, dest_base, layout, dest_n, type_layouts); |
@@ -43260,8 +43277,10 @@ fn emit_allocatable_source_copy_on_success( |
| 43260 | 43277 | Some(ScalarAllocSourceCopyPlan::Static(type_name)) => { |
| 43261 | 43278 | let dest_base = |
| 43262 | 43279 | b.load_typed(dest_desc, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 43263 | | - let source_base = |
| 43264 | | - b.load_typed(source_desc, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))); |
| 43280 | + let source_base = b.load_typed( |
| 43281 | + source_desc, |
| 43282 | + IrType::Ptr(Box::new(IrType::Int(IntWidth::I8))), |
| 43283 | + ); |
| 43265 | 43284 | emit_derived_value_copy(b, type_layouts, type_name, dest_base, source_base); |
| 43266 | 43285 | true |
| 43267 | 43286 | } |
@@ -43289,10 +43308,8 @@ fn emit_allocatable_source_copy_on_success( |
| 43289 | 43308 | .map(|(i, _)| b.create_block(&format!("alloc_source_dispatch_case_{}", i))) |
| 43290 | 43309 | .collect(); |
| 43291 | 43310 | b.branch(test_blocks[0], vec![]); |
| 43292 | | - for (idx, ((type_tag, type_name), case_bb)) in candidates |
| 43293 | | - .iter() |
| 43294 | | - .zip(case_blocks.iter()) |
| 43295 | | - .enumerate() |
| 43311 | + for (idx, ((type_tag, type_name), case_bb)) in |
| 43312 | + candidates.iter().zip(case_blocks.iter()).enumerate() |
| 43296 | 43313 | { |
| 43297 | 43314 | b.set_block(test_blocks[idx]); |
| 43298 | 43315 | let want_tag = b.const_i64(*type_tag as i64); |
@@ -43305,13 +43322,7 @@ fn emit_allocatable_source_copy_on_success( |
| 43305 | 43322 | b.cond_branch(is_match, *case_bb, vec![], next_bb, vec![]); |
| 43306 | 43323 | |
| 43307 | 43324 | b.set_block(*case_bb); |
| 43308 | | - emit_derived_value_copy( |
| 43309 | | - b, |
| 43310 | | - type_layouts, |
| 43311 | | - type_name, |
| 43312 | | - dest_base, |
| 43313 | | - source_base, |
| 43314 | | - ); |
| 43325 | + emit_derived_value_copy(b, type_layouts, type_name, dest_base, source_base); |
| 43315 | 43326 | b.branch(done_bb, vec![]); |
| 43316 | 43327 | } |
| 43317 | 43328 | b.set_block(fallback); |
@@ -43339,8 +43350,7 @@ fn static_expr_type_tag_value( |
| 43339 | 43350 | st: &SymbolTable, |
| 43340 | 43351 | type_layouts: &crate::sema::type_layout::TypeLayoutRegistry, |
| 43341 | 43352 | ) -> Option<ValueId> { |
| 43342 | | - expr_type_layout(expr, None, st, type_layouts) |
| 43343 | | - .map(|layout| b.const_i64(layout.type_tag as i64)) |
| 43353 | + expr_type_layout(expr, None, st, type_layouts).map(|layout| b.const_i64(layout.type_tag as i64)) |
| 43344 | 43354 | } |
| 43345 | 43355 | |
| 43346 | 43356 | fn derived_type_tag_value( |
@@ -43353,9 +43363,7 @@ fn derived_type_tag_value( |
| 43353 | 43363 | .map(|layout| b.const_i64(layout.type_tag as i64)) |
| 43354 | 43364 | } |
| 43355 | 43365 | |
| 43356 | | -fn type_layout_tbp_lookup_symbol( |
| 43357 | | - layout: &crate::sema::type_layout::TypeLayout, |
| 43358 | | -) -> Option<String> { |
| 43366 | +fn type_layout_tbp_lookup_symbol(layout: &crate::sema::type_layout::TypeLayout) -> Option<String> { |
| 43359 | 43367 | if layout.bound_procs.is_empty() { |
| 43360 | 43368 | return None; |
| 43361 | 43369 | } |
@@ -43420,8 +43428,7 @@ fn static_alloc_target_type_tag_value( |
| 43420 | 43428 | st: &SymbolTable, |
| 43421 | 43429 | type_layouts: &crate::sema::type_layout::TypeLayoutRegistry, |
| 43422 | 43430 | ) -> Option<ValueId> { |
| 43423 | | - expr_type_layout(expr, None, st, type_layouts) |
| 43424 | | - .map(|layout| b.const_i64(layout.type_tag as i64)) |
| 43431 | + expr_type_layout(expr, None, st, type_layouts).map(|layout| b.const_i64(layout.type_tag as i64)) |
| 43425 | 43432 | } |
| 43426 | 43433 | |
| 43427 | 43434 | fn static_alloc_target_tbp_lookup_value( |
@@ -43639,18 +43646,18 @@ fn resolve_component_base_for_method( |
| 43639 | 43646 | let key = name.to_lowercase(); |
| 43640 | 43647 | let info = locals.get(&key)?; |
| 43641 | 43648 | let type_name = info.derived_type.as_ref()?.clone(); |
| 43642 | | - let addr = if info.is_pointer && local_uses_array_descriptor(info) && info.dims.is_empty() |
| 43643 | | - { |
| 43644 | | - array_base_addr(b, info) |
| 43645 | | - } else if info.is_pointer { |
| 43646 | | - b.load_typed(info.addr, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))) |
| 43647 | | - } else if info.allocatable { |
| 43648 | | - array_base_addr(b, info) |
| 43649 | | - } else if info.by_ref { |
| 43650 | | - b.load(info.addr) |
| 43651 | | - } else { |
| 43652 | | - info.addr |
| 43653 | | - }; |
| 43649 | + let addr = |
| 43650 | + if info.is_pointer && local_uses_array_descriptor(info) && info.dims.is_empty() { |
| 43651 | + array_base_addr(b, info) |
| 43652 | + } else if info.is_pointer { |
| 43653 | + b.load_typed(info.addr, IrType::Ptr(Box::new(IrType::Int(IntWidth::I8)))) |
| 43654 | + } else if info.allocatable { |
| 43655 | + array_base_addr(b, info) |
| 43656 | + } else if info.by_ref { |
| 43657 | + b.load(info.addr) |
| 43658 | + } else { |
| 43659 | + info.addr |
| 43660 | + }; |
| 43654 | 43661 | Some((addr, type_name)) |
| 43655 | 43662 | } |
| 43656 | 43663 | Expr::ComponentAccess { |
@@ -44069,7 +44076,7 @@ fn lower_arg_by_ref_full( |
| 44069 | 44076 | is_pointer: false, |
| 44070 | 44077 | runtime_dim_upper: vec![], |
| 44071 | 44078 | is_class: false, |
| 44072 | | - logical_kind: None, |
| 44079 | + logical_kind: None, |
| 44073 | 44080 | last_dim_assumed_size: false, |
| 44074 | 44081 | }; |
| 44075 | 44082 | return derived_scalar_storage_addr_for_call(b, &info); |
@@ -44589,11 +44596,18 @@ fn substitute_names_in_expr( |
| 44589 | 44596 | match v { |
| 44590 | 44597 | AcValue::Expr(e) => AcValue::Expr(substitute_names_in_expr(e, subst)), |
| 44591 | 44598 | AcValue::ImpliedDo(ido) => AcValue::ImpliedDo(Box::new(ImpliedDoLoop { |
| 44592 | | - values: ido.values.iter().map(|v| rewrite_acvalue(v, subst)).collect(), |
| 44599 | + values: ido |
| 44600 | + .values |
| 44601 | + .iter() |
| 44602 | + .map(|v| rewrite_acvalue(v, subst)) |
| 44603 | + .collect(), |
| 44593 | 44604 | var: ido.var.clone(), |
| 44594 | 44605 | start: substitute_names_in_expr(&ido.start, subst), |
| 44595 | 44606 | end: substitute_names_in_expr(&ido.end, subst), |
| 44596 | | - step: ido.step.as_ref().map(|e| substitute_names_in_expr(e, subst)), |
| 44607 | + step: ido |
| 44608 | + .step |
| 44609 | + .as_ref() |
| 44610 | + .map(|e| substitute_names_in_expr(e, subst)), |
| 44597 | 44611 | })), |
| 44598 | 44612 | } |
| 44599 | 44613 | } |
@@ -44663,7 +44677,9 @@ fn lower_expr_full( |
| 44663 | 44677 | let clean = text.split('_').next().unwrap_or(text); |
| 44664 | 44678 | let kind_width = kind |
| 44665 | 44679 | .as_deref() |
| 44666 | | - .map(|kind_str| int_kind_to_width_in_context(kind_str, Some(locals), None, Some(st))) |
| 44680 | + .map(|kind_str| { |
| 44681 | + int_kind_to_width_in_context(kind_str, Some(locals), None, Some(st)) |
| 44682 | + }) |
| 44667 | 44683 | .unwrap_or_else(crate::driver::defaults::default_int_kind); |
| 44668 | 44684 | let val: i128 = clean.parse().unwrap_or(0); |
| 44669 | 44685 | let width = match kind_width { |
@@ -45296,8 +45312,14 @@ fn lower_expr_full( |
| 45296 | 45312 | if let Expr::Name { name } = &callee.node { |
| 45297 | 45313 | if name.eq_ignore_ascii_case("transfer") && args.len() >= 2 { |
| 45298 | 45314 | if let Some(result) = lower_transfer_intrinsic( |
| 45299 | | - b, locals, args, st, type_layouts, |
| 45300 | | - internal_funcs, contained_host_refs, descriptor_params, |
| 45315 | + b, |
| 45316 | + locals, |
| 45317 | + args, |
| 45318 | + st, |
| 45319 | + type_layouts, |
| 45320 | + internal_funcs, |
| 45321 | + contained_host_refs, |
| 45322 | + descriptor_params, |
| 45301 | 45323 | ) { |
| 45302 | 45324 | return result; |
| 45303 | 45325 | } |
@@ -45402,19 +45424,17 @@ fn lower_expr_full( |
| 45402 | 45424 | } |
| 45403 | 45425 | |
| 45404 | 45426 | // Check for array intrinsics (SIZE, SUM, etc.) that need descriptor addresses. |
| 45405 | | - if let Some(result) = |
| 45406 | | - lower_array_intrinsic( |
| 45407 | | - b, |
| 45408 | | - locals, |
| 45409 | | - &key, |
| 45410 | | - args, |
| 45411 | | - st, |
| 45412 | | - type_layouts, |
| 45413 | | - internal_funcs, |
| 45414 | | - contained_host_refs, |
| 45415 | | - descriptor_params, |
| 45416 | | - ) |
| 45417 | | - { |
| 45427 | + if let Some(result) = lower_array_intrinsic( |
| 45428 | + b, |
| 45429 | + locals, |
| 45430 | + &key, |
| 45431 | + args, |
| 45432 | + st, |
| 45433 | + type_layouts, |
| 45434 | + internal_funcs, |
| 45435 | + contained_host_refs, |
| 45436 | + descriptor_params, |
| 45437 | + ) { |
| 45418 | 45438 | return result; |
| 45419 | 45439 | } |
| 45420 | 45440 | |
@@ -45666,8 +45686,7 @@ fn lower_expr_full( |
| 45666 | 45686 | tmp |
| 45667 | 45687 | } |
| 45668 | 45688 | }; |
| 45669 | | - let re_ptr = |
| 45670 | | - b.gep(buf, vec![zero_off], IrType::Int(IntWidth::I8)); |
| 45689 | + let re_ptr = b.gep(buf, vec![zero_off], IrType::Int(IntWidth::I8)); |
| 45671 | 45690 | let im_ptr = |
| 45672 | 45691 | b.gep(buf, vec![lane_bytes], IrType::Int(IntWidth::I8)); |
| 45673 | 45692 | let re_in = b.load_typed(re_ptr, elem.clone()); |
@@ -45698,8 +45717,7 @@ fn lower_expr_full( |
| 45698 | 45717 | let half_plus_pos = b.fcmp(CmpOp::Ge, half_plus, zero_f); |
| 45699 | 45718 | let half_plus_safe = b.select(half_plus_pos, half_plus, zero_f); |
| 45700 | 45719 | let half_minus_pos = b.fcmp(CmpOp::Ge, half_minus, zero_f); |
| 45701 | | - let half_minus_safe = |
| 45702 | | - b.select(half_minus_pos, half_minus, zero_f); |
| 45720 | + let half_minus_safe = b.select(half_minus_pos, half_minus, zero_f); |
| 45703 | 45721 | let re_out = b.fsqrt(half_plus_safe); |
| 45704 | 45722 | let im_mag = b.fsqrt(half_minus_safe); |
| 45705 | 45723 | let im_neg = b.fneg(im_mag); |
@@ -45707,8 +45725,7 @@ fn lower_expr_full( |
| 45707 | 45725 | let im_out = b.select(b_nonneg, im_mag, im_neg); |
| 45708 | 45726 | |
| 45709 | 45727 | let out = b.alloca(arr_ty); |
| 45710 | | - let out_re = |
| 45711 | | - b.gep(out, vec![zero_off], IrType::Int(IntWidth::I8)); |
| 45728 | + let out_re = b.gep(out, vec![zero_off], IrType::Int(IntWidth::I8)); |
| 45712 | 45729 | let out_im = |
| 45713 | 45730 | b.gep(out, vec![lane_bytes], IrType::Int(IntWidth::I8)); |
| 45714 | 45731 | b.store(re_out, out_re); |
@@ -45789,14 +45806,10 @@ fn lower_expr_full( |
| 45789 | 45806 | { |
| 45790 | 45807 | if let Some(arg) = args.first() { |
| 45791 | 45808 | if let crate::ast::expr::SectionSubscript::Element(arg_expr) = &arg.value { |
| 45792 | | - if let Some(elem_ty) = ast_arg_element_ir_type( |
| 45793 | | - arg_expr, |
| 45794 | | - locals, |
| 45795 | | - st, |
| 45796 | | - type_layouts, |
| 45797 | | - ) { |
| 45798 | | - if let Some(v) = lower_numeric_inquiry_constant(b, &key, &elem_ty) |
| 45799 | | - { |
| 45809 | + if let Some(elem_ty) = |
| 45810 | + ast_arg_element_ir_type(arg_expr, locals, st, type_layouts) |
| 45811 | + { |
| 45812 | + if let Some(v) = lower_numeric_inquiry_constant(b, &key, &elem_ty) { |
| 45800 | 45813 | return v; |
| 45801 | 45814 | } |
| 45802 | 45815 | } |
@@ -46294,17 +46307,14 @@ fn lower_expr_full( |
| 46294 | 46307 | { |
| 46295 | 46308 | let abi_lookup_keys = |
| 46296 | 46309 | procedure_abi_lookup_keys(st, &[&signature_key]); |
| 46297 | | - let ret_ty = first_procedure_lookup( |
| 46298 | | - &abi_lookup_keys, |
| 46299 | | - |k| callee_return_ir_type(st, k), |
| 46300 | | - ) |
| 46310 | + let ret_ty = first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46311 | + callee_return_ir_type(st, k) |
| 46312 | + }) |
| 46301 | 46313 | .unwrap_or(IrType::Int(IntWidth::I32)); |
| 46302 | | - let mut arg_vals: Vec<ValueId> = |
| 46303 | | - Vec::with_capacity(args.len()); |
| 46314 | + let mut arg_vals: Vec<ValueId> = Vec::with_capacity(args.len()); |
| 46304 | 46315 | for arg in args { |
| 46305 | | - if let crate::ast::expr::SectionSubscript::Element( |
| 46306 | | - e, |
| 46307 | | - ) = &arg.value |
| 46316 | + if let crate::ast::expr::SectionSubscript::Element(e) = |
| 46317 | + &arg.value |
| 46308 | 46318 | { |
| 46309 | 46319 | arg_vals.push(lower_arg_by_ref_full( |
| 46310 | 46320 | b, |
@@ -46318,272 +46328,211 @@ fn lower_expr_full( |
| 46318 | 46328 | )); |
| 46319 | 46329 | } |
| 46320 | 46330 | } |
| 46321 | | - return b.call( |
| 46322 | | - FuncRef::Indirect(target_ptr), |
| 46323 | | - arg_vals, |
| 46324 | | - ret_ty, |
| 46325 | | - ); |
| 46331 | + return b.call(FuncRef::Indirect(target_ptr), arg_vals, ret_ty); |
| 46326 | 46332 | } |
| 46327 | 46333 | } |
| 46328 | 46334 | let bp = bp_opt.unwrap_or_else(|| { |
| 46329 | 46335 | fail_unmatched_bound_proc_resolution(callee.span, layout, component) |
| 46330 | 46336 | }); |
| 46331 | | - let target = bp.target_name.clone(); |
| 46332 | | - let target_key = abi_key_for_link_name(st, &target) |
| 46333 | | - .unwrap_or_else(|| bp.abi_name.clone()); |
| 46334 | | - let call_name = target.clone(); |
| 46335 | | - let nopass = bp.nopass; |
| 46336 | | - let arg_slots = reorder_args_by_keyword_slots_with_formal_skip( |
| 46337 | | - args, |
| 46338 | | - &target_key, |
| 46339 | | - st, |
| 46340 | | - if nopass { 0 } else { 1 }, |
| 46341 | | - ); |
| 46342 | | - let abi_lookup_keys = procedure_abi_lookup_keys( |
| 46337 | + let target = bp.target_name.clone(); |
| 46338 | + let target_key = abi_key_for_link_name(st, &target) |
| 46339 | + .unwrap_or_else(|| bp.abi_name.clone()); |
| 46340 | + let call_name = target.clone(); |
| 46341 | + let nopass = bp.nopass; |
| 46342 | + let arg_slots = reorder_args_by_keyword_slots_with_formal_skip( |
| 46343 | + args, |
| 46344 | + &target_key, |
| 46345 | + st, |
| 46346 | + if nopass { 0 } else { 1 }, |
| 46347 | + ); |
| 46348 | + let abi_lookup_keys = |
| 46349 | + procedure_abi_lookup_keys(st, &[call_name.as_str(), &target_key]); |
| 46350 | + let abi_primary_key = abi_lookup_keys |
| 46351 | + .first() |
| 46352 | + .map(String::as_str) |
| 46353 | + .unwrap_or(target_key.as_str()); |
| 46354 | + if let Some(hidden_abi) = |
| 46355 | + first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46356 | + callee_hidden_result_abi(st, k) |
| 46357 | + }) |
| 46358 | + { |
| 46359 | + if let Some((raw, typed)) = allocate_hidden_result_buffer( |
| 46360 | + b, |
| 46343 | 46361 | st, |
| 46344 | | - &[call_name.as_str(), &target_key], |
| 46345 | | - ); |
| 46346 | | - let abi_primary_key = abi_lookup_keys |
| 46347 | | - .first() |
| 46348 | | - .map(String::as_str) |
| 46349 | | - .unwrap_or(target_key.as_str()); |
| 46350 | | - if let Some(hidden_abi) = |
| 46351 | | - first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46352 | | - callee_hidden_result_abi(st, k) |
| 46353 | | - }) |
| 46354 | | - { |
| 46355 | | - if let Some((raw, typed)) = allocate_hidden_result_buffer( |
| 46362 | + type_layouts, |
| 46363 | + &abi_lookup_keys, |
| 46364 | + hidden_abi, |
| 46365 | + ) { |
| 46366 | + emit_bound_function_call( |
| 46356 | 46367 | b, |
| 46368 | + locals, |
| 46357 | 46369 | st, |
| 46358 | 46370 | type_layouts, |
| 46359 | | - &abi_lookup_keys, |
| 46360 | | - hidden_abi, |
| 46361 | | - ) { |
| 46362 | | - emit_bound_function_call( |
| 46363 | | - b, |
| 46364 | | - locals, |
| 46365 | | - st, |
| 46366 | | - type_layouts, |
| 46367 | | - internal_funcs, |
| 46368 | | - contained_host_refs, |
| 46369 | | - descriptor_params, |
| 46370 | | - callee.span, |
| 46371 | | - base, |
| 46372 | | - component, |
| 46373 | | - args, |
| 46374 | | - Some(raw), |
| 46375 | | - IrType::Void, |
| 46376 | | - ); |
| 46377 | | - return typed; |
| 46378 | | - } |
| 46371 | + internal_funcs, |
| 46372 | + contained_host_refs, |
| 46373 | + descriptor_params, |
| 46374 | + callee.span, |
| 46375 | + base, |
| 46376 | + component, |
| 46377 | + args, |
| 46378 | + Some(raw), |
| 46379 | + IrType::Void, |
| 46380 | + ); |
| 46381 | + return typed; |
| 46379 | 46382 | } |
| 46380 | | - let callee_value_args = |
| 46381 | | - first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46382 | | - callee_value_arg_mask(st, k) |
| 46383 | | - }); |
| 46384 | | - let callee_descriptor_args = |
| 46385 | | - first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46386 | | - descriptor_params |
| 46387 | | - .and_then(|m| cached_param_mask_for_lookup(st, m, k)) |
| 46388 | | - }); |
| 46389 | | - let callee_string_descriptor_args = |
| 46390 | | - first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46391 | | - callee_string_descriptor_arg_mask(st, k) |
| 46392 | | - }); |
| 46393 | | - let callee_bind_c_char_args = |
| 46394 | | - first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46395 | | - callee_bind_c_char_arg_mask(st, k) |
| 46396 | | - }); |
| 46397 | | - let callee_pointer_args = |
| 46398 | | - first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46399 | | - callee_pointer_arg_mask(st, k) |
| 46400 | | - }); |
| 46401 | | - let opt_flags = first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46402 | | - callee_optional_arg_mask(st, k) |
| 46383 | + } |
| 46384 | + let callee_value_args = first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46385 | + callee_value_arg_mask(st, k) |
| 46386 | + }); |
| 46387 | + let callee_descriptor_args = |
| 46388 | + first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46389 | + descriptor_params |
| 46390 | + .and_then(|m| cached_param_mask_for_lookup(st, m, k)) |
| 46391 | + }); |
| 46392 | + let callee_string_descriptor_args = |
| 46393 | + first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46394 | + callee_string_descriptor_arg_mask(st, k) |
| 46395 | + }); |
| 46396 | + let callee_bind_c_char_args = |
| 46397 | + first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46398 | + callee_bind_c_char_arg_mask(st, k) |
| 46399 | + }); |
| 46400 | + let callee_pointer_args = |
| 46401 | + first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46402 | + callee_pointer_arg_mask(st, k) |
| 46403 | + }); |
| 46404 | + let opt_flags = first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46405 | + callee_optional_arg_mask(st, k) |
| 46406 | + }); |
| 46407 | + let callee_char_len_star_args = |
| 46408 | + first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46409 | + callee_char_len_star_mask(st, k) |
| 46403 | 46410 | }); |
| 46404 | | - let callee_char_len_star_args = |
| 46405 | | - first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46406 | | - callee_char_len_star_mask(st, k) |
| 46407 | | - }); |
| 46408 | 46411 | |
| 46409 | | - let mut call_args = Vec::with_capacity(arg_slots.len() + 1); |
| 46410 | | - for (i, slot) in arg_slots.iter().enumerate() { |
| 46411 | | - if !nopass && i == 0 { |
| 46412 | | - let wants_bind_c_char = callee_bind_c_char_args |
| 46413 | | - .as_ref() |
| 46414 | | - .map(|mask| mask.first().copied().unwrap_or(false)) |
| 46415 | | - .unwrap_or(false); |
| 46416 | | - let wants_descriptor = callee_descriptor_args |
| 46417 | | - .as_ref() |
| 46418 | | - .map(|mask| mask.first().copied().unwrap_or(false)) |
| 46419 | | - .unwrap_or(false) |
| 46420 | | - && !wants_bind_c_char; |
| 46421 | | - call_args.push(if wants_descriptor { |
| 46422 | | - lower_arg_descriptor( |
| 46423 | | - b, |
| 46424 | | - locals, |
| 46425 | | - base, |
| 46426 | | - st, |
| 46427 | | - type_layouts, |
| 46428 | | - false, |
| 46429 | | - ) |
| 46430 | | - } else { |
| 46431 | | - obj_addr |
| 46432 | | - }); |
| 46433 | | - continue; |
| 46434 | | - } |
| 46435 | | - let is_value = callee_value_args |
| 46436 | | - .as_ref() |
| 46437 | | - .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46438 | | - .unwrap_or(false); |
| 46439 | | - let wants_descriptor = callee_descriptor_args |
| 46440 | | - .as_ref() |
| 46441 | | - .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46442 | | - .unwrap_or(false); |
| 46443 | | - let wants_string_descriptor = callee_string_descriptor_args |
| 46444 | | - .as_ref() |
| 46445 | | - .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46446 | | - .unwrap_or(false); |
| 46412 | + let mut call_args = Vec::with_capacity(arg_slots.len() + 1); |
| 46413 | + for (i, slot) in arg_slots.iter().enumerate() { |
| 46414 | + if !nopass && i == 0 { |
| 46447 | 46415 | let wants_bind_c_char = callee_bind_c_char_args |
| 46448 | 46416 | .as_ref() |
| 46449 | | - .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46417 | + .map(|mask| mask.first().copied().unwrap_or(false)) |
| 46450 | 46418 | .unwrap_or(false); |
| 46451 | | - let wants_descriptor = wants_descriptor && !wants_bind_c_char; |
| 46452 | | - let wants_string_descriptor = |
| 46453 | | - wants_string_descriptor && !wants_bind_c_char; |
| 46454 | | - let wants_pointer = callee_pointer_args |
| 46419 | + let wants_descriptor = callee_descriptor_args |
| 46455 | 46420 | .as_ref() |
| 46456 | | - .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46457 | | - .unwrap_or(false); |
| 46458 | | - let value = match slot { |
| 46459 | | - Some(arg) => match &arg.value { |
| 46460 | | - crate::ast::expr::SectionSubscript::Element(e) => { |
| 46461 | | - if is_value && wants_bind_c_char { |
| 46462 | | - lower_bind_c_char_value_arg( |
| 46463 | | - b, |
| 46464 | | - locals, |
| 46465 | | - e, |
| 46466 | | - st, |
| 46467 | | - type_layouts, |
| 46468 | | - internal_funcs, |
| 46469 | | - contained_host_refs, |
| 46470 | | - descriptor_params, |
| 46471 | | - ) |
| 46472 | | - } else if is_value { |
| 46473 | | - let raw = lower_expr_full( |
| 46474 | | - b, |
| 46475 | | - locals, |
| 46476 | | - e, |
| 46477 | | - st, |
| 46478 | | - type_layouts, |
| 46479 | | - internal_funcs, |
| 46480 | | - contained_host_refs, |
| 46481 | | - descriptor_params, |
| 46482 | | - ); |
| 46483 | | - coerce_value_call_arg( |
| 46484 | | - b, |
| 46485 | | - st, |
| 46486 | | - abi_primary_key, |
| 46487 | | - i, |
| 46488 | | - raw, |
| 46489 | | - ) |
| 46490 | | - } else if wants_descriptor { |
| 46491 | | - lower_arg_descriptor( |
| 46492 | | - b, |
| 46493 | | - locals, |
| 46494 | | - e, |
| 46495 | | - st, |
| 46496 | | - type_layouts, |
| 46497 | | - false, |
| 46498 | | - ) |
| 46499 | | - } else if wants_string_descriptor { |
| 46500 | | - lower_arg_string_descriptor( |
| 46501 | | - b, |
| 46502 | | - locals, |
| 46503 | | - e, |
| 46504 | | - st, |
| 46505 | | - type_layouts, |
| 46506 | | - ) |
| 46507 | | - } else if wants_bind_c_char { |
| 46508 | | - lower_bind_c_char_arg_raw( |
| 46509 | | - b, |
| 46510 | | - locals, |
| 46511 | | - e, |
| 46512 | | - st, |
| 46513 | | - type_layouts, |
| 46514 | | - internal_funcs, |
| 46515 | | - contained_host_refs, |
| 46516 | | - descriptor_params, |
| 46517 | | - ) |
| 46518 | | - } else if wants_pointer { |
| 46519 | | - lower_pointer_dummy_actual( |
| 46520 | | - b, |
| 46521 | | - locals, |
| 46522 | | - e, |
| 46523 | | - st, |
| 46524 | | - type_layouts, |
| 46525 | | - internal_funcs, |
| 46526 | | - contained_host_refs, |
| 46527 | | - descriptor_params, |
| 46528 | | - ) |
| 46529 | | - .unwrap_or_else(|| { |
| 46530 | | - lower_arg_by_ref_full( |
| 46531 | | - b, |
| 46532 | | - locals, |
| 46533 | | - e, |
| 46534 | | - st, |
| 46535 | | - type_layouts, |
| 46536 | | - internal_funcs, |
| 46537 | | - contained_host_refs, |
| 46538 | | - descriptor_params, |
| 46539 | | - ) |
| 46540 | | - }) |
| 46541 | | - } else { |
| 46542 | | - lower_arg_by_ref_full( |
| 46543 | | - b, |
| 46544 | | - locals, |
| 46545 | | - e, |
| 46546 | | - st, |
| 46547 | | - type_layouts, |
| 46548 | | - internal_funcs, |
| 46549 | | - contained_host_refs, |
| 46550 | | - descriptor_params, |
| 46551 | | - ) |
| 46552 | | - } |
| 46553 | | - } |
| 46554 | | - _ => b.const_i32(0), |
| 46555 | | - }, |
| 46556 | | - None => missing_optional_call_arg( |
| 46421 | + .map(|mask| mask.first().copied().unwrap_or(false)) |
| 46422 | + .unwrap_or(false) |
| 46423 | + && !wants_bind_c_char; |
| 46424 | + call_args.push(if wants_descriptor { |
| 46425 | + lower_arg_descriptor( |
| 46557 | 46426 | b, |
| 46427 | + locals, |
| 46428 | + base, |
| 46558 | 46429 | st, |
| 46559 | | - abi_primary_key, |
| 46560 | | - i, |
| 46561 | | - is_value, |
| 46562 | | - ), |
| 46563 | | - }; |
| 46564 | | - call_args.push(value); |
| 46565 | | - } |
| 46566 | | - if let Some(opt_flags) = opt_flags { |
| 46567 | | - for flag in opt_flags.iter().skip(call_args.len()) { |
| 46568 | | - if *flag { |
| 46569 | | - call_args.push(b.const_i64(0)); |
| 46570 | | - } |
| 46571 | | - } |
| 46430 | + type_layouts, |
| 46431 | + false, |
| 46432 | + ) |
| 46433 | + } else { |
| 46434 | + obj_addr |
| 46435 | + }); |
| 46436 | + continue; |
| 46572 | 46437 | } |
| 46573 | | - if let Some(cls_flags) = &callee_char_len_star_args { |
| 46574 | | - for (i, flag) in cls_flags.iter().enumerate() { |
| 46575 | | - if !*flag || i >= arg_slots.len() { |
| 46576 | | - continue; |
| 46577 | | - } |
| 46578 | | - if let Some(arg) = &arg_slots[i] { |
| 46579 | | - if let crate::ast::expr::SectionSubscript::Element(e) = |
| 46580 | | - &arg.value |
| 46581 | | - { |
| 46582 | | - call_args.push( |
| 46583 | | - actual_char_arg_runtime_len( |
| 46438 | + let is_value = callee_value_args |
| 46439 | + .as_ref() |
| 46440 | + .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46441 | + .unwrap_or(false); |
| 46442 | + let wants_descriptor = callee_descriptor_args |
| 46443 | + .as_ref() |
| 46444 | + .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46445 | + .unwrap_or(false); |
| 46446 | + let wants_string_descriptor = callee_string_descriptor_args |
| 46447 | + .as_ref() |
| 46448 | + .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46449 | + .unwrap_or(false); |
| 46450 | + let wants_bind_c_char = callee_bind_c_char_args |
| 46451 | + .as_ref() |
| 46452 | + .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46453 | + .unwrap_or(false); |
| 46454 | + let wants_descriptor = wants_descriptor && !wants_bind_c_char; |
| 46455 | + let wants_string_descriptor = |
| 46456 | + wants_string_descriptor && !wants_bind_c_char; |
| 46457 | + let wants_pointer = callee_pointer_args |
| 46458 | + .as_ref() |
| 46459 | + .map(|mask| mask.get(i).copied().unwrap_or(false)) |
| 46460 | + .unwrap_or(false); |
| 46461 | + let value = match slot { |
| 46462 | + Some(arg) => match &arg.value { |
| 46463 | + crate::ast::expr::SectionSubscript::Element(e) => { |
| 46464 | + if is_value && wants_bind_c_char { |
| 46465 | + lower_bind_c_char_value_arg( |
| 46466 | + b, |
| 46467 | + locals, |
| 46468 | + e, |
| 46469 | + st, |
| 46470 | + type_layouts, |
| 46471 | + internal_funcs, |
| 46472 | + contained_host_refs, |
| 46473 | + descriptor_params, |
| 46474 | + ) |
| 46475 | + } else if is_value { |
| 46476 | + let raw = lower_expr_full( |
| 46477 | + b, |
| 46478 | + locals, |
| 46479 | + e, |
| 46480 | + st, |
| 46481 | + type_layouts, |
| 46482 | + internal_funcs, |
| 46483 | + contained_host_refs, |
| 46484 | + descriptor_params, |
| 46485 | + ); |
| 46486 | + coerce_value_call_arg( |
| 46487 | + b, |
| 46488 | + st, |
| 46489 | + abi_primary_key, |
| 46490 | + i, |
| 46491 | + raw, |
| 46492 | + ) |
| 46493 | + } else if wants_descriptor { |
| 46494 | + lower_arg_descriptor( |
| 46495 | + b, |
| 46496 | + locals, |
| 46497 | + e, |
| 46498 | + st, |
| 46499 | + type_layouts, |
| 46500 | + false, |
| 46501 | + ) |
| 46502 | + } else if wants_string_descriptor { |
| 46503 | + lower_arg_string_descriptor( |
| 46504 | + b, |
| 46505 | + locals, |
| 46506 | + e, |
| 46507 | + st, |
| 46508 | + type_layouts, |
| 46509 | + ) |
| 46510 | + } else if wants_bind_c_char { |
| 46511 | + lower_bind_c_char_arg_raw( |
| 46512 | + b, |
| 46513 | + locals, |
| 46514 | + e, |
| 46515 | + st, |
| 46516 | + type_layouts, |
| 46517 | + internal_funcs, |
| 46518 | + contained_host_refs, |
| 46519 | + descriptor_params, |
| 46520 | + ) |
| 46521 | + } else if wants_pointer { |
| 46522 | + lower_pointer_dummy_actual( |
| 46523 | + b, |
| 46524 | + locals, |
| 46525 | + e, |
| 46526 | + st, |
| 46527 | + type_layouts, |
| 46528 | + internal_funcs, |
| 46529 | + contained_host_refs, |
| 46530 | + descriptor_params, |
| 46531 | + ) |
| 46532 | + .unwrap_or_else(|| { |
| 46533 | + lower_arg_by_ref_full( |
| 46584 | 46534 | b, |
| 46585 | 46535 | locals, |
| 46586 | | - None, |
| 46587 | 46536 | e, |
| 46588 | 46537 | st, |
| 46589 | 46538 | type_layouts, |
@@ -46591,36 +46540,90 @@ fn lower_expr_full( |
| 46591 | 46540 | contained_host_refs, |
| 46592 | 46541 | descriptor_params, |
| 46593 | 46542 | ) |
| 46594 | | - .unwrap_or_else(|| b.const_i64(0)), |
| 46595 | | - ); |
| 46543 | + }) |
| 46596 | 46544 | } else { |
| 46597 | | - call_args.push(b.const_i64(0)); |
| 46545 | + lower_arg_by_ref_full( |
| 46546 | + b, |
| 46547 | + locals, |
| 46548 | + e, |
| 46549 | + st, |
| 46550 | + type_layouts, |
| 46551 | + internal_funcs, |
| 46552 | + contained_host_refs, |
| 46553 | + descriptor_params, |
| 46554 | + ) |
| 46598 | 46555 | } |
| 46556 | + } |
| 46557 | + _ => b.const_i32(0), |
| 46558 | + }, |
| 46559 | + None => missing_optional_call_arg( |
| 46560 | + b, |
| 46561 | + st, |
| 46562 | + abi_primary_key, |
| 46563 | + i, |
| 46564 | + is_value, |
| 46565 | + ), |
| 46566 | + }; |
| 46567 | + call_args.push(value); |
| 46568 | + } |
| 46569 | + if let Some(opt_flags) = opt_flags { |
| 46570 | + for flag in opt_flags.iter().skip(call_args.len()) { |
| 46571 | + if *flag { |
| 46572 | + call_args.push(b.const_i64(0)); |
| 46573 | + } |
| 46574 | + } |
| 46575 | + } |
| 46576 | + if let Some(cls_flags) = &callee_char_len_star_args { |
| 46577 | + for (i, flag) in cls_flags.iter().enumerate() { |
| 46578 | + if !*flag || i >= arg_slots.len() { |
| 46579 | + continue; |
| 46580 | + } |
| 46581 | + if let Some(arg) = &arg_slots[i] { |
| 46582 | + if let crate::ast::expr::SectionSubscript::Element(e) = |
| 46583 | + &arg.value |
| 46584 | + { |
| 46585 | + call_args.push( |
| 46586 | + actual_char_arg_runtime_len( |
| 46587 | + b, |
| 46588 | + locals, |
| 46589 | + None, |
| 46590 | + e, |
| 46591 | + st, |
| 46592 | + type_layouts, |
| 46593 | + internal_funcs, |
| 46594 | + contained_host_refs, |
| 46595 | + descriptor_params, |
| 46596 | + ) |
| 46597 | + .unwrap_or_else(|| b.const_i64(0)), |
| 46598 | + ); |
| 46599 | 46599 | } else { |
| 46600 | 46600 | call_args.push(b.const_i64(0)); |
| 46601 | 46601 | } |
| 46602 | + } else { |
| 46603 | + call_args.push(b.const_i64(0)); |
| 46602 | 46604 | } |
| 46603 | 46605 | } |
| 46606 | + } |
| 46604 | 46607 | |
| 46605 | | - let ret_ty = first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46606 | | - callee_return_ir_type(st, k) |
| 46607 | | - }) |
| 46608 | | - .unwrap_or(IrType::Int(IntWidth::I32)); |
| 46609 | | - let call_result = |
| 46610 | | - b.call(FuncRef::External(call_name), call_args, ret_ty); |
| 46611 | | - if let Some(tl) = type_layouts { |
| 46612 | | - if let Some(type_name) = |
| 46613 | | - callee_return_stabilized_derived_type_name(st, &target_key) |
| 46614 | | - { |
| 46615 | | - return stabilize_derived_call_result( |
| 46616 | | - b, |
| 46617 | | - tl, |
| 46618 | | - &type_name, |
| 46619 | | - call_result, |
| 46620 | | - ); |
| 46621 | | - } |
| 46608 | + let ret_ty = first_procedure_lookup(&abi_lookup_keys, |k| { |
| 46609 | + callee_return_ir_type(st, k) |
| 46610 | + }) |
| 46611 | + .unwrap_or(IrType::Int(IntWidth::I32)); |
| 46612 | + let call_result = |
| 46613 | + b.call(FuncRef::External(call_name), call_args, ret_ty); |
| 46614 | + if let Some(tl) = type_layouts { |
| 46615 | + if let Some(type_name) = |
| 46616 | + callee_return_stabilized_derived_type_name(st, &target_key) |
| 46617 | + { |
| 46618 | + return stabilize_derived_call_result( |
| 46619 | + b, |
| 46620 | + tl, |
| 46621 | + &type_name, |
| 46622 | + call_result, |
| 46623 | + ); |
| 46622 | 46624 | } |
| 46623 | | - return call_result; |
| 46625 | + } |
| 46626 | + return call_result; |
| 46624 | 46627 | } |
| 46625 | 46628 | } |
| 46626 | 46629 | reject_unsupported_polymorphic_component_method_base( |
@@ -46664,11 +46667,7 @@ fn lower_expr_full( |
| 46664 | 46667 | contained_host_refs, |
| 46665 | 46668 | descriptor_params, |
| 46666 | 46669 | ); |
| 46667 | | - let off = if lc_component == "re" { |
| 46668 | | - 0 |
| 46669 | | - } else { |
| 46670 | | - kind_bytes |
| 46671 | | - }; |
| 46670 | + let off = if lc_component == "re" { 0 } else { kind_bytes }; |
| 46672 | 46671 | let off_v = b.const_i64(off); |
| 46673 | 46672 | let lane_ptr = b.gep(base_addr, vec![off_v], IrType::Int(IntWidth::I8)); |
| 46674 | 46673 | return b.load_typed(lane_ptr, elem_ty); |
@@ -46926,7 +46925,12 @@ fn lower_expr_full( |
| 46926 | 46925 | return true; |
| 46927 | 46926 | } |
| 46928 | 46927 | if let Some(kind_str) = kind { |
| 46929 | | - return real_kind_to_width_in_context(kind_str, Some(locals), None, Some(st)) == 8; |
| 46928 | + return real_kind_to_width_in_context( |
| 46929 | + kind_str, |
| 46930 | + Some(locals), |
| 46931 | + None, |
| 46932 | + Some(st), |
| 46933 | + ) == 8; |
| 46930 | 46934 | } |
| 46931 | 46935 | } |
| 46932 | 46936 | false |
@@ -47068,12 +47072,8 @@ fn try_lower_transfer_into_array( |
| 47068 | 47072 | }; |
| 47069 | 47073 | |
| 47070 | 47074 | // Mold scalar byte size from the mold's semantic type. |
| 47071 | | - let mold_ti = operator_expr_type_info( |
| 47072 | | - mold_expr, |
| 47073 | | - Some(&ctx.locals), |
| 47074 | | - ctx.st, |
| 47075 | | - Some(ctx.type_layouts), |
| 47076 | | - ); |
| 47075 | + let mold_ti = |
| 47076 | + operator_expr_type_info(mold_expr, Some(&ctx.locals), ctx.st, Some(ctx.type_layouts)); |
| 47077 | 47077 | let scalar_size: i64 = match mold_ti { |
| 47078 | 47078 | Some(crate::sema::symtab::TypeInfo::Integer { kind }) => kind.unwrap_or(4) as i64, |
| 47079 | 47079 | Some(crate::sema::symtab::TypeInfo::Real { kind }) => kind.unwrap_or(4) as i64, |
@@ -47091,9 +47091,7 @@ fn try_lower_transfer_into_array( |
| 47091 | 47091 | // MOLD_elem_size)` (F2018 §16.9.193) — derive that from the source |
| 47092 | 47092 | // array descriptor at runtime, which only works for descriptor- |
| 47093 | 47093 | // backed destinations (fixed-shape molds need a static extent). |
| 47094 | | - let const_size: Option<i64> = size_expr_opt |
| 47095 | | - .and_then(eval_const_int) |
| 47096 | | - .filter(|s| *s >= 1); |
| 47094 | + let const_size: Option<i64> = size_expr_opt.and_then(eval_const_int).filter(|s| *s >= 1); |
| 47097 | 47095 | let descriptor_dest = local_uses_array_descriptor(dest_info); |
| 47098 | 47096 | let (size_v, total_v): (ValueId, ValueId) = if let Some(size) = const_size { |
| 47099 | 47097 | let total_bytes = size * scalar_size; |
@@ -47141,20 +47139,13 @@ fn try_lower_transfer_into_array( |
| 47141 | 47139 | let crate::ast::expr::AcValue::Expr(expr) = v else { |
| 47142 | 47140 | return None; |
| 47143 | 47141 | }; |
| 47144 | | - operator_expr_type_info( |
| 47145 | | - expr, |
| 47146 | | - Some(&ctx.locals), |
| 47147 | | - ctx.st, |
| 47148 | | - Some(ctx.type_layouts), |
| 47149 | | - ) |
| 47142 | + operator_expr_type_info(expr, Some(&ctx.locals), ctx.st, Some(ctx.type_layouts)) |
| 47150 | 47143 | }); |
| 47151 | 47144 | let src_elem_size: i64 = match elem_ti { |
| 47152 | 47145 | Some(crate::sema::symtab::TypeInfo::Integer { kind }) => { |
| 47153 | 47146 | kind.unwrap_or(4) as i64 |
| 47154 | 47147 | } |
| 47155 | | - Some(crate::sema::symtab::TypeInfo::Real { kind }) => { |
| 47156 | | - kind.unwrap_or(4) as i64 |
| 47157 | | - } |
| 47148 | + Some(crate::sema::symtab::TypeInfo::Real { kind }) => kind.unwrap_or(4) as i64, |
| 47158 | 47149 | Some(crate::sema::symtab::TypeInfo::Logical { kind }) => { |
| 47159 | 47150 | kind.unwrap_or(4) as i64 |
| 47160 | 47151 | } |
@@ -47360,15 +47351,9 @@ fn lower_transfer_intrinsic( |
| 47360 | 47351 | // mishandle. |
| 47361 | 47352 | let mold_ti = operator_expr_type_info(mold_expr, Some(locals), st, type_layouts)?; |
| 47362 | 47353 | let mold_ty = match &mold_ti { |
| 47363 | | - crate::sema::symtab::TypeInfo::Integer { kind } => { |
| 47364 | | - IrType::int_from_kind(kind.unwrap_or(4)) |
| 47365 | | - } |
| 47366 | | - crate::sema::symtab::TypeInfo::Real { kind } => { |
| 47367 | | - IrType::float_from_kind(kind.unwrap_or(4)) |
| 47368 | | - } |
| 47369 | | - crate::sema::symtab::TypeInfo::Logical { kind } => { |
| 47370 | | - IrType::int_from_kind(kind.unwrap_or(4)) |
| 47371 | | - } |
| 47354 | + crate::sema::symtab::TypeInfo::Integer { kind } => IrType::int_from_kind(kind.unwrap_or(4)), |
| 47355 | + crate::sema::symtab::TypeInfo::Real { kind } => IrType::float_from_kind(kind.unwrap_or(4)), |
| 47356 | + crate::sema::symtab::TypeInfo::Logical { kind } => IrType::int_from_kind(kind.unwrap_or(4)), |
| 47372 | 47357 | _ => return None, |
| 47373 | 47358 | }; |
| 47374 | 47359 | |
@@ -47405,10 +47390,19 @@ fn lower_transfer_intrinsic( |
| 47405 | 47390 | return None; |
| 47406 | 47391 | }; |
| 47407 | 47392 | let elem_val = lower_expr_full( |
| 47408 | | - b, locals, e, st, type_layouts, |
| 47409 | | - internal_funcs, contained_host_refs, descriptor_params, |
| 47393 | + b, |
| 47394 | + locals, |
| 47395 | + e, |
| 47396 | + st, |
| 47397 | + type_layouts, |
| 47398 | + internal_funcs, |
| 47399 | + contained_host_refs, |
| 47400 | + descriptor_params, |
| 47410 | 47401 | ); |
| 47411 | | - let elem_ty = b.func().value_type(elem_val).unwrap_or(IrType::Int(IntWidth::I32)); |
| 47402 | + let elem_ty = b |
| 47403 | + .func() |
| 47404 | + .value_type(elem_val) |
| 47405 | + .unwrap_or(IrType::Int(IntWidth::I32)); |
| 47412 | 47406 | let elem_size = ir_scalar_byte_size(&elem_ty); |
| 47413 | 47407 | let off_val = b.const_i64(byte_off); |
| 47414 | 47408 | let dst = b.gep(buf, vec![off_val], IrType::Int(IntWidth::I8)); |
@@ -47420,10 +47414,19 @@ fn lower_transfer_intrinsic( |
| 47420 | 47414 | |
| 47421 | 47415 | // Scalar source: lower it, store to temp, reload as mold type. |
| 47422 | 47416 | let src_val = lower_expr_full( |
| 47423 | | - b, locals, source_expr, st, type_layouts, |
| 47424 | | - internal_funcs, contained_host_refs, descriptor_params, |
| 47417 | + b, |
| 47418 | + locals, |
| 47419 | + source_expr, |
| 47420 | + st, |
| 47421 | + type_layouts, |
| 47422 | + internal_funcs, |
| 47423 | + contained_host_refs, |
| 47424 | + descriptor_params, |
| 47425 | 47425 | ); |
| 47426 | | - let src_ty = b.func().value_type(src_val).unwrap_or(IrType::Int(IntWidth::I32)); |
| 47426 | + let src_ty = b |
| 47427 | + .func() |
| 47428 | + .value_type(src_val) |
| 47429 | + .unwrap_or(IrType::Int(IntWidth::I32)); |
| 47427 | 47430 | if matches!(src_ty, IrType::Int(_) | IrType::Float(_) | IrType::Bool) { |
| 47428 | 47431 | let zero_off = b.const_i64(0); |
| 47429 | 47432 | let dst = b.gep(buf, vec![zero_off], IrType::Int(IntWidth::I8)); |