aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/rust
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/rust')
-rw-r--r--gcc/testsuite/rust/borrowck/reference.rs1
-rw-r--r--gcc/testsuite/rust/borrowck/tmp.rs1
-rw-r--r--gcc/testsuite/rust/compile/additional-trait-bounds1.rs10
-rw-r--r--gcc/testsuite/rust/compile/additional-trait-bounds2.rs9
-rw-r--r--gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs9
-rw-r--r--gcc/testsuite/rust/compile/all-cast.rs2
-rw-r--r--gcc/testsuite/rust/compile/arrays2.rs3
-rw-r--r--gcc/testsuite/rust/compile/attr-macro.rs7
-rw-r--r--gcc/testsuite/rust/compile/attr_malformed_doc.rs3
-rw-r--r--gcc/testsuite/rust/compile/attr_malformed_path.rs3
-rw-r--r--gcc/testsuite/rust/compile/auto_traits1.rs27
-rw-r--r--gcc/testsuite/rust/compile/auto_traits2.rs25
-rw-r--r--gcc/testsuite/rust/compile/auto_traits4.rs14
-rw-r--r--gcc/testsuite/rust/compile/bad-rpit1.rs27
-rw-r--r--gcc/testsuite/rust/compile/black_box.rs28
-rw-r--r--gcc/testsuite/rust/compile/bounds1.rs1
-rw-r--r--gcc/testsuite/rust/compile/box_syntax_feature_gate.rs1
-rw-r--r--gcc/testsuite/rust/compile/braced_macro_arm.rs3
-rw-r--r--gcc/testsuite/rust/compile/bug-with-default-generic.rs16
-rw-r--r--gcc/testsuite/rust/compile/canonical_paths1.rs1
-rw-r--r--gcc/testsuite/rust/compile/cast_float_as_integer.rs10
-rw-r--r--gcc/testsuite/rust/compile/cast_generics.rs1
-rw-r--r--gcc/testsuite/rust/compile/cfg-core1.rs12
-rw-r--r--gcc/testsuite/rust/compile/cfg-core2.rs12
-rw-r--r--gcc/testsuite/rust/compile/cfg-test.rs4
-rw-r--r--gcc/testsuite/rust/compile/closure_no_type_anno.rs1
-rw-r--r--gcc/testsuite/rust/compile/cmp1.rs79
-rw-r--r--gcc/testsuite/rust/compile/complex_qualified_path_in_expr.rs1
-rw-r--r--gcc/testsuite/rust/compile/const-issue1440.rs1
-rw-r--r--gcc/testsuite/rust/compile/const3.rs2
-rw-r--r--gcc/testsuite/rust/compile/const_generics_1.rs1
-rw-r--r--gcc/testsuite/rust/compile/const_generics_10.rs33
-rw-r--r--gcc/testsuite/rust/compile/const_generics_11.rs14
-rw-r--r--gcc/testsuite/rust/compile/const_generics_12.rs14
-rw-r--r--gcc/testsuite/rust/compile/const_generics_13.rs12
-rw-r--r--gcc/testsuite/rust/compile/const_generics_14.rs14
-rw-r--r--gcc/testsuite/rust/compile/const_generics_15.rs17
-rw-r--r--gcc/testsuite/rust/compile/const_generics_16.rs11
-rw-r--r--gcc/testsuite/rust/compile/const_generics_17.rs3
-rw-r--r--gcc/testsuite/rust/compile/const_generics_18.rs11
-rw-r--r--gcc/testsuite/rust/compile/const_generics_19.rs11
-rw-r--r--gcc/testsuite/rust/compile/const_generics_3.rs28
-rw-r--r--gcc/testsuite/rust/compile/const_generics_4.rs2
-rw-r--r--gcc/testsuite/rust/compile/const_generics_5.rs4
-rw-r--r--gcc/testsuite/rust/compile/const_generics_7.rs14
-rw-r--r--gcc/testsuite/rust/compile/const_generics_8.rs8
-rw-r--r--gcc/testsuite/rust/compile/const_generics_9.rs13
-rw-r--r--gcc/testsuite/rust/compile/crate-metavar1.rs14
-rw-r--r--gcc/testsuite/rust/compile/decl_macro6.rs1
-rw-r--r--gcc/testsuite/rust/compile/decl_macro7.rs1
-rw-r--r--gcc/testsuite/rust/compile/deferred_const_inference.rs7
-rw-r--r--gcc/testsuite/rust/compile/derive-debug1.rs42
-rw-r--r--gcc/testsuite/rust/compile/derive-default1.rs31
-rw-r--r--gcc/testsuite/rust/compile/derive-eq-invalid.rs54
-rw-r--r--gcc/testsuite/rust/compile/derive-hash1.rs91
-rw-r--r--gcc/testsuite/rust/compile/derive-partialeq1.rs62
-rw-r--r--gcc/testsuite/rust/compile/derive_clone_enum1.rs18
-rw-r--r--gcc/testsuite/rust/compile/derive_clone_enum2.rs18
-rw-r--r--gcc/testsuite/rust/compile/derive_clone_enum3.rs18
-rw-r--r--gcc/testsuite/rust/compile/derive_macro1.rs4
-rw-r--r--gcc/testsuite/rust/compile/derive_macro3.rs2
-rw-r--r--gcc/testsuite/rust/compile/derive_macro4.rs9
-rw-r--r--gcc/testsuite/rust/compile/derive_macro6.rs8
-rw-r--r--gcc/testsuite/rust/compile/derive_partial_ord1.rs464
-rw-r--r--gcc/testsuite/rust/compile/e0579-neg-float-fail.rs9
-rw-r--r--gcc/testsuite/rust/compile/e0579-neg-float.rs9
-rw-r--r--gcc/testsuite/rust/compile/enum_discriminant1.rs7
-rw-r--r--gcc/testsuite/rust/compile/enum_discriminant2.rs9
-rw-r--r--gcc/testsuite/rust/compile/enum_discriminant3.rs8
-rw-r--r--gcc/testsuite/rust/compile/enum_variant_name.rs12
-rw-r--r--gcc/testsuite/rust/compile/exhaustiveness1.rs4
-rw-r--r--gcc/testsuite/rust/compile/expand_macro_qual_path_in_type.rs1
-rw-r--r--gcc/testsuite/rust/compile/expected_type_args2.rs1
-rw-r--r--gcc/testsuite/rust/compile/expected_type_args3.rs1
-rw-r--r--gcc/testsuite/rust/compile/extern_generics.rs9
-rw-r--r--gcc/testsuite/rust/compile/extern_type_item_missing_semi.rs1
-rw-r--r--gcc/testsuite/rust/compile/feature.rs2
-rw-r--r--gcc/testsuite/rust/compile/feature_rust_attri0.rs6
-rw-r--r--gcc/testsuite/rust/compile/for-loop1.rs543
-rw-r--r--gcc/testsuite/rust/compile/for-loop2.rs547
-rw-r--r--gcc/testsuite/rust/compile/format_args_basic_expansion.rs3
-rw-r--r--gcc/testsuite/rust/compile/format_args_concat.rs51
-rw-r--r--gcc/testsuite/rust/compile/format_args_extra_comma.rs46
-rw-r--r--gcc/testsuite/rust/compile/gat1.rs4
-rw-r--r--gcc/testsuite/rust/compile/generic-default1.rs2
-rw-r--r--gcc/testsuite/rust/compile/generics1.rs1
-rw-r--r--gcc/testsuite/rust/compile/generics11.rs1
-rw-r--r--gcc/testsuite/rust/compile/generics12.rs1
-rw-r--r--gcc/testsuite/rust/compile/generics14.rs1
-rw-r--r--gcc/testsuite/rust/compile/generics2.rs1
-rw-r--r--gcc/testsuite/rust/compile/generics3.rs1
-rw-r--r--gcc/testsuite/rust/compile/generics4.rs2
-rw-r--r--gcc/testsuite/rust/compile/generics5.rs2
-rw-r--r--gcc/testsuite/rust/compile/generics6.rs2
-rw-r--r--gcc/testsuite/rust/compile/generics7.rs1
-rw-r--r--gcc/testsuite/rust/compile/generics8.rs3
-rw-r--r--gcc/testsuite/rust/compile/generics9.rs2
-rw-r--r--gcc/testsuite/rust/compile/glob_import_enum.rs16
-rw-r--r--gcc/testsuite/rust/compile/global-path-array.rs5
-rw-r--r--gcc/testsuite/rust/compile/if-without-else.rs9
-rw-r--r--gcc/testsuite/rust/compile/if_let_expr.rs6
-rw-r--r--gcc/testsuite/rust/compile/if_let_expr_simple.rs12
-rw-r--r--gcc/testsuite/rust/compile/iflet.rs32
-rw-r--r--gcc/testsuite/rust/compile/impl_fnptr.rs19
-rw-r--r--gcc/testsuite/rust/compile/impl_trait_diag.rs18
-rw-r--r--gcc/testsuite/rust/compile/impl_trait_generic_arg.rs26
-rw-r--r--gcc/testsuite/rust/compile/implicit_returns_err3.rs2
-rw-r--r--gcc/testsuite/rust/compile/import_wildcards.rs8
-rw-r--r--gcc/testsuite/rust/compile/invalid_label_name.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-1005.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1019.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1031.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1034.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1048.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-1128.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1129-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1130.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1131.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1165.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1173.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1235.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1237.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1289.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1383.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1446.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-1447.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1483.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1485.rs17
-rw-r--r--gcc/testsuite/rust/compile/issue-1487.rs17
-rw-r--r--gcc/testsuite/rust/compile/issue-1525.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-1589.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1725-1.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1725-2.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-1773.rs23
-rw-r--r--gcc/testsuite/rust/compile/issue-1786.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1893.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1901.rs5
-rw-r--r--gcc/testsuite/rust/compile/issue-1930.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1981.rs41
-rw-r--r--gcc/testsuite/rust/compile/issue-2015.rs22
-rw-r--r--gcc/testsuite/rust/compile/issue-2019-1.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2019-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2019-3.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2035.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-2036.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2037.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2043.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2070.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2105.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2106.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2135.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2136-1.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2136-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2139.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2142.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2165.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2166.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-2187.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2190-1.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2190-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2195.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2238.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-2304.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2323.rs11
-rw-r--r--gcc/testsuite/rust/compile/issue-2330.rs40
-rw-r--r--gcc/testsuite/rust/compile/issue-2369.rs23
-rw-r--r--gcc/testsuite/rust/compile/issue-2375.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2394.rs15
-rw-r--r--gcc/testsuite/rust/compile/issue-2423.rs14
-rw-r--r--gcc/testsuite/rust/compile/issue-2478.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2499.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2567-1.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-2567-2.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-2567-3.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-266.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-2680.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-2723-1.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2723-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2725.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2747.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2772-1.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2772-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2775.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2782.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2812.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-2847.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-2905-1.rs27
-rw-r--r--gcc/testsuite/rust/compile/issue-2905-2.rs136
-rw-r--r--gcc/testsuite/rust/compile/issue-2907.rs33
-rw-r--r--gcc/testsuite/rust/compile/issue-2951.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2953-1.rs29
-rw-r--r--gcc/testsuite/rust/compile/issue-2953-2.rs39
-rw-r--r--gcc/testsuite/rust/compile/issue-2954.rs19
-rw-r--r--gcc/testsuite/rust/compile/issue-2987.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-3009.rs26
-rw-r--r--gcc/testsuite/rust/compile/issue-3022.rs20
-rw-r--r--gcc/testsuite/rust/compile/issue-3030.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-3031.rs15
-rw-r--r--gcc/testsuite/rust/compile/issue-3032-1.rs58
-rw-r--r--gcc/testsuite/rust/compile/issue-3032-2.rs49
-rw-r--r--gcc/testsuite/rust/compile/issue-3033.rs144
-rw-r--r--gcc/testsuite/rust/compile/issue-3035.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3036.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3045-1.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3045-2.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3046.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3140.rs27
-rw-r--r--gcc/testsuite/rust/compile/issue-3144.rs30
-rw-r--r--gcc/testsuite/rust/compile/issue-3174.rs28
-rw-r--r--gcc/testsuite/rust/compile/issue-3231.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3242.rs24
-rw-r--r--gcc/testsuite/rust/compile/issue-3261.rs18
-rw-r--r--gcc/testsuite/rust/compile/issue-3304.rs11
-rw-r--r--gcc/testsuite/rust/compile/issue-3315-1.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3315-2.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3350.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3382.rs63
-rw-r--r--gcc/testsuite/rust/compile/issue-3402-1.rs31
-rw-r--r--gcc/testsuite/rust/compile/issue-3402-2.rs20
-rw-r--r--gcc/testsuite/rust/compile/issue-3403.rs40
-rw-r--r--gcc/testsuite/rust/compile/issue-3454.rs21
-rw-r--r--gcc/testsuite/rust/compile/issue-3524.rs9
-rw-r--r--gcc/testsuite/rust/compile/issue-3525.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-3530-1.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3530-2.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3538.rs9
-rw-r--r--gcc/testsuite/rust/compile/issue-3541-1.rs5
-rw-r--r--gcc/testsuite/rust/compile/issue-3541-2.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3546.rs16
-rw-r--r--gcc/testsuite/rust/compile/issue-3549.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3551.rs16
-rw-r--r--gcc/testsuite/rust/compile/issue-3552.rs14
-rw-r--r--gcc/testsuite/rust/compile/issue-3553.rs18
-rw-r--r--gcc/testsuite/rust/compile/issue-3554-1.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3554-2.rs19
-rw-r--r--gcc/testsuite/rust/compile/issue-3556.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3563.rs17
-rw-r--r--gcc/testsuite/rust/compile/issue-3566-1.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3566-2.rs22
-rw-r--r--gcc/testsuite/rust/compile/issue-3567.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3568.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3581-1.rs12
-rw-r--r--gcc/testsuite/rust/compile/issue-3581-2.rs9
-rw-r--r--gcc/testsuite/rust/compile/issue-3588.rs5
-rw-r--r--gcc/testsuite/rust/compile/issue-3592.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3599.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3605.rs5
-rw-r--r--gcc/testsuite/rust/compile/issue-3606.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-3612.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3613.rs18
-rw-r--r--gcc/testsuite/rust/compile/issue-3614.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3615.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3617.rs14
-rw-r--r--gcc/testsuite/rust/compile/issue-3618.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3625.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3628.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3642.rs11
-rw-r--r--gcc/testsuite/rust/compile/issue-3643.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3645.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-3646.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3647.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3648.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3649.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3652.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3654.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3656.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3657.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3659.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3660.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3661.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3662.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3663.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-3664.rs5
-rw-r--r--gcc/testsuite/rust/compile/issue-3665.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-3667.rs24
-rw-r--r--gcc/testsuite/rust/compile/issue-3671.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3711.rs18
-rw-r--r--gcc/testsuite/rust/compile/issue-3726.rs17
-rw-r--r--gcc/testsuite/rust/compile/issue-3836.rs69
-rw-r--r--gcc/testsuite/rust/compile/issue-3874.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3876.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3885.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3898.rs113
-rw-r--r--gcc/testsuite/rust/compile/issue-3915.rs30
-rw-r--r--gcc/testsuite/rust/compile/issue-3916.rs36
-rw-r--r--gcc/testsuite/rust/compile/issue-3922.rs12
-rw-r--r--gcc/testsuite/rust/compile/issue-3924.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-3928.rs12
-rw-r--r--gcc/testsuite/rust/compile/issue-3929-1.rs9
-rw-r--r--gcc/testsuite/rust/compile/issue-3929-2.rs12
-rw-r--r--gcc/testsuite/rust/compile/issue-3930.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3947.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3958.rs11
-rw-r--r--gcc/testsuite/rust/compile/issue-3960.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3965-1.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3965-2.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3966.rs5
-rw-r--r--gcc/testsuite/rust/compile/issue-3969.rs32
-rw-r--r--gcc/testsuite/rust/compile/issue-3971.rs11
-rw-r--r--gcc/testsuite/rust/compile/issue-3974.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3978.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-4006.rs13
-rw-r--r--gcc/testsuite/rust/compile/issue-402.rs15
-rw-r--r--gcc/testsuite/rust/compile/issue-407-2.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-407.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-4090-1.rs70
-rw-r--r--gcc/testsuite/rust/compile/issue-4090-2.rs73
-rw-r--r--gcc/testsuite/rust/compile/issue-4139.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-4140-1.rs18
-rw-r--r--gcc/testsuite/rust/compile/issue-4140-2.rs12
-rw-r--r--gcc/testsuite/rust/compile/issue-4145.rs13
-rw-r--r--gcc/testsuite/rust/compile/issue-4146.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-4148.rs26
-rw-r--r--gcc/testsuite/rust/compile/issue-4155.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-4162.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-4165.rs12
-rw-r--r--gcc/testsuite/rust/compile/issue-4168.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-4188.rs13
-rw-r--r--gcc/testsuite/rust/compile/issue-4212.rs5
-rw-r--r--gcc/testsuite/rust/compile/issue-4219.rs5
-rw-r--r--gcc/testsuite/rust/compile/issue-4222.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-4226.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-4231.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-4242.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-4261.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-4262.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-4267.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-850.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-855.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-867.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-925.rs1
-rw-r--r--gcc/testsuite/rust/compile/iterators1.rs78
-rw-r--r--gcc/testsuite/rust/compile/lang_feature_gate.rs2
-rw-r--r--gcc/testsuite/rust/compile/loop_constant_context.rs5
-rw-r--r--gcc/testsuite/rust/compile/macros/builtin/eager1.rs2
-rw-r--r--gcc/testsuite/rust/compile/macros/builtin/option_env1.rs29
-rw-r--r--gcc/testsuite/rust/compile/macros/builtin/option_env2.rs27
-rw-r--r--gcc/testsuite/rust/compile/macros/builtin/option_env3.rs28
-rw-r--r--gcc/testsuite/rust/compile/macros/builtin/recurse2.rs26
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs11
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue1053-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue1395-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue1400.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs5
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3608.rs10
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs10
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs81
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs10
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs82
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue4054.rs14
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro20.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro23.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro27.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro28.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro29.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro30.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro31.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro33.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro35.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro37.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro38.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro39.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro40.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro43.rs17
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro44.rs2
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro48.rs5
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro49.rs12
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro54.rs1
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro58.rs12
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro6.rs2
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/meta-param.rs7
-rw-r--r--gcc/testsuite/rust/compile/match-identifierpattern-enum.rs12
-rw-r--r--gcc/testsuite/rust/compile/match-identifierpattern.rs9
-rw-r--r--gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs8
-rw-r--r--gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs8
-rw-r--r--gcc/testsuite/rust/compile/match-slicepattern-array.rs8
-rw-r--r--gcc/testsuite/rust/compile/match-slicepattern-slice.rs10
-rw-r--r--gcc/testsuite/rust/compile/match-tuplestructpattern-err.rs14
-rw-r--r--gcc/testsuite/rust/compile/match-tuplestructpattern-non-variant.rs20
-rw-r--r--gcc/testsuite/rust/compile/match-tuplestructpattern-rest.rs9
-rw-r--r--gcc/testsuite/rust/compile/match-tuplestructpattern.rs9
-rw-r--r--gcc/testsuite/rust/compile/method2.rs2
-rw-r--r--gcc/testsuite/rust/compile/min_specialization1.rs15
-rw-r--r--gcc/testsuite/rust/compile/multiline-string.rs14
-rw-r--r--gcc/testsuite/rust/compile/multiple_bindings1.rs30
-rw-r--r--gcc/testsuite/rust/compile/mutability_checks1.rs15
-rw-r--r--gcc/testsuite/rust/compile/name_resolution10.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution11.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution12.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution13.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution14.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution15.rs1
-rw-r--r--gcc/testsuite/rust/compile/name_resolution16.rs1
-rw-r--r--gcc/testsuite/rust/compile/name_resolution17.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution18.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution2.rs3
-rw-r--r--gcc/testsuite/rust/compile/name_resolution20.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution22.rs1
-rw-r--r--gcc/testsuite/rust/compile/name_resolution23.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution24.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution25.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution4.rs3
-rw-r--r--gcc/testsuite/rust/compile/name_resolution6.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution7.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution8.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution9.rs6
-rw-r--r--gcc/testsuite/rust/compile/nested_generic.rs1
-rw-r--r--gcc/testsuite/rust/compile/nested_macro_definition.rs2
-rw-r--r--gcc/testsuite/rust/compile/nested_macro_use2.rs2
-rw-r--r--gcc/testsuite/rust/compile/nonexistent-field.rs2
-rw-r--r--gcc/testsuite/rust/compile/nr2/compile.exp136
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude237
-rw-r--r--gcc/testsuite/rust/compile/offset_of1.rs11
-rw-r--r--gcc/testsuite/rust/compile/offset_of2.rs9
-rw-r--r--gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs1
-rw-r--r--gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs1
-rw-r--r--gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs1
-rw-r--r--gcc/testsuite/rust/compile/parse_closure_bind.rs20
-rw-r--r--gcc/testsuite/rust/compile/parse_complex_generic_application.rs1
-rw-r--r--gcc/testsuite/rust/compile/parse_complex_generic_application2.rs1
-rw-r--r--gcc/testsuite/rust/compile/parse_float_dot.rs3
-rw-r--r--gcc/testsuite/rust/compile/parse_invalid_specialization.rs1
-rw-r--r--gcc/testsuite/rust/compile/parse_simple_path_fail_1.rs2
-rw-r--r--gcc/testsuite/rust/compile/parse_simple_path_fail_2.rs7
-rw-r--r--gcc/testsuite/rust/compile/path_as_generic_arg.rs1
-rw-r--r--gcc/testsuite/rust/compile/primitive-import.rs7
-rw-r--r--gcc/testsuite/rust/compile/privacy4.rs1
-rw-r--r--gcc/testsuite/rust/compile/privacy6.rs1
-rw-r--r--gcc/testsuite/rust/compile/ptr_int_cast.rs18
-rw-r--r--gcc/testsuite/rust/compile/pub_restricted_1.rs6
-rw-r--r--gcc/testsuite/rust/compile/pub_restricted_2.rs8
-rw-r--r--gcc/testsuite/rust/compile/raw-byte-string-loc.rs1
-rw-r--r--gcc/testsuite/rust/compile/raw-string-loc.rs1
-rw-r--r--gcc/testsuite/rust/compile/raw_ref_op_invalid.rs2
-rw-r--r--gcc/testsuite/rust/compile/redef_error2.rs2
-rw-r--r--gcc/testsuite/rust/compile/redef_error5.rs2
-rw-r--r--gcc/testsuite/rust/compile/reference1.rs2
-rw-r--r--gcc/testsuite/rust/compile/same_field_name.rs (renamed from gcc/testsuite/rust/execute/same_field_name.rs)2
-rw-r--r--gcc/testsuite/rust/compile/self-in-impl.rs15
-rw-r--r--gcc/testsuite/rust/compile/self-path2.rs4
-rw-r--r--gcc/testsuite/rust/compile/self_const_ptr.rs1
-rw-r--r--gcc/testsuite/rust/compile/self_import_namespace.rs12
-rw-r--r--gcc/testsuite/rust/compile/self_mut_ptr.rs1
-rw-r--r--gcc/testsuite/rust/compile/self_ptr.rs1
-rw-r--r--gcc/testsuite/rust/compile/silly-order-bug.rs10
-rw-r--r--gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs3
-rw-r--r--gcc/testsuite/rust/compile/slice_rest_pattern.rs3
-rw-r--r--gcc/testsuite/rust/compile/slicepattern-size-mismatch.rs8
-rw-r--r--gcc/testsuite/rust/compile/static_var1.rs2
-rw-r--r--gcc/testsuite/rust/compile/stmt_with_block_dot.rs1
-rw-r--r--gcc/testsuite/rust/compile/struct_init1.rs6
-rw-r--r--gcc/testsuite/rust/compile/structural-eq-peq.rs11
-rw-r--r--gcc/testsuite/rust/compile/torture/associated_types1.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/builtin_abort.rs4
-rw-r--r--gcc/testsuite/rust/compile/torture/extern_mod2.rs6
-rw-r--r--gcc/testsuite/rust/compile/torture/forward_decl_5.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics1.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics10.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics11.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics12.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics13.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics14.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics15.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics16.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics17.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics18.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics19.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics2.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics20.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics21.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics22.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics23.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics24.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics25.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics26.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics27.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics28.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics29.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/generics3.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics30.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/generics31.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics32.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics4.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics5.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics6.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics7.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics8.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics9.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/identifier-missing-impl-1.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/if.rs8
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-4.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-5.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-6.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-7.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-8.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1024.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1075.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1432.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1555.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-368.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-808.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-862.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-893-2.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-893.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/must_use2.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/nested_fn2.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/phantom_data.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/range-lang-item1.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits1.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits10.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits11.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits12.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits13.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits14.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits15.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits16.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits17.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits18.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits19.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits2.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits3.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/traits4.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits5.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits6.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits7.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/traits8.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits9.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/transmute1.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs6
-rw-r--r--gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs5
-rw-r--r--gcc/testsuite/rust/compile/torture/utf8_identifiers.rs1
-rw-r--r--gcc/testsuite/rust/compile/track_caller.rs6
-rw-r--r--gcc/testsuite/rust/compile/traits1.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits10.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits11.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits12.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits2.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits3.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits4.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits5.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits6.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits7.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits8.rs1
-rw-r--r--gcc/testsuite/rust/compile/traits9.rs4
-rw-r--r--gcc/testsuite/rust/compile/try-catch-unwind-new.rs20
-rw-r--r--gcc/testsuite/rust/compile/try-catch-unwind-old.rs21
-rw-r--r--gcc/testsuite/rust/compile/try-expr1.rs85
-rw-r--r--gcc/testsuite/rust/compile/try-trait.rs46
-rw-r--r--gcc/testsuite/rust/compile/try_block1.rs90
-rw-r--r--gcc/testsuite/rust/compile/tuple_index_on_non_tuple.rs15
-rw-r--r--gcc/testsuite/rust/compile/tuple_mismatch.rs1
-rw-r--r--gcc/testsuite/rust/compile/tuplepattern-rest-readonly.rs5
-rw-r--r--gcc/testsuite/rust/compile/tuplepattern-restpattern-typecheck-err.rs8
-rw-r--r--gcc/testsuite/rust/compile/type-bindings1.rs2
-rw-r--r--gcc/testsuite/rust/compile/unconstrained_type_param.rs2
-rw-r--r--gcc/testsuite/rust/compile/undeclared_label.rs4
-rw-r--r--gcc/testsuite/rust/compile/unify-errors1.rs50
-rw-r--r--gcc/testsuite/rust/compile/unsafe10.rs1
-rw-r--r--gcc/testsuite/rust/compile/use_1.rs8
-rw-r--r--gcc/testsuite/rust/compile/use_3.rs10
-rw-r--r--gcc/testsuite/rust/compile/use_self_alone.rs2
-rw-r--r--gcc/testsuite/rust/compile/use_self_alone_in_list.rs7
-rw-r--r--gcc/testsuite/rust/compile/usize1.rs2
-rw-r--r--gcc/testsuite/rust/compile/v0-mangle1.rs1
-rw-r--r--gcc/testsuite/rust/compile/v0-mangle2.rs1
-rw-r--r--gcc/testsuite/rust/compile/while_let1.rs111
-rw-r--r--gcc/testsuite/rust/compile/while_let_without_label.rs11
-rw-r--r--gcc/testsuite/rust/compile/xfail/name_resolution21.rs2
-rw-r--r--gcc/testsuite/rust/core/core.exp37
-rw-r--r--gcc/testsuite/rust/execute/black_box.rs31
-rw-r--r--gcc/testsuite/rust/execute/crate-metavar1.rs11
-rw-r--r--gcc/testsuite/rust/execute/execute.exp33
-rw-r--r--gcc/testsuite/rust/execute/inline_asm_inout_ident.rs24
-rw-r--r--gcc/testsuite/rust/execute/inline_asm_inout_var.rs25
-rw-r--r--gcc/testsuite/rust/execute/torture/atomic_load.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/atomic_store.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs191
-rw-r--r--gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs199
-rw-r--r--gcc/testsuite/rust/execute/torture/builtin_abort.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/builtin_macro_option_env.rs65
-rw-r--r--gcc/testsuite/rust/execute/torture/closure1.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/closure2.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/closure3.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/closure4.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/coercion1.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/coercion2.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/coercion3.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/const-generics-1.rs26
-rw-r--r--gcc/testsuite/rust/execute/torture/const-generics-2.rs22
-rw-r--r--gcc/testsuite/rust/execute/torture/const-generics-3.rs14
-rw-r--r--gcc/testsuite/rust/execute/torture/const-generics-4.rs44
-rw-r--r--gcc/testsuite/rust/execute/torture/const-generics-5.rs15
-rw-r--r--gcc/testsuite/rust/execute/torture/const-generics-6.rs17
-rw-r--r--gcc/testsuite/rust/execute/torture/const-generics-7.rs23
-rw-r--r--gcc/testsuite/rust/execute/torture/const_block1.rs9
-rw-r--r--gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/derive-default1.rs28
-rw-r--r--gcc/testsuite/rust/execute/torture/derive-partialeq1.rs64
-rw-r--r--gcc/testsuite/rust/execute/torture/derive-partialeq2.rs80
-rw-r--r--gcc/testsuite/rust/execute/torture/derive_clone_enum1.rs53
-rw-r--r--gcc/testsuite/rust/execute/torture/derive_macro1.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/derive_macro3.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/derive_macro4.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/enum_intrinsics1.rs49
-rw-r--r--gcc/testsuite/rust/execute/torture/enum_intrinsics2.rs26
-rw-r--r--gcc/testsuite/rust/execute/torture/for-loop1.rs545
-rw-r--r--gcc/testsuite/rust/execute/torture/for-loop2.rs544
-rw-r--r--gcc/testsuite/rust/execute/torture/gat1.rs20
-rw-r--r--gcc/testsuite/rust/execute/torture/iflet.rs84
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_desugar-2.rs34
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_desugar.rs34
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit1.rs30
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit2.rs38
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit3.rs27
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait1.rs33
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait2.rs33
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait3.rs46
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait4.rs33
-rw-r--r--gcc/testsuite/rust/execute/torture/index1.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1120.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1133.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1198.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1232.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1249.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1436.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1481.rs36
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1482.rs25
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1496.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1720-2.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1720.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-2005.rs465
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-2052.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-2179.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-2180.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-2236.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-2583.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-3126.rs54
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-3381.rs92
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-3502.rs54
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-3836.rs454
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-4242.rs11
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-647.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-845.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-851.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-858.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/iter1.rs40
-rw-r--r--gcc/testsuite/rust/execute/torture/let-identifierpattern-subpattern.rs11
-rw-r--r--gcc/testsuite/rust/execute/torture/link-name.rs16
-rw-r--r--gcc/testsuite/rust/execute/torture/literalpattern_neg.rs9
-rw-r--r--gcc/testsuite/rust/execute/torture/macros23.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/macros28.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/match-identifierpattern.rs10
-rw-r--r--gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs27
-rw-r--r--gcc/testsuite/rust/execute/torture/match-slicepattern-array-1.rs23
-rw-r--r--gcc/testsuite/rust/execute/torture/match-slicepattern-array-2.rs27
-rw-r--r--gcc/testsuite/rust/execute/torture/match-slicepattern-slice-1.rs24
-rw-r--r--gcc/testsuite/rust/execute/torture/match-slicepattern-slice-2.rs28
-rw-r--r--gcc/testsuite/rust/execute/torture/match-tuplestructpattern-rest-1.rs24
-rw-r--r--gcc/testsuite/rust/execute/torture/match-tuplestructpattern-rest-2.rs28
-rw-r--r--gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs12
-rw-r--r--gcc/testsuite/rust/execute/torture/method2.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/method3.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/method4.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/min_specialization2.rs31
-rw-r--r--gcc/testsuite/rust/execute/torture/min_specialization3.rs36
-rw-r--r--gcc/testsuite/rust/execute/torture/multiline-string.rs15
-rw-r--r--gcc/testsuite/rust/execute/torture/name_resolution.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/offset_of1.rs16
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_1.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_10.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_11.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_12.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_2.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_3.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_4.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_5.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_6.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_7.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_8.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_9.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-eq-1.rs104
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-eq-2.rs61
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-eq-3.rs457
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-eq-4.rs457
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-1.rs102
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-2.rs469
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-3.rs489
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-4.rs115
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-5.rs487
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-6.rs518
-rw-r--r--gcc/testsuite/rust/execute/torture/prefetch_data.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/ref-pattern2.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/sip-hasher.rs437
-rw-r--r--gcc/testsuite/rust/execute/torture/slice-magic.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/slice-magic2.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/slice1.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/str-layout1.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/struct-pattern-match.rs13
-rw-r--r--gcc/testsuite/rust/execute/torture/struct_pattern1.rs19
-rw-r--r--gcc/testsuite/rust/execute/torture/trait1.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait10.rs3
-rw-r--r--gcc/testsuite/rust/execute/torture/trait11.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait12.rs3
-rw-r--r--gcc/testsuite/rust/execute/torture/trait13.rs3
-rw-r--r--gcc/testsuite/rust/execute/torture/trait14.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/trait15.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait2.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait3.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait4.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait5.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait6.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait7.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait8.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/trait9.rs3
-rw-r--r--gcc/testsuite/rust/execute/torture/transmute1.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/wrapping_op1.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/wrapping_op2.rs1
-rw-r--r--gcc/testsuite/rust/execute/xfail/match-identifierpattern-enum.rs15
-rw-r--r--gcc/testsuite/rust/link/generic_function_0.rs3
-rw-r--r--gcc/testsuite/rust/link/generic_function_1.rs1
-rw-r--r--gcc/testsuite/rust/link/trait_import_0.rs3
-rw-r--r--gcc/testsuite/rust/link/trait_import_1.rs4
725 files changed, 14641 insertions, 726 deletions
diff --git a/gcc/testsuite/rust/borrowck/reference.rs b/gcc/testsuite/rust/borrowck/reference.rs
index c4b9f7d..1bef938 100644
--- a/gcc/testsuite/rust/borrowck/reference.rs
+++ b/gcc/testsuite/rust/borrowck/reference.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
// { dg-enable-nn-line-numbers "" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/borrowck/tmp.rs b/gcc/testsuite/rust/borrowck/tmp.rs
index 545a278..210153f 100644
--- a/gcc/testsuite/rust/borrowck/tmp.rs
+++ b/gcc/testsuite/rust/borrowck/tmp.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
// { dg-enable-nn-line-numbers "" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds1.rs b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs
new file mode 100644
index 0000000..c629aba
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs
@@ -0,0 +1,10 @@
+#![feature(optin_builtin_traits, lang_items)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send {}
+impl dyn A + Send + Sync {}
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2.rs b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
new file mode 100644
index 0000000..7140b3b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
@@ -0,0 +1,9 @@
+#![feature(optin_builtin_traits, lang_items)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send + Sync + NonExist {} // { dg-error "could not resolve type path .NonExist." }
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
new file mode 100644
index 0000000..7140b3b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
@@ -0,0 +1,9 @@
+#![feature(optin_builtin_traits, lang_items)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send + Sync + NonExist {} // { dg-error "could not resolve type path .NonExist." }
diff --git a/gcc/testsuite/rust/compile/all-cast.rs b/gcc/testsuite/rust/compile/all-cast.rs
index fa24373..6d8576c 100644
--- a/gcc/testsuite/rust/compile/all-cast.rs
+++ b/gcc/testsuite/rust/compile/all-cast.rs
@@ -4,7 +4,7 @@ fn main() {
0u32 as char; // { dg-error "cannot cast .u32. as .char., only .u8. can be cast as .char." }
- let x = &[1_usize, 2] as [usize]; // { dg-error "cast to unsized type: .& .usize:CAPACITY.. as ..usize.." }
+ let x = &[1_usize, 2] as [usize]; // { dg-error "cast to unsized type: .& .usize; 2.. as ..usize.." }
let a = &0u8; // Here, `x` is a `&u8`.
let y: u32 = a as u32; // { dg-error "casting .& u8. as .u32. is invalid" }
diff --git a/gcc/testsuite/rust/compile/arrays2.rs b/gcc/testsuite/rust/compile/arrays2.rs
index 668bcf0..1090059 100644
--- a/gcc/testsuite/rust/compile/arrays2.rs
+++ b/gcc/testsuite/rust/compile/arrays2.rs
@@ -1,5 +1,4 @@
-// { dg-additional-options "-w" }
fn main() {
let array: [i32; 5] = [1, 2, 3];
- // { dg-error "mismatched types, expected an array with a fixed size of 5 elements, found one with 3 elements" "" { target *-*-* } .-1 }
+ // { dg-error "mismatched types, expected ..i32; 5.. but got ...integer.; 3.. .E0308." "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/attr-macro.rs b/gcc/testsuite/rust/compile/attr-macro.rs
new file mode 100644
index 0000000..de9fce1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/attr-macro.rs
@@ -0,0 +1,7 @@
+macro_rules! foo {
+ () => { #[cfg(all())] 12 }
+}
+
+fn main() -> i32 {
+ foo!()
+}
diff --git a/gcc/testsuite/rust/compile/attr_malformed_doc.rs b/gcc/testsuite/rust/compile/attr_malformed_doc.rs
new file mode 100644
index 0000000..6b9ef61
--- /dev/null
+++ b/gcc/testsuite/rust/compile/attr_malformed_doc.rs
@@ -0,0 +1,3 @@
+// { dg-error "valid forms for the attribute are ...doc.hidden.inline....... and ...doc = . string ..." "" { target *-*-* } .+1 }
+#[doc]
+trait MyTrait {}
diff --git a/gcc/testsuite/rust/compile/attr_malformed_path.rs b/gcc/testsuite/rust/compile/attr_malformed_path.rs
new file mode 100644
index 0000000..2bccf37
--- /dev/null
+++ b/gcc/testsuite/rust/compile/attr_malformed_path.rs
@@ -0,0 +1,3 @@
+#[cfg_attr(target_arch = "x86_64", path = (target_arch = "x86", path = "x86.rs"))]
+mod imp {}
+// { dg-error "malformed .path. attribute input" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/auto_traits1.rs b/gcc/testsuite/rust/compile/auto_traits1.rs
new file mode 100644
index 0000000..e9f5e0a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_traits1.rs
@@ -0,0 +1,27 @@
+// { dg-additional-options "-frust-compile-until=typecheck" }
+
+#![feature(optin_builtin_traits, lang_items)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {
+ fn a_method(&self) {}
+}
+
+fn foo(a: &(dyn A + Send + Sync)) {
+ a.a_method();
+}
+
+struct S;
+
+impl A for S {
+ fn a_method(&self) {}
+}
+
+fn main() {
+ let s = S;
+
+ foo(&s);
+}
diff --git a/gcc/testsuite/rust/compile/auto_traits2.rs b/gcc/testsuite/rust/compile/auto_traits2.rs
new file mode 100644
index 0000000..eda22b5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_traits2.rs
@@ -0,0 +1,25 @@
+#![feature(optin_builtin_traits, lang_items)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {
+ fn a_method(&self) {}
+}
+
+fn foo(a: &(dyn A + Send + Sync)) {
+ a.a_method();
+}
+
+struct S;
+
+impl A for S {
+ fn a_method(&self) {}
+}
+
+fn main() {
+ let s = S;
+
+ foo(&s);
+}
diff --git a/gcc/testsuite/rust/compile/auto_traits4.rs b/gcc/testsuite/rust/compile/auto_traits4.rs
new file mode 100644
index 0000000..f1cd1e4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_traits4.rs
@@ -0,0 +1,14 @@
+#![feature(optin_builtin_traits)]
+
+unsafe auto trait Send {}
+unsafe auto trait Sync {}
+
+fn take_send(_: &dyn Send) {}
+fn take_sync(_: &dyn Sync) {}
+
+fn main() {
+ let a = i32;
+
+ take_send(&a);
+ take_sync(&a);
+}
diff --git a/gcc/testsuite/rust/compile/bad-rpit1.rs b/gcc/testsuite/rust/compile/bad-rpit1.rs
new file mode 100644
index 0000000..c728e36
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad-rpit1.rs
@@ -0,0 +1,27 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct A;
+struct B;
+
+impl Foo for A {
+ fn id(&self) -> i32 {
+ 1
+ }
+}
+
+impl Foo for B {
+ fn id(&self) -> i32 {
+ 2
+ }
+}
+
+fn make_foo(cond: bool) -> impl Foo {
+ if cond { A } else { B }
+ // { dg-error "mismatched types, expected .A. but got .B. .E0308." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/black_box.rs b/gcc/testsuite/rust/compile/black_box.rs
new file mode 100644
index 0000000..35d9e9e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/black_box.rs
@@ -0,0 +1,28 @@
+// { dg-options "-fdump-tree-gimple" }
+#![feature(rustc_attrs, lang_items)]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[rustc_builtin_macro]
+macro_rules! llvm_asm {
+ () => {};
+}
+
+pub fn black_box<T>(mut dummy: T) -> T {
+ unsafe {
+ // { dg-final { scan-tree-dump-times {memory} 1 gimple } }
+ llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
+ }
+
+ dummy
+}
+
+fn my_function(a: i32) -> i32 {
+ a
+}
+
+fn main() {
+ let dummy: i32 = 42;
+ let _ = black_box(my_function(dummy));
+}
diff --git a/gcc/testsuite/rust/compile/bounds1.rs b/gcc/testsuite/rust/compile/bounds1.rs
index a02e6f6..5891f71 100644
--- a/gcc/testsuite/rust/compile/bounds1.rs
+++ b/gcc/testsuite/rust/compile/bounds1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs b/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs
index 5f62a59..62e7c10 100644
--- a/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs
+++ b/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs
@@ -1,4 +1,5 @@
// { dg-options "-frust-compile-until=lowering" }
+#![feature(lang_items)]
#[lang = "owned_box"]
pub struct Box<T>;
diff --git a/gcc/testsuite/rust/compile/braced_macro_arm.rs b/gcc/testsuite/rust/compile/braced_macro_arm.rs
index 1446878..8782cf9 100644
--- a/gcc/testsuite/rust/compile/braced_macro_arm.rs
+++ b/gcc/testsuite/rust/compile/braced_macro_arm.rs
@@ -7,12 +7,9 @@ macro_rules! m {
fn h(c: bool) {
match c {
- // { dg-error "failed to parse statement or expression in block expression" "" { target *-*-* } .-1 }
true => m! {}
false => ()
// { dg-error "exprwithoutblock requires comma after match case expression in match arm \\(if not final case\\)" "" { target *-*-* } .-1 }
- // { dg-error "unrecognised token .false. for start of item" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
};
}
diff --git a/gcc/testsuite/rust/compile/bug-with-default-generic.rs b/gcc/testsuite/rust/compile/bug-with-default-generic.rs
new file mode 100644
index 0000000..3f31fcc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bug-with-default-generic.rs
@@ -0,0 +1,16 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+pub trait MyBinaryTrait<Rhs = Self> {
+ fn do_something(&self, rhs: &Rhs);
+}
+
+struct Foo<T> {
+ // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+ value: T,
+}
+
+impl<T> MyBinaryTrait for Foo<T> {
+ fn do_something(&self, _rhs: &Self) {}
+}
diff --git a/gcc/testsuite/rust/compile/canonical_paths1.rs b/gcc/testsuite/rust/compile/canonical_paths1.rs
index bd6f3b2..f80d6e6 100644
--- a/gcc/testsuite/rust/compile/canonical_paths1.rs
+++ b/gcc/testsuite/rust/compile/canonical_paths1.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w -fdump-tree-gimple -frust-crate=example" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/cast_float_as_integer.rs b/gcc/testsuite/rust/compile/cast_float_as_integer.rs
new file mode 100644
index 0000000..e6b86db
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cast_float_as_integer.rs
@@ -0,0 +1,10 @@
+// { dg-options "-w" }
+fn main(){
+ let foo:f64 = 13.37;
+ let _ = foo as i64;
+ let _ = foo as u64;
+ let _ = foo as isize;
+ let _ = foo as usize;
+ let _ = foo as i8;
+ let _ = foo as u8;
+}
diff --git a/gcc/testsuite/rust/compile/cast_generics.rs b/gcc/testsuite/rust/compile/cast_generics.rs
index 469fa94..6da9193 100644
--- a/gcc/testsuite/rust/compile/cast_generics.rs
+++ b/gcc/testsuite/rust/compile/cast_generics.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/cfg-core1.rs b/gcc/testsuite/rust/compile/cfg-core1.rs
new file mode 100644
index 0000000..7780cc9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg-core1.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-frust-cfg=A -frust-cfg=B" }
+
+#[cfg_attr(A, cfg(B))]
+struct Foo0;
+
+#[cfg_attr(A, cfg(C))]
+struct Bar0;
+
+fn main() {
+ let a = Foo0;
+ let a = Bar0; // { dg-error "cannot find value" }
+}
diff --git a/gcc/testsuite/rust/compile/cfg-core2.rs b/gcc/testsuite/rust/compile/cfg-core2.rs
new file mode 100644
index 0000000..e346edd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg-core2.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-frust-cfg=B" }
+
+#[cfg(not(any(A, B)))]
+struct Foo0;
+
+#[cfg(not(any(A, C)))]
+struct Bar0;
+
+fn main() {
+ let a = Foo0; // { dg-error "cannot find value" }
+ let a = Bar0;
+}
diff --git a/gcc/testsuite/rust/compile/cfg-test.rs b/gcc/testsuite/rust/compile/cfg-test.rs
new file mode 100644
index 0000000..a2e870c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg-test.rs
@@ -0,0 +1,4 @@
+#[test]
+fn foo() {
+ some_function_which_doesnt_exist();
+}
diff --git a/gcc/testsuite/rust/compile/closure_no_type_anno.rs b/gcc/testsuite/rust/compile/closure_no_type_anno.rs
index b647da7..2aab16f 100644
--- a/gcc/testsuite/rust/compile/closure_no_type_anno.rs
+++ b/gcc/testsuite/rust/compile/closure_no_type_anno.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/cmp1.rs b/gcc/testsuite/rust/compile/cmp1.rs
new file mode 100644
index 0000000..db1589e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cmp1.rs
@@ -0,0 +1,79 @@
+// { dg-options "-w" }
+// taken from https://github.com/rust-lang/rust/blob/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/core/src/cmp.rs#L98
+
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "eq"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(alias = "==")]
+#[doc(alias = "!=")]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ /// This method tests for `!=`.
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+enum BookFormat {
+ Paperback,
+ Hardback,
+ Ebook,
+}
+
+impl PartialEq<BookFormat> for BookFormat {
+ fn eq(&self, other: &BookFormat) -> bool {
+ self == other
+ }
+}
+
+pub struct Book {
+ isbn: i32,
+ format: BookFormat,
+}
+
+// Implement <Book> == <BookFormat> comparisons
+impl PartialEq<BookFormat> for Book {
+ fn eq(&self, other: &BookFormat) -> bool {
+ self.format == *other
+ }
+}
+
+// Implement <BookFormat> == <Book> comparisons
+impl PartialEq<Book> for BookFormat {
+ fn eq(&self, other: &Book) -> bool {
+ *self == other.format
+ }
+}
+
+// Implement <Book> == <Book> comparisons
+impl PartialEq<Book> for Book {
+ fn eq(&self, other: &Book) -> bool {
+ self.isbn == other.isbn
+ }
+}
+
+pub fn main() {
+ let b1 = Book {
+ isbn: 1,
+ format: BookFormat::Paperback,
+ };
+ let b2 = Book {
+ isbn: 2,
+ format: BookFormat::Paperback,
+ };
+
+ let _c1: bool = b1 == BookFormat::Paperback;
+ let _c2: bool = BookFormat::Paperback == b2;
+ let _c3: bool = b1 != b2;
+}
diff --git a/gcc/testsuite/rust/compile/complex_qualified_path_in_expr.rs b/gcc/testsuite/rust/compile/complex_qualified_path_in_expr.rs
index 5036410..85bdaf0 100644
--- a/gcc/testsuite/rust/compile/complex_qualified_path_in_expr.rs
+++ b/gcc/testsuite/rust/compile/complex_qualified_path_in_expr.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/const-issue1440.rs b/gcc/testsuite/rust/compile/const-issue1440.rs
index 3a2989c..43748cf2 100644
--- a/gcc/testsuite/rust/compile/const-issue1440.rs
+++ b/gcc/testsuite/rust/compile/const-issue1440.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/const3.rs b/gcc/testsuite/rust/compile/const3.rs
index 22dc3d3..c1d0f29 100644
--- a/gcc/testsuite/rust/compile/const3.rs
+++ b/gcc/testsuite/rust/compile/const3.rs
@@ -3,5 +3,5 @@ fn size() -> usize {
}
fn main() {
- let a = [15; size()]; // { dg-error "only functions marked as .const. are allowed to be called from constant contexts" }
+ let a = [15; size()]; // { dg-error "calls in constants are limited to constant functions, tuple structs and tuple variants" }
}
diff --git a/gcc/testsuite/rust/compile/const_generics_1.rs b/gcc/testsuite/rust/compile/const_generics_1.rs
index 5d4ca64..b22e07e 100644
--- a/gcc/testsuite/rust/compile/const_generics_1.rs
+++ b/gcc/testsuite/rust/compile/const_generics_1.rs
@@ -3,6 +3,7 @@
// There are errors about unused generic parameters, but we can't handle that yet.
// Still, this code is invalid Rust.
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/const_generics_10.rs b/gcc/testsuite/rust/compile/const_generics_10.rs
new file mode 100644
index 0000000..1300126
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_10.rs
@@ -0,0 +1,33 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+const M: usize = 4;
+
+struct Foo<T, const N: usize = 1> {
+ value: [T; N],
+}
+
+fn main() {
+ let foo = Foo::<i32> { value: [15] };
+ let foo = Foo::<i32, 2> { value: [15, 13] };
+ let foo: Foo<i32, 2> = Foo { value: [15, 13] };
+ let foo: Foo<i32, 2> = Foo::<i32, 2> { value: [15, 13] };
+ let foo: Foo<i32, { 1 + 1 }> = Foo { value: [15, 13] };
+ let foo = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+ let foo: Foo<i32, { 1 + 1 }> = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+ let foo: Foo<i32, M> = Foo::<i32, 4> {
+ value: [15, 13, 11, 9],
+ };
+
+ let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, 3> { value: [15, 13] };
+ // { dg-error {mismatched types, expected ..T=i32; 3.. but got ...integer.; 2.. .E0308.} "" { target *-*-* } .-1 }
+ // { dg-error {mismatched types, expected ..T=i32; 2.. but got ..T=i32; 3.. .E0308.} "" { target *-*-* } .-2 }
+
+ let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, M> { value: [15, 13] };
+ // { dg-error {mismatched types, expected ..T=i32; 4.. but got ...integer.; 2.. .E0308.} "" { target *-*-* } .-1 }
+ // { dg-error {mismatched types, expected ..T=i32; 2.. but got ..T=i32; 4.. .E0308.} "" { target *-*-* } .-2 }
+
+ let invalid_foo: Foo<i32> = Foo::<i32, 2> { value: [15, 13] };
+ // { dg-error {mismatched types, expected ..T=i32; 1.. but got ..T=i32; 2.. .E0308.} "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_11.rs b/gcc/testsuite/rust/compile/const_generics_11.rs
new file mode 100644
index 0000000..381d9f4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_11.rs
@@ -0,0 +1,14 @@
+// { dg-options "-w" }
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+struct Matrix<T, const ROWS: usize, const COLS: usize> {
+ data: [[T; COLS]; ROWS],
+}
+
+fn main() {
+ let _: Matrix<u8, 2, 3> = Matrix {
+ data: [[1, 2, 3], [4, 5, 6]],
+ };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_12.rs b/gcc/testsuite/rust/compile/const_generics_12.rs
new file mode 100644
index 0000000..88b151f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_12.rs
@@ -0,0 +1,14 @@
+// { dg-options "-w" }
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+const BASE: usize = 2;
+
+struct Foo<T, const N: usize> {
+ data: [T; N],
+}
+
+fn main() {
+ let _ = Foo::<u8, { BASE + 1 * 2 }> { data: [0; 4] };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_13.rs b/gcc/testsuite/rust/compile/const_generics_13.rs
new file mode 100644
index 0000000..bf8e78e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_13.rs
@@ -0,0 +1,12 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<T, const N: usize> {
+ value: [T; N],
+}
+
+fn main() {
+ let foo: Foo<_, _>;
+ // { dg-error {type provided when a constant was expected .E0747.} "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_14.rs b/gcc/testsuite/rust/compile/const_generics_14.rs
new file mode 100644
index 0000000..e0d206f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_14.rs
@@ -0,0 +1,14 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+type MyLen = usize;
+struct Foo<T, const N: usize> {
+ data: [T; N],
+}
+
+fn main() {
+ let _ = Foo::<u8, MyLen> { data: [1, 2, 3] };
+ // { dg-error {type provided when a constant was expected .E0747.} "" { target *-*-* } .-1 }
+ // { dg-error {expected an ADT type for constructor} "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_15.rs b/gcc/testsuite/rust/compile/const_generics_15.rs
new file mode 100644
index 0000000..158548c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_15.rs
@@ -0,0 +1,17 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+enum Foo<const N: usize> {
+ A([u8; N]),
+}
+
+union Bar<const N: usize> {
+ a: [i32; N],
+ b: [u8; N],
+}
+
+fn main() {
+ let _ = Foo::<4>::A([1, 2, 3, 4]);
+ let _ = Bar::<4> { a: [0; 4] };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_16.rs b/gcc/testsuite/rust/compile/const_generics_16.rs
new file mode 100644
index 0000000..467be6a68
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_16.rs
@@ -0,0 +1,11 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<T = u8, const N: usize = 4> {
+ data: [T; N], // { dg-warning "field is never read: .data." }
+}
+
+fn main() {
+ let _x = Foo { data: [1, 2, 3, 4] };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_17.rs b/gcc/testsuite/rust/compile/const_generics_17.rs
new file mode 100644
index 0000000..f65ca22
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_17.rs
@@ -0,0 +1,3 @@
+struct Foo<const N: u32 = 1, const O: bool>; // { dg-error "invalid order for generic parameters: generic parameters with a default must be trailing" }
+
+impl<const N: u32> Foo<N> {}
diff --git a/gcc/testsuite/rust/compile/const_generics_18.rs b/gcc/testsuite/rust/compile/const_generics_18.rs
new file mode 100644
index 0000000..09bb860
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_18.rs
@@ -0,0 +1,11 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<const N: usize>;
+type Alias = Foo<4>;
+
+fn main() -> i32 {
+ let _x: Alias = Foo::<4> {};
+ 0
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_19.rs b/gcc/testsuite/rust/compile/const_generics_19.rs
new file mode 100644
index 0000000..73c1419
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_19.rs
@@ -0,0 +1,11 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<const N: usize>;
+struct Wrapper<T>(T);
+
+fn main() -> i32 {
+ let _: Wrapper<Foo<3>> = Wrapper(Foo::<3> {});
+ 0
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_3.rs b/gcc/testsuite/rust/compile/const_generics_3.rs
index e4e9008..528cf69 100644
--- a/gcc/testsuite/rust/compile/const_generics_3.rs
+++ b/gcc/testsuite/rust/compile/const_generics_3.rs
@@ -1,26 +1,22 @@
-// { dg-additional-options "-w" }
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
const M: usize = 4;
struct Foo<T, const N: usize = 1> {
- // FIXME: This error is bogus. But having it means parsing is valid!
- value: [i32; N], // { dg-error "cannot find value .N. in this scope" }
+ value: [T; N], // { dg-warning "field is never read: .value." }
}
fn main() {
- let foo = Foo::<i32> { value: [15] };
- let foo = Foo::<i32, 2> { value: [15, 13] };
- let foo: Foo<i32, 2> = Foo { value: [15, 13] };
- let foo: Foo<i32, 2> = Foo::<i32, 2> { value: [15, 13] };
- let foo: Foo<i32, { 1 + 1 }> = Foo { value: [15, 13] };
- let foo = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
- let foo: Foo<i32, { 1 + 1 }> = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
- let foo: Foo<i32, M> = Foo::<i32, 4> {
+ let _foo = Foo::<i32> { value: [15] };
+ let _foo = Foo::<i32, 2> { value: [15, 13] };
+ let _foo: Foo<i32, 2> = Foo { value: [15, 13] };
+ let _foo: Foo<i32, 2> = Foo::<i32, 2> { value: [15, 13] };
+ let _foo: Foo<i32, { 1 + 1 }> = Foo { value: [15, 13] };
+ let _foo = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+ let _foo: Foo<i32, { 1 + 1 }> = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+ let _foo: Foo<i32, M> = Foo::<i32, 4> {
value: [15, 13, 11, 9],
};
-
- // FIXME: Add proper const typecheck errors here
- let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, 3> { value: [15, 13] };
- let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, M> { value: [15, 13] };
- let invalid_foo: Foo<i32> = Foo::<i32, 2> { value: [15, 13] };
}
diff --git a/gcc/testsuite/rust/compile/const_generics_4.rs b/gcc/testsuite/rust/compile/const_generics_4.rs
index b364d3b..2766e4c 100644
--- a/gcc/testsuite/rust/compile/const_generics_4.rs
+++ b/gcc/testsuite/rust/compile/const_generics_4.rs
@@ -4,4 +4,4 @@ const P: usize = 14;
struct Foo<const N: usize = { M }>; // { dg-error "cannot find value .M. in this scope" }
struct Bar<const N: usize = { P }>;
-struct Baz<const N: NotAType = { P }>; // { dg-error "failed to resolve TypePath: NotAType in this scope" }
+struct Baz<const N: NotAType = { P }>; // { dg-error "could not resolve type path .NotAType." }
diff --git a/gcc/testsuite/rust/compile/const_generics_5.rs b/gcc/testsuite/rust/compile/const_generics_5.rs
index 685229e..4d05569 100644
--- a/gcc/testsuite/rust/compile/const_generics_5.rs
+++ b/gcc/testsuite/rust/compile/const_generics_5.rs
@@ -1,4 +1,3 @@
-// { dg-options "-w" }
struct Foo<const N: usize = { 14 }>;
const M: usize = 15;
@@ -8,5 +7,6 @@ fn main() {
let _: Foo<15> = Foo;
let _: Foo<{ M }> = Foo;
let _: Foo<M> = Foo;
- // let _: Foo<N> = Foo; this causes an ICE we need to do const generics
+ let _: Foo<N> = Foo;
+ // { dg-error {type provided when a constant was expected .E0747.} "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/const_generics_7.rs b/gcc/testsuite/rust/compile/const_generics_7.rs
index 2c128db..dad4c21 100644
--- a/gcc/testsuite/rust/compile/const_generics_7.rs
+++ b/gcc/testsuite/rust/compile/const_generics_7.rs
@@ -1,17 +1,17 @@
struct S<const N: usize>;
-pub fn foo<const N: FooBar>() {} // { dg-error "failed to resolve" }
-type Foo<const N: FooBar> = S<N>; // { dg-error "failed to resolve" }
-struct Foo2<const N: FooBar>; // { dg-error "failed to resolve" }
-enum Foo3<const N: FooBar> { // { dg-error "failed to resolve" }
+pub fn foo<const N: FooBar>() {} // { dg-error "could not resolve" }
+type Foo<const N: FooBar> = S<N>; // { dg-error "could not resolve" }
+struct Foo2<const N: FooBar>; // { dg-error "could not resolve" }
+enum Foo3<const N: FooBar> { // { dg-error "could not resolve" }
Foo,
Bar,
}
-union Foo4<const N: FooBar> { // { dg-error "failed to resolve" }
+union Foo4<const N: FooBar> { // { dg-error "could not resolve" }
a: usize,
b: i32,
}
-trait Fooable<const N: FooBar> {} // { dg-error "failed to resolve" }
+trait Fooable<const N: FooBar> {} // { dg-error "could not resolve" }
trait Traitable {}
-impl<const N: FooBar> Traitable for Foo2<N> {} // { dg-error "failed to resolve" }
+impl<const N: FooBar> Traitable for Foo2<N> {} // { dg-error "could not resolve" }
diff --git a/gcc/testsuite/rust/compile/const_generics_8.rs b/gcc/testsuite/rust/compile/const_generics_8.rs
index bb34652..32b7a19 100644
--- a/gcc/testsuite/rust/compile/const_generics_8.rs
+++ b/gcc/testsuite/rust/compile/const_generics_8.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -9,12 +10,13 @@ type Bipboupe<const N: i32 = 15> = Bidule;
trait Fooable<const N: i32 = 15> {}
union Bidoulepe<const N: i32 = 15> {
- // { dg-error "default values for const generic parameters are not allowed in .union. items" "" {target *-*-* } .-1 }
int: i32,
float: f32,
}
-fn const_default<const N: i32 = 15>() {} // { dg-error "default values for const generic parameters are not allowed in .function. items" }
+fn const_default<const N: i32 = 15>() {} // { dg-error "default values for const generic parameters are not allowed here" }
// Note - missing generic parameter - needs name resolution on const generics
-impl<const N: i32 = 15> Bidule {} // { dg-error "default values for const generic parameters are not allowed in .impl. items" }
+impl<const N: i32 = 15> Bidule {}
+// { dg-error "default values for const generic parameters are not allowed here" "" {target *-*-* } .-1 }
+// { dg-error "unconstrained type parameter" "" {target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/const_generics_9.rs b/gcc/testsuite/rust/compile/const_generics_9.rs
new file mode 100644
index 0000000..a3f7485
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_9.rs
@@ -0,0 +1,13 @@
+// { dg-options "-w" }
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+struct ArrayWrapper<T, const N: usize> {
+ data: [T; N],
+}
+
+pub fn test() -> [u8; 4] {
+ let a = ArrayWrapper { data: [1u8; 4] };
+ a.data
+}
diff --git a/gcc/testsuite/rust/compile/crate-metavar1.rs b/gcc/testsuite/rust/compile/crate-metavar1.rs
new file mode 100644
index 0000000..45384e1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/crate-metavar1.rs
@@ -0,0 +1,14 @@
+macro_rules! foo {
+ () => {
+ $crate::inner::bar()
+ }
+}
+
+pub mod inner {
+ pub fn bar() { }
+}
+
+fn main() {
+ foo!();
+ crate::inner::bar();
+}
diff --git a/gcc/testsuite/rust/compile/decl_macro6.rs b/gcc/testsuite/rust/compile/decl_macro6.rs
index 5c5e700..b290b4c 100644
--- a/gcc/testsuite/rust/compile/decl_macro6.rs
+++ b/gcc/testsuite/rust/compile/decl_macro6.rs
@@ -2,4 +2,3 @@
macro m {}
// { dg-error "unexpected token .\}. - expecting delimiters .for a macro matcher." "" { target *-*-* } .-1 }
// { dg-error "required first macro rule in declarative macro definition could not be parsed" "" { target *-*-* } .-2 }
-// { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
diff --git a/gcc/testsuite/rust/compile/decl_macro7.rs b/gcc/testsuite/rust/compile/decl_macro7.rs
index 7327fb5..8007544 100644
--- a/gcc/testsuite/rust/compile/decl_macro7.rs
+++ b/gcc/testsuite/rust/compile/decl_macro7.rs
@@ -1,4 +1,3 @@
#![feature(decl_macro)]
pub macro hello() [ "Hello" ]
// { dg-error "only braces can be used for a macro transcriber in declarative macro definition" "" { target *-*-* } .-1 }
-// { dg-error "failed to parse item in crate" } \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/deferred_const_inference.rs b/gcc/testsuite/rust/compile/deferred_const_inference.rs
new file mode 100644
index 0000000..25a3b17
--- /dev/null
+++ b/gcc/testsuite/rust/compile/deferred_const_inference.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-frust-compile-until=typecheck" }
+
+// #![feature(generic_arg_infer)]
+
+fn main() {
+ let a: [u32; _] = [15u32];
+}
diff --git a/gcc/testsuite/rust/compile/derive-debug1.rs b/gcc/testsuite/rust/compile/derive-debug1.rs
new file mode 100644
index 0000000..f69be0d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive-debug1.rs
@@ -0,0 +1,42 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+mod core {
+ pub mod result {
+ pub enum Result<T, E> {
+ #[lang = "Ok"]
+ Ok(T),
+ #[lang = "Err"]
+ Err(E),
+ }
+ }
+
+ mod fmt {
+ struct Formatter; // { dg-warning "is never constructed" }
+ struct Error; // { dg-warning "is never constructed" }
+
+ type Result = crate::core::result::Result<(), Error>;
+
+ trait Debug {
+ fn fmt(&self, fmt: &mut Formatter) -> Result;
+ }
+ }
+}
+
+#[derive(Debug)]
+// { dg-warning "stub implementation" "" { target *-*-* } .-1 }
+struct Foo { a: i32, b: i64 } // { dg-warning "is never constructed" }
+
+#[derive(Debug)]
+// { dg-warning "stub implementation" "" { target *-*-* } .-1 }
+struct Bar(i32, i32); // { dg-warning "is never constructed" }
+
+#[derive(Debug)]
+// { dg-warning "stub implementation" "" { target *-*-* } .-1 }
+enum Baz {
+ A,
+ B(i32),
+ C { a: i32 }
+}
+
diff --git a/gcc/testsuite/rust/compile/derive-default1.rs b/gcc/testsuite/rust/compile/derive-default1.rs
new file mode 100644
index 0000000..ad31d5a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive-default1.rs
@@ -0,0 +1,31 @@
+#![feature(lang_items)]
+
+#[derive(Default)]
+struct Foo { _a: i32, _b: i64, _c: u8 }
+
+#[lang = "sized"]
+trait Sized {}
+
+mod core {
+ mod default {
+ trait Default: Sized {
+ fn default() -> Self;
+ }
+
+ impl Default for i32 {
+ fn default() -> Self { 0 }
+ }
+
+ impl Default for i64 {
+ fn default() -> Self { 27 }
+ }
+
+ impl Default for u8 {
+ fn default() -> Self { 18 }
+ }
+ }
+}
+
+fn main() {
+ let _ = Foo::default();
+}
diff --git a/gcc/testsuite/rust/compile/derive-eq-invalid.rs b/gcc/testsuite/rust/compile/derive-eq-invalid.rs
new file mode 100644
index 0000000..47fac78
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive-eq-invalid.rs
@@ -0,0 +1,54 @@
+#![feature(lang_items)]
+
+mod core {
+ mod cmp {
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ pub trait Eq: PartialEq<Self> {
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+ }
+}
+
+#[lang = "phantom_data"]
+struct PhantomData<T>;
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
+#[lang = "structural_teq"]
+trait StructuralEq {}
+
+#[derive(PartialEq)]
+struct NotEq;
+
+#[derive(Eq, PartialEq)] // { dg-error "bounds not satisfied for NotEq .Eq." }
+struct Container(NotEq);
+
+// #[derive(Eq)]
+// struct Foo { a: i32 }
+// #[derive(Eq)]
+// struct Bar(i32);
+
+// #[derive(Eq)]
+// enum Baz {
+// A,
+// B(i32),
+// C { a: i32 }
+// }
+
+// #[derive(Eq)]
+// union Qux {
+// a: i32,
+// b: i64,
+// }
diff --git a/gcc/testsuite/rust/compile/derive-hash1.rs b/gcc/testsuite/rust/compile/derive-hash1.rs
new file mode 100644
index 0000000..cdcc9b1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive-hash1.rs
@@ -0,0 +1,91 @@
+#![feature(intrinsics, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+
+ pub mod hash {
+ pub trait Hasher {}
+
+ pub trait Hash {
+ /// Feeds this value into the given [`Hasher`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::hash_map::DefaultHasher;
+ /// use std::hash::{Hash, Hasher};
+ ///
+ /// let mut hasher = DefaultHasher::new();
+ /// 7920.hash(&mut hasher);
+ /// println!("Hash is {:x}!", hasher.finish());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn hash<H: Hasher>(&self, state: &mut H);
+
+ /// Feeds a slice of this type into the given [`Hasher`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::hash_map::DefaultHasher;
+ /// use std::hash::{Hash, Hasher};
+ ///
+ /// let mut hasher = DefaultHasher::new();
+ /// let numbers = [6, 28, 496, 8128];
+ /// Hash::hash_slice(&numbers, &mut hasher);
+ /// println!("Hash is {:x}!", hasher.finish());
+ /// ```
+ #[stable(feature = "hash_slice", since = "1.3.0")]
+ fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
+ where
+ Self: Sized,
+ {
+ // for piece in data {
+ // piece.hash(state);
+ // }
+ }
+ }
+ }
+}
+
+impl core::hash::Hash for i32 {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {}
+}
+
+impl core::hash::Hash for i64 {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {}
+}
+
+// for the discriminant value
+impl core::hash::Hash for isize {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {}
+}
+
+#[derive(Hash)]
+struct Foo { // { dg-warning "never constructed" }
+ a: i32,
+ b: i32,
+}
+
+#[derive(Hash)]
+struct Bar(i32, i64); // { dg-warning "never constructed" }
+
+#[derive(Hash)]
+enum Baz {
+ A,
+ B(i32),
+ C { a: i64 }
+}
diff --git a/gcc/testsuite/rust/compile/derive-partialeq1.rs b/gcc/testsuite/rust/compile/derive-partialeq1.rs
new file mode 100644
index 0000000..fbeb054
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive-partialeq1.rs
@@ -0,0 +1,62 @@
+#![feature(intrinsics, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ /// This method tests for `!=`.
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+#[derive(PartialEq, Copy)] // { dg-warning "unused name" }
+struct Foo;
+
+#[derive(PartialEq)]
+struct Bar(Foo);
+
+#[derive(PartialEq)]
+struct Baz { _inner: Foo }
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(b: bool) {
+ if b {
+ unsafe { puts("true" as *const str as *const i8) }
+ } else {
+ unsafe { puts("false" as *const str as *const i8) }
+ }
+}
+
+fn main() -> i32 {
+ let x = Foo;
+
+ let b1 = x == Foo;
+ let b2 = Bar(x) != Bar(Foo);
+ let b3 = Baz { _inner: Foo } != Baz { _inner: x };
+
+ print(b1);
+ print(b2);
+ print(b3);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/compile/derive_clone_enum1.rs b/gcc/testsuite/rust/compile/derive_clone_enum1.rs
new file mode 100644
index 0000000..7dc0a80
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive_clone_enum1.rs
@@ -0,0 +1,18 @@
+#![feature(lang_items)]
+
+#[lang = "clone"]
+trait Clone {
+ pub fn clone(&self) -> Self;
+}
+
+impl Clone for i32 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+#[derive(Clone)]
+enum AllIdentifiers {
+ A,
+ B
+}
diff --git a/gcc/testsuite/rust/compile/derive_clone_enum2.rs b/gcc/testsuite/rust/compile/derive_clone_enum2.rs
new file mode 100644
index 0000000..6f5b29a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive_clone_enum2.rs
@@ -0,0 +1,18 @@
+#![feature(lang_items)]
+
+#[lang = "clone"]
+trait Clone {
+ pub fn clone(&self) -> Self;
+}
+
+impl Clone for i32 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+#[derive(Clone)]
+enum TupleEnum {
+ A(i32),
+ B(i32, i32, i32)
+}
diff --git a/gcc/testsuite/rust/compile/derive_clone_enum3.rs b/gcc/testsuite/rust/compile/derive_clone_enum3.rs
new file mode 100644
index 0000000..7c76ab2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive_clone_enum3.rs
@@ -0,0 +1,18 @@
+#![feature(lang_items)]
+
+#[lang = "clone"]
+trait Clone {
+ pub fn clone(&self) -> Self;
+}
+
+impl Clone for i32 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+#[derive(Clone)]
+enum StructEnum {
+ A { i0: i32 },
+ B { i0: i32, i1: i32, i2: i32 }
+}
diff --git a/gcc/testsuite/rust/compile/derive_macro1.rs b/gcc/testsuite/rust/compile/derive_macro1.rs
index 779aad78e..df7c8e3 100644
--- a/gcc/testsuite/rust/compile/derive_macro1.rs
+++ b/gcc/testsuite/rust/compile/derive_macro1.rs
@@ -1,12 +1,14 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
+#[lang = "clone"]
pub trait Clone {
fn clone(&self) -> Self;
}
// This warning can be removed once we properly handle implems with #[automatically_derived]
-#[derive(Clone)] // { dg-warning "unused name .self." }
+#[derive(Clone)]
pub struct S;
fn main() {
diff --git a/gcc/testsuite/rust/compile/derive_macro3.rs b/gcc/testsuite/rust/compile/derive_macro3.rs
index 1c7d473..37b1d50 100644
--- a/gcc/testsuite/rust/compile/derive_macro3.rs
+++ b/gcc/testsuite/rust/compile/derive_macro3.rs
@@ -1,6 +1,8 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
+#[lang = "clone"]
pub trait Clone {
fn clone(&self) -> Self;
}
diff --git a/gcc/testsuite/rust/compile/derive_macro4.rs b/gcc/testsuite/rust/compile/derive_macro4.rs
index 7802e8f..7429019 100644
--- a/gcc/testsuite/rust/compile/derive_macro4.rs
+++ b/gcc/testsuite/rust/compile/derive_macro4.rs
@@ -1,17 +1,18 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
+#[lang = "copy"]
pub trait Copy {}
+
+#[lang = "clone"]
pub trait Clone {
fn clone(&self) -> Self;
}
+#[lang = "phantom_data"]
struct PhantomData<T>;
-pub struct AssertParamIsCopy<T: Copy> {
- _field: PhantomData<T>,
-}
-
#[derive(Clone)] // { dg-error "bounds not satisfied for U .Copy. is not satisfied" }
union U {
i: i32,
diff --git a/gcc/testsuite/rust/compile/derive_macro6.rs b/gcc/testsuite/rust/compile/derive_macro6.rs
index b7bf7a7..d575ff1 100644
--- a/gcc/testsuite/rust/compile/derive_macro6.rs
+++ b/gcc/testsuite/rust/compile/derive_macro6.rs
@@ -1,7 +1,11 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
+#[lang = "copy"]
pub trait Copy {}
+
+#[lang = "clone"]
pub trait Clone {
fn clone(&self) -> Self;
}
@@ -9,10 +13,6 @@ pub trait Clone {
#[lang = "phantom_data"]
pub struct PhantomData<T>;
-pub struct AssertParamIsCopy<T: Copy> {
- pub _field: PhantomData<T>,
-}
-
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for U {}
diff --git a/gcc/testsuite/rust/compile/derive_partial_ord1.rs b/gcc/testsuite/rust/compile/derive_partial_ord1.rs
new file mode 100644
index 0000000..4d26de5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive_partial_ord1.rs
@@ -0,0 +1,464 @@
+// { dg-additional-options "-w" }
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+impl Eq for i32 {}
+
+#[derive(PartialEq, PartialOrd)]
+enum Foo {
+ A,
+ B(i32, i32, i32),
+ C { inner: i32, outer: i32 },
+}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct Bar {
+ a: i32,
+}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct BarFull {
+ a: i32,
+ b: i32,
+ c: i32,
+ d: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() {
+ let a = Foo::A;
+ let b = Foo::B(15, 14, 13);
+
+ match a.partial_cmp(&b) {
+ Option::Some(Ordering::Less) => print("less"),
+ Option::Some(Ordering::Greater) => print("greater"),
+ Option::Some(Ordering::Equal) => print("equal"),
+ _ => print("uuuuh woops lol"),
+ }
+}
diff --git a/gcc/testsuite/rust/compile/e0579-neg-float-fail.rs b/gcc/testsuite/rust/compile/e0579-neg-float-fail.rs
new file mode 100644
index 0000000..fefe221
--- /dev/null
+++ b/gcc/testsuite/rust/compile/e0579-neg-float-fail.rs
@@ -0,0 +1,9 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ let x = 1.0;
+
+ match x { // { dg-message "sorry, unimplemented: match on floating-point types is not yet supported" }
+ -1.0f32..-1.2f32 => 2, // { dg-error "lower range bound must be less than upper .E0579." }
+ };
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/e0579-neg-float.rs b/gcc/testsuite/rust/compile/e0579-neg-float.rs
new file mode 100644
index 0000000..cc60e80
--- /dev/null
+++ b/gcc/testsuite/rust/compile/e0579-neg-float.rs
@@ -0,0 +1,9 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ let x = 1.0;
+
+ match x { // { dg-message "sorry, unimplemented: match on floating-point types is not yet supported" }
+ -1.2f32..-1.0f32 => 2,
+ };
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/enum_discriminant1.rs b/gcc/testsuite/rust/compile/enum_discriminant1.rs
new file mode 100644
index 0000000..32092b2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_discriminant1.rs
@@ -0,0 +1,7 @@
+enum Foo {
+ Bar = 3 + 12,
+}
+
+fn test() -> Foo { // { dg-warning "function is never used" }
+ return Foo::Bar;
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/enum_discriminant2.rs b/gcc/testsuite/rust/compile/enum_discriminant2.rs
new file mode 100644
index 0000000..351dfbb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_discriminant2.rs
@@ -0,0 +1,9 @@
+fn test() -> isize {
+ 1
+}
+
+enum Foo {
+ Bar = test() // { dg-error "only functions marked as .const." }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/enum_discriminant3.rs b/gcc/testsuite/rust/compile/enum_discriminant3.rs
new file mode 100644
index 0000000..32c79a5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_discriminant3.rs
@@ -0,0 +1,8 @@
+const x: isize = 1;
+// { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+fn main() {
+ enum Foo {
+ Bar = x,
+ }
+}
diff --git a/gcc/testsuite/rust/compile/enum_variant_name.rs b/gcc/testsuite/rust/compile/enum_variant_name.rs
new file mode 100644
index 0000000..965acd1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_variant_name.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-w" }
+struct E1;
+
+enum Test {
+ E1 = {
+ let x = E1;
+ {
+ let x = E1;
+ }
+ 0
+ },
+}
diff --git a/gcc/testsuite/rust/compile/exhaustiveness1.rs b/gcc/testsuite/rust/compile/exhaustiveness1.rs
index fe95ea3..356636b 100644
--- a/gcc/testsuite/rust/compile/exhaustiveness1.rs
+++ b/gcc/testsuite/rust/compile/exhaustiveness1.rs
@@ -15,9 +15,7 @@ fn s2(s: S) {
}
fn s3(s: S) {
- match s {
- // { dg-error "non-exhaustive patterns: '_' not covered" "" { target *-*-* } .-1 }
- }
+ match s {}
}
enum E {
diff --git a/gcc/testsuite/rust/compile/expand_macro_qual_path_in_type.rs b/gcc/testsuite/rust/compile/expand_macro_qual_path_in_type.rs
index 2d60197..16d120f 100644
--- a/gcc/testsuite/rust/compile/expand_macro_qual_path_in_type.rs
+++ b/gcc/testsuite/rust/compile/expand_macro_qual_path_in_type.rs
@@ -1,5 +1,6 @@
// this SEGVs in lowering for now
// { dg-additional-options "-frust-compile-until=nameresolution" }
+#![feature(lang_items)]
macro_rules! forward_ref_binop {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
diff --git a/gcc/testsuite/rust/compile/expected_type_args2.rs b/gcc/testsuite/rust/compile/expected_type_args2.rs
index 11a70be..22702e3 100644
--- a/gcc/testsuite/rust/compile/expected_type_args2.rs
+++ b/gcc/testsuite/rust/compile/expected_type_args2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/expected_type_args3.rs b/gcc/testsuite/rust/compile/expected_type_args3.rs
index 7003f7a..0916ec9 100644
--- a/gcc/testsuite/rust/compile/expected_type_args3.rs
+++ b/gcc/testsuite/rust/compile/expected_type_args3.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/extern_generics.rs b/gcc/testsuite/rust/compile/extern_generics.rs
new file mode 100644
index 0000000..0312626
--- /dev/null
+++ b/gcc/testsuite/rust/compile/extern_generics.rs
@@ -0,0 +1,9 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+
+// E0044
+fn main() {
+extern "C" { fn some_func<T>(x: T); } // { dg-error "foreign items may not have type parameters .E0044." }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/extern_type_item_missing_semi.rs b/gcc/testsuite/rust/compile/extern_type_item_missing_semi.rs
index a42af02..cd4d4e2 100644
--- a/gcc/testsuite/rust/compile/extern_type_item_missing_semi.rs
+++ b/gcc/testsuite/rust/compile/extern_type_item_missing_semi.rs
@@ -4,4 +4,3 @@ extern "C" {
type F;
type E // { dg-error "failed to parse" }
} // { dg-error "expecting" }
-// { dg-error "failed to parse item in crate" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/feature.rs b/gcc/testsuite/rust/compile/feature.rs
index f743f92..6f428f0 100644
--- a/gcc/testsuite/rust/compile/feature.rs
+++ b/gcc/testsuite/rust/compile/feature.rs
@@ -2,5 +2,7 @@
#![feature(AA)] //{ dg-error "unknown feature .AA." }
#![feature(iamcrabby)] // { dg-error "unknown feature .iamcrabby." }
#![feature(nonexistent_gccrs_feature)] // { dg-error "unknown feature .nonexistent_gccrs_feature." }
+// ErrorCode - E0556
+#![feature] // { dg-error "malformed .feature. attribute input" }
fn main() {}
diff --git a/gcc/testsuite/rust/compile/feature_rust_attri0.rs b/gcc/testsuite/rust/compile/feature_rust_attri0.rs
index 9c11f56..1937acf 100644
--- a/gcc/testsuite/rust/compile/feature_rust_attri0.rs
+++ b/gcc/testsuite/rust/compile/feature_rust_attri0.rs
@@ -1,3 +1,7 @@
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
#[rustc_builtin_macro] //{ dg-error "internal implementation detail. " "" { target *-*-* } }
macro_rules! line {
() => {{}};
@@ -5,7 +9,7 @@ macro_rules! line {
fn main() -> i32 {
let a = line!();
- print(a);
+ printf("%d\0" as *const str as *const i8, a);
0
}
diff --git a/gcc/testsuite/rust/compile/for-loop1.rs b/gcc/testsuite/rust/compile/for-loop1.rs
new file mode 100644
index 0000000..d42cf67
--- /dev/null
+++ b/gcc/testsuite/rust/compile/for-loop1.rs
@@ -0,0 +1,543 @@
+// { dg-output "loop\r*\nloop\r*\n" }
+#![feature(intrinsics, lang_items)]
+
+pub use option::Option::{self, None, Some};
+pub use result::Result::{self, Err, Ok};
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+ fn puts(s: *const i8);
+}
+
+mod option {
+ pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+ }
+}
+
+mod result {
+ enum Result<T, E> {
+ Ok(T),
+ Err(E),
+ }
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+ fn clone(&self) -> Self;
+
+ fn clone_from(&mut self, source: &Self) {
+ *self = source.clone()
+ }
+}
+
+mod impls {
+ use super::Clone;
+
+ macro_rules! impl_clone {
+ ($($t:ty)*) => {
+ $(
+ impl Clone for $t {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ )*
+ }
+ }
+
+ impl_clone! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[lang = "copy"]
+pub trait Copy: Clone {
+ // Empty.
+}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ pub fn wrapping_sub<T>(a: T, b: T) -> T;
+ pub fn rotate_left<T>(a: T, b: T) -> T;
+ pub fn rotate_right<T>(a: T, b: T) -> T;
+ pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+ pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+ pub fn move_val_init<T>(dst: *mut T, src: T);
+ pub fn uninit<T>() -> T;
+ }
+}
+
+mod ptr {
+ #[lang = "const_ptr"]
+ impl<T> *const T {
+ pub unsafe fn offset(self, count: isize) -> *const T {
+ crate::intrinsics::offset(self, count)
+ }
+ }
+
+ #[lang = "mut_ptr"]
+ impl<T> *mut T {
+ pub unsafe fn offset(self, count: isize) -> *mut T {
+ crate::intrinsics::offset(self, count) as *mut T
+ }
+ }
+
+ pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
+ let x = x as *mut u8;
+ let y = y as *mut u8;
+ let len = crate::mem::size_of::<T>() * count;
+ swap_nonoverlapping_bytes(x, y, len)
+ }
+
+ pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
+ // For types smaller than the block optimization below,
+ // just swap directly to avoid pessimizing codegen.
+ if crate::mem::size_of::<T>() < 32 {
+ let z = read(x);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
+ write(y, z);
+ } else {
+ swap_nonoverlapping(x, y, 1);
+ }
+ }
+
+ pub unsafe fn write<T>(dst: *mut T, src: T) {
+ crate::intrinsics::move_val_init(&mut *dst, src)
+ }
+
+ pub unsafe fn read<T>(src: *const T) -> T {
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ tmp
+ }
+
+ pub unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
+ struct Block(u64, u64, u64, u64);
+ struct UnalignedBlock(u64, u64, u64, u64);
+
+ let block_size = crate::mem::size_of::<Block>();
+
+ // Loop through x & y, copying them `Block` at a time
+ // The optimizer should unroll the loop fully for most types
+ // N.B. We can't use a for loop as the `range` impl calls `mem::swap` recursively
+ let mut i: usize = 0;
+ while i + block_size <= len {
+ // Create some uninitialized memory as scratch space
+ // Declaring `t` here avoids aligning the stack when this loop is unused
+ let mut t: Block = crate::mem::uninitialized();
+ let t = &mut t as *mut _ as *mut u8;
+ let x = x.offset(i as isize);
+ let y = y.offset(i as isize);
+
+ // Swap a block of bytes of x & y, using t as a temporary buffer
+ // This should be optimized into efficient SIMD operations where available
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
+ i += block_size;
+ }
+
+ if i < len {
+ // Swap any remaining bytes
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
+ let rem = len - i;
+
+ let t = &mut t as *mut _ as *mut u8;
+ let x = x.offset(i as isize);
+ let y = y.offset(i as isize);
+
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
+ }
+ }
+}
+
+mod mem {
+ extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+ pub fn transmute<T, U>(_: T) -> U;
+ #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
+ pub fn size_of<T>() -> usize;
+ }
+
+ pub fn swap<T>(x: &mut T, y: &mut T) {
+ unsafe {
+ crate::ptr::swap_nonoverlapping_one(x, y);
+ }
+ }
+
+ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
+ swap(dest, &mut src);
+ src
+ }
+
+ pub unsafe fn uninitialized<T>() -> T {
+ crate::intrinsics::uninit()
+ }
+}
+
+macro_rules! impl_uint {
+ ($($ty:ident = $lang:literal),*) => {
+ $(
+ impl $ty {
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ unsafe {
+ crate::intrinsics::wrapping_add(self, rhs)
+ }
+ }
+
+ pub fn wrapping_sub(self, rhs: Self) -> Self {
+ unsafe {
+ crate::intrinsics::wrapping_sub(self, rhs)
+ }
+ }
+
+ pub fn rotate_left(self, n: u32) -> Self {
+ unsafe {
+ crate::intrinsics::rotate_left(self, n as Self)
+ }
+ }
+
+ pub fn rotate_right(self, n: u32) -> Self {
+ unsafe {
+ crate::intrinsics::rotate_right(self, n as Self)
+ }
+ }
+
+ pub fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ }
+
+ pub const fn from_le_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self {
+ Self::from_le(Self::from_ne_bytes(bytes))
+ }
+
+ pub const fn from_le(x: Self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ x
+ }
+ }
+
+ pub const fn from_ne_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self {
+ unsafe { crate::mem::transmute(bytes) }
+ }
+
+ pub fn checked_add(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_add(rhs);
+ if b {
+ Option::None
+ } else {
+ Option::Some(a)
+ }
+ }
+
+ pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe { crate::intrinsics::add_with_overflow(self as $ty, rhs as $ty) };
+ (a as Self, b)
+ }
+ }
+ )*
+ }
+}
+
+impl_uint!(
+ u8 = "u8",
+ u16 = "u16",
+ u32 = "u32",
+ u64 = "u64",
+ usize = "usize"
+);
+
+#[lang = "add"]
+pub trait Add<RHS = Self> {
+ type Output;
+
+ fn add(self, rhs: RHS) -> Self::Output;
+}
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ impl Add for $t {
+ type Output = $t;
+
+ fn add(self, other: $t) -> $t { self + other }
+ }
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 }
+
+#[lang = "sub"]
+pub trait Sub<RHS = Self> {
+ type Output;
+
+ fn sub(self, rhs: RHS) -> Self::Output;
+}
+macro_rules! sub_impl {
+ ($($t:ty)*) => ($(
+ impl Sub for $t {
+ type Output = $t;
+
+ fn sub(self, other: $t) -> $t { self - other }
+ }
+ )*)
+}
+
+sub_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 }
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+ pub start: Idx,
+ pub end: Idx,
+}
+
+pub trait TryFrom<T>: Sized {
+ /// The type returned in the event of a conversion error.
+ type Error;
+
+ /// Performs the conversion.
+ fn try_from(value: T) -> Result<Self, Self::Error>;
+}
+
+pub trait From<T>: Sized {
+ fn from(_: T) -> Self;
+}
+
+impl<T> From<T> for T {
+ fn from(t: T) -> T {
+ t
+ }
+}
+
+impl<T, U> TryFrom<U> for T
+where
+ T: From<U>,
+{
+ type Error = !;
+
+ fn try_from(value: U) -> Result<Self, Self::Error> {
+ Ok(T::from(value))
+ }
+}
+
+trait Step {
+ /// Returns the number of steps between two step objects. The count is
+ /// inclusive of `start` and exclusive of `end`.
+ ///
+ /// Returns `None` if it is not possible to calculate `steps_between`
+ /// without overflow.
+ fn steps_between(start: &Self, end: &Self) -> Option<usize>;
+
+ /// Replaces this step with `1`, returning itself
+ fn replace_one(&mut self) -> Self;
+
+ /// Replaces this step with `0`, returning itself
+ fn replace_zero(&mut self) -> Self;
+
+ /// Adds one to this step, returning the result
+ fn add_one(&self) -> Self;
+
+ /// Subtracts one to this step, returning the result
+ fn sub_one(&self) -> Self;
+
+ /// Add an usize, returning None on overflow
+ fn add_usize(&self, n: usize) -> Option<Self>;
+}
+
+// These are still macro-generated because the integer literals resolve to different types.
+macro_rules! step_identical_methods {
+ () => {
+ #[inline]
+ fn replace_one(&mut self) -> Self {
+ crate::mem::replace(self, 1)
+ }
+
+ #[inline]
+ fn replace_zero(&mut self) -> Self {
+ crate::mem::replace(self, 0)
+ }
+
+ #[inline]
+ fn add_one(&self) -> Self {
+ Add::add(*self, 1)
+ }
+
+ #[inline]
+ fn sub_one(&self) -> Self {
+ Sub::sub(*self, 1)
+ }
+ };
+}
+
+macro_rules! step_impl_unsigned {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
+ if *start < *end {
+ // Note: We assume $t <= usize here
+ Option::Some((*end - *start) as usize)
+ } else {
+ Option::Some(0)
+ }
+ }
+
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ match <$t>::try_from(n) {
+ Result::Ok(n_as_t) => self.checked_add(n_as_t),
+ Result::Err(_) => Option::None,
+ }
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+macro_rules! step_impl_signed {
+ ($( [$t:ty : $unsigned:ty] )*) => ($(
+ impl Step for $t {
+ #[inline]
+ #[allow(trivial_numeric_casts)]
+ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
+ if *start < *end {
+ // Note: We assume $t <= isize here
+ // Use .wrapping_sub and cast to usize to compute the
+ // difference that may not fit inside the range of isize.
+ Option::Some((*end as isize).wrapping_sub(*start as isize) as usize)
+ } else {
+ Option::Some(0)
+ }
+ }
+
+ #[inline]
+ #[allow(unreachable_patterns)]
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ match <$unsigned>::try_from(n) {
+ Result::Ok(n_as_unsigned) => {
+ // Wrapping in unsigned space handles cases like
+ // `-120_i8.add_usize(200) == Option::Some(80_i8)`,
+ // even though 200_usize is out of range for i8.
+ let wrapped = (*self as $unsigned).wrapping_add(n_as_unsigned) as $t;
+ if wrapped >= *self {
+ Option::Some(wrapped)
+ } else {
+ Option::None // Addition overflowed
+ }
+ }
+ Result::Err(_) => Option::None,
+ }
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+
+macro_rules! step_impl_no_between {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ #[inline]
+ fn steps_between(_start: &Self, _end: &Self) -> Option<usize> {
+ Option::None
+ }
+
+ #[inline]
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ self.checked_add(n as $t)
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+
+step_impl_unsigned!(usize);
+
+pub trait Iterator {
+ type Item;
+
+ #[lang = "next"]
+ fn next(&mut self) -> Option<Self::Item>;
+}
+
+impl<A: Step> Iterator for Range<A> {
+ type Item = A;
+
+ fn next(&mut self) -> Option<A> {
+ if self.start < self.end {
+ // We check for overflow here, even though it can't actually
+ // happen. Adding this check does however help llvm vectorize loops
+ // for some ranges that don't get vectorized otherwise,
+ // and this won't actually result in an extra check in an optimized build.
+ match self.start.add_usize(1) {
+ Option::Some(mut n) => {
+ crate::mem::swap(&mut n, &mut self.start);
+ Option::Some(n)
+ }
+ Option::None => Option::None,
+ }
+ } else {
+ Option::None
+ }
+ }
+}
+
+pub trait IntoIterator {
+ type Item;
+
+ type IntoIter: Iterator<Item = Self::Item>;
+
+ #[lang = "into_iter"]
+ fn into_iter(self) -> Self::IntoIter;
+}
+
+impl<I: Iterator> IntoIterator for I {
+ type Item = I::Item;
+ type IntoIter = I;
+
+ fn into_iter(self) -> I {
+ self
+ }
+}
+
+pub fn main() {
+ let a = 1usize..3usize;
+
+ for i in a { // { dg-warning "unused name" }
+ unsafe { puts("loop\0" as *const str as *const i8); }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/for-loop2.rs b/gcc/testsuite/rust/compile/for-loop2.rs
new file mode 100644
index 0000000..680fd86
--- /dev/null
+++ b/gcc/testsuite/rust/compile/for-loop2.rs
@@ -0,0 +1,547 @@
+// { dg-output "1\r*\n2\r*\n" }
+#![feature(intrinsics, lang_items)]
+
+pub use option::Option::{self, None, Some};
+pub use result::Result::{self, Err, Ok};
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+ fn puts(s: *const i8);
+}
+
+mod option {
+ pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+ }
+}
+
+mod result {
+ enum Result<T, E> {
+ Ok(T),
+ Err(E),
+ }
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+ fn clone(&self) -> Self;
+
+ fn clone_from(&mut self, source: &Self) {
+ *self = source.clone()
+ }
+}
+
+mod impls {
+ use super::Clone;
+
+ macro_rules! impl_clone {
+ ($($t:ty)*) => {
+ $(
+ impl Clone for $t {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ )*
+ }
+ }
+
+ impl_clone! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[lang = "copy"]
+pub trait Copy: Clone {
+ // Empty.
+}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ pub fn wrapping_sub<T>(a: T, b: T) -> T;
+ pub fn rotate_left<T>(a: T, b: T) -> T;
+ pub fn rotate_right<T>(a: T, b: T) -> T;
+ pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+ pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+ pub fn move_val_init<T>(dst: *mut T, src: T);
+ pub fn uninit<T>() -> T;
+ }
+}
+
+mod ptr {
+ #[lang = "const_ptr"]
+ impl<T> *const T {
+ pub unsafe fn offset(self, count: isize) -> *const T {
+ crate::intrinsics::offset(self, count)
+ }
+ }
+
+ #[lang = "mut_ptr"]
+ impl<T> *mut T {
+ pub unsafe fn offset(self, count: isize) -> *mut T {
+ crate::intrinsics::offset(self, count) as *mut T
+ }
+ }
+
+ pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
+ let x = x as *mut u8;
+ let y = y as *mut u8;
+ let len = crate::mem::size_of::<T>() * count;
+ swap_nonoverlapping_bytes(x, y, len)
+ }
+
+ pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
+ // For types smaller than the block optimization below,
+ // just swap directly to avoid pessimizing codegen.
+ if crate::mem::size_of::<T>() < 32 {
+ let z = read(x);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
+ write(y, z);
+ } else {
+ swap_nonoverlapping(x, y, 1);
+ }
+ }
+
+ pub unsafe fn write<T>(dst: *mut T, src: T) {
+ crate::intrinsics::move_val_init(&mut *dst, src)
+ }
+
+ pub unsafe fn read<T>(src: *const T) -> T {
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ tmp
+ }
+
+ pub unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
+ struct Block(u64, u64, u64, u64);
+ struct UnalignedBlock(u64, u64, u64, u64);
+
+ let block_size = crate::mem::size_of::<Block>();
+
+ // Loop through x & y, copying them `Block` at a time
+ // The optimizer should unroll the loop fully for most types
+ // N.B. We can't use a for loop as the `range` impl calls `mem::swap` recursively
+ let mut i: usize = 0;
+ while i + block_size <= len {
+ // Create some uninitialized memory as scratch space
+ // Declaring `t` here avoids aligning the stack when this loop is unused
+ let mut t: Block = crate::mem::uninitialized();
+ let t = &mut t as *mut _ as *mut u8;
+ let x = x.offset(i as isize);
+ let y = y.offset(i as isize);
+
+ // Swap a block of bytes of x & y, using t as a temporary buffer
+ // This should be optimized into efficient SIMD operations where available
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
+ i += block_size;
+ }
+
+ if i < len {
+ // Swap any remaining bytes
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
+ let rem = len - i;
+
+ let t = &mut t as *mut _ as *mut u8;
+ let x = x.offset(i as isize);
+ let y = y.offset(i as isize);
+
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
+ }
+ }
+}
+
+mod mem {
+ extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+ pub fn transmute<T, U>(_: T) -> U;
+ #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
+ pub fn size_of<T>() -> usize;
+ }
+
+ pub fn swap<T>(x: &mut T, y: &mut T) {
+ unsafe {
+ crate::ptr::swap_nonoverlapping_one(x, y);
+ }
+ }
+
+ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
+ swap(dest, &mut src);
+ src
+ }
+
+ pub unsafe fn uninitialized<T>() -> T {
+ crate::intrinsics::uninit()
+ }
+}
+
+macro_rules! impl_uint {
+ ($($ty:ident = $lang:literal),*) => {
+ $(
+ impl $ty {
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ unsafe {
+ crate::intrinsics::wrapping_add(self, rhs)
+ }
+ }
+
+ pub fn wrapping_sub(self, rhs: Self) -> Self {
+ unsafe {
+ crate::intrinsics::wrapping_sub(self, rhs)
+ }
+ }
+
+ pub fn rotate_left(self, n: u32) -> Self {
+ unsafe {
+ crate::intrinsics::rotate_left(self, n as Self)
+ }
+ }
+
+ pub fn rotate_right(self, n: u32) -> Self {
+ unsafe {
+ crate::intrinsics::rotate_right(self, n as Self)
+ }
+ }
+
+ pub fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ }
+
+ pub const fn from_le_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self {
+ Self::from_le(Self::from_ne_bytes(bytes))
+ }
+
+ pub const fn from_le(x: Self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ x
+ }
+ }
+
+ pub const fn from_ne_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self {
+ unsafe { crate::mem::transmute(bytes) }
+ }
+
+ pub fn checked_add(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_add(rhs);
+ if b {
+ Option::None
+ } else {
+ Option::Some(a)
+ }
+ }
+
+ pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe { crate::intrinsics::add_with_overflow(self as $ty, rhs as $ty) };
+ (a as Self, b)
+ }
+ }
+ )*
+ }
+}
+
+impl_uint!(
+ u8 = "u8",
+ u16 = "u16",
+ u32 = "u32",
+ u64 = "u64",
+ usize = "usize"
+);
+
+#[lang = "add"]
+pub trait Add<RHS = Self> {
+ type Output;
+
+ fn add(self, rhs: RHS) -> Self::Output;
+}
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ impl Add for $t {
+ type Output = $t;
+
+ fn add(self, other: $t) -> $t { self + other }
+ }
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 }
+
+#[lang = "sub"]
+pub trait Sub<RHS = Self> {
+ type Output;
+
+ fn sub(self, rhs: RHS) -> Self::Output;
+}
+macro_rules! sub_impl {
+ ($($t:ty)*) => ($(
+ impl Sub for $t {
+ type Output = $t;
+
+ fn sub(self, other: $t) -> $t { self - other }
+ }
+ )*)
+}
+
+sub_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 }
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+ pub start: Idx,
+ pub end: Idx,
+}
+
+pub trait TryFrom<T>: Sized {
+ /// The type returned in the event of a conversion error.
+ type Error;
+
+ /// Performs the conversion.
+ fn try_from(value: T) -> Result<Self, Self::Error>;
+}
+
+pub trait From<T>: Sized {
+ fn from(_: T) -> Self;
+}
+
+impl<T> From<T> for T {
+ fn from(t: T) -> T {
+ t
+ }
+}
+
+impl<T, U> TryFrom<U> for T
+where
+ T: From<U>,
+{
+ type Error = !;
+
+ fn try_from(value: U) -> Result<Self, Self::Error> {
+ Ok(T::from(value))
+ }
+}
+
+trait Step {
+ /// Returns the number of steps between two step objects. The count is
+ /// inclusive of `start` and exclusive of `end`.
+ ///
+ /// Returns `None` if it is not possible to calculate `steps_between`
+ /// without overflow.
+ fn steps_between(start: &Self, end: &Self) -> Option<usize>;
+
+ /// Replaces this step with `1`, returning itself
+ fn replace_one(&mut self) -> Self;
+
+ /// Replaces this step with `0`, returning itself
+ fn replace_zero(&mut self) -> Self;
+
+ /// Adds one to this step, returning the result
+ fn add_one(&self) -> Self;
+
+ /// Subtracts one to this step, returning the result
+ fn sub_one(&self) -> Self;
+
+ /// Add an usize, returning None on overflow
+ fn add_usize(&self, n: usize) -> Option<Self>;
+}
+
+// These are still macro-generated because the integer literals resolve to different types.
+macro_rules! step_identical_methods {
+ () => {
+ #[inline]
+ fn replace_one(&mut self) -> Self {
+ crate::mem::replace(self, 1)
+ }
+
+ #[inline]
+ fn replace_zero(&mut self) -> Self {
+ crate::mem::replace(self, 0)
+ }
+
+ #[inline]
+ fn add_one(&self) -> Self {
+ Add::add(*self, 1)
+ }
+
+ #[inline]
+ fn sub_one(&self) -> Self {
+ Sub::sub(*self, 1)
+ }
+ };
+}
+
+macro_rules! step_impl_unsigned {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
+ if *start < *end {
+ // Note: We assume $t <= usize here
+ Option::Some((*end - *start) as usize)
+ } else {
+ Option::Some(0)
+ }
+ }
+
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ match <$t>::try_from(n) {
+ Result::Ok(n_as_t) => self.checked_add(n_as_t),
+ Result::Err(_) => Option::None,
+ }
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+macro_rules! step_impl_signed {
+ ($( [$t:ty : $unsigned:ty] )*) => ($(
+ impl Step for $t {
+ #[inline]
+ #[allow(trivial_numeric_casts)]
+ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
+ if *start < *end {
+ // Note: We assume $t <= isize here
+ // Use .wrapping_sub and cast to usize to compute the
+ // difference that may not fit inside the range of isize.
+ Option::Some((*end as isize).wrapping_sub(*start as isize) as usize)
+ } else {
+ Option::Some(0)
+ }
+ }
+
+ #[inline]
+ #[allow(unreachable_patterns)]
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ match <$unsigned>::try_from(n) {
+ Result::Ok(n_as_unsigned) => {
+ // Wrapping in unsigned space handles cases like
+ // `-120_i8.add_usize(200) == Option::Some(80_i8)`,
+ // even though 200_usize is out of range for i8.
+ let wrapped = (*self as $unsigned).wrapping_add(n_as_unsigned) as $t;
+ if wrapped >= *self {
+ Option::Some(wrapped)
+ } else {
+ Option::None // Addition overflowed
+ }
+ }
+ Result::Err(_) => Option::None,
+ }
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+
+macro_rules! step_impl_no_between {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ #[inline]
+ fn steps_between(_start: &Self, _end: &Self) -> Option<usize> {
+ Option::None
+ }
+
+ #[inline]
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ self.checked_add(n as $t)
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+
+step_impl_unsigned!(usize);
+
+pub trait Iterator {
+ type Item;
+
+ #[lang = "next"]
+ fn next(&mut self) -> Option<Self::Item>;
+}
+
+impl<A: Step> Iterator for Range<A> {
+ type Item = A;
+
+ fn next(&mut self) -> Option<A> {
+ if self.start < self.end {
+ // We check for overflow here, even though it can't actually
+ // happen. Adding this check does however help llvm vectorize loops
+ // for some ranges that don't get vectorized otherwise,
+ // and this won't actually result in an extra check in an optimized build.
+ match self.start.add_usize(1) {
+ Option::Some(mut n) => {
+ crate::mem::swap(&mut n, &mut self.start);
+ Option::Some(n)
+ }
+ Option::None => Option::None,
+ }
+ } else {
+ Option::None
+ }
+ }
+}
+
+pub trait IntoIterator {
+ type Item;
+
+ type IntoIter: Iterator<Item = Self::Item>;
+
+ #[lang = "into_iter"]
+ fn into_iter(self) -> Self::IntoIter;
+}
+
+impl<I: Iterator> IntoIterator for I {
+ type Item = I::Item;
+ type IntoIter = I;
+
+ fn into_iter(self) -> I {
+ self
+ }
+}
+
+pub fn main() {
+ // make sure we can desugar for-loops inside other blocks
+
+ if true {
+ for _ in 20usize..40usize {
+ unsafe {
+ puts("loop\0" as *const str as *const i8);
+ }
+ }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/format_args_basic_expansion.rs b/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
index 40bcd3c..59101ac 100644
--- a/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
+++ b/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
@@ -1,4 +1,4 @@
-#![feature(rustc_attrs)]
+#![feature(rustc_attrs, lang_items)]
#[rustc_builtin_macro]
macro_rules! format_args {
@@ -35,7 +35,6 @@ pub mod core {
impl Display for i32 {
fn fmt(&self, _: &mut Formatter) -> Result {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
Result
}
}
diff --git a/gcc/testsuite/rust/compile/format_args_concat.rs b/gcc/testsuite/rust/compile/format_args_concat.rs
new file mode 100644
index 0000000..695cde65
--- /dev/null
+++ b/gcc/testsuite/rust/compile/format_args_concat.rs
@@ -0,0 +1,51 @@
+#![feature(rustc_attrs, lang_items)]
+
+#[rustc_builtin_macro]
+macro_rules! format_args {
+ () => {};
+}
+
+#[rustc_builtin_macro]
+macro_rules! concat {
+ () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod fmt {
+ pub struct Formatter;
+ pub struct Result;
+
+ pub struct Arguments<'a>;
+
+ impl<'a> Arguments<'a> {
+ pub fn new_v1(_: &'a [&'static str], _: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
+ Arguments
+ }
+ }
+
+ pub struct ArgumentV1<'a>;
+
+ impl<'a> ArgumentV1<'a> {
+ pub fn new<'b, T>(_: &'b T, _: fn(&T, &mut Formatter) -> Result) -> ArgumentV1 {
+ ArgumentV1
+ }
+ }
+
+ pub trait Display {
+ fn fmt(&self, _: &mut Formatter) -> Result;
+ }
+
+ impl Display for i32 {
+ fn fmt(&self, _: &mut Formatter) -> Result {
+ Result
+ }
+ }
+ }
+}
+
+fn main() {
+ let _formatted = format_args!(concat!("hello ", "{}"), 15);
+}
diff --git a/gcc/testsuite/rust/compile/format_args_extra_comma.rs b/gcc/testsuite/rust/compile/format_args_extra_comma.rs
new file mode 100644
index 0000000..5b8fee5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/format_args_extra_comma.rs
@@ -0,0 +1,46 @@
+#![feature(rustc_attrs, lang_items)]
+
+#[rustc_builtin_macro]
+macro_rules! format_args {
+ () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod fmt {
+ pub struct Formatter;
+ pub struct Result;
+
+ pub struct Arguments<'a>;
+
+ impl<'a> Arguments<'a> {
+ pub fn new_v1(_: &'a [&'static str], _: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
+ Arguments
+ }
+ }
+
+ pub struct ArgumentV1<'a>;
+
+ impl<'a> ArgumentV1<'a> {
+ pub fn new<'b, T>(_: &'b T, _: fn(&T, &mut Formatter) -> Result) -> ArgumentV1 {
+ ArgumentV1
+ }
+ }
+
+ pub trait Display {
+ fn fmt(&self, _: &mut Formatter) -> Result;
+ }
+
+ impl Display for i32 {
+ fn fmt(&self, _: &mut Formatter) -> Result {
+ Result
+ }
+ }
+ }
+}
+
+fn main() {
+ let _formatted = format_args!("extra commas {} {}", 15, 14,);
+}
diff --git a/gcc/testsuite/rust/compile/gat1.rs b/gcc/testsuite/rust/compile/gat1.rs
new file mode 100644
index 0000000..032f64e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/gat1.rs
@@ -0,0 +1,4 @@
+trait Foo {
+ type Bar<T>;
+ type Baz<'a>;
+}
diff --git a/gcc/testsuite/rust/compile/generic-default1.rs b/gcc/testsuite/rust/compile/generic-default1.rs
index 0a132bf..4155640 100644
--- a/gcc/testsuite/rust/compile/generic-default1.rs
+++ b/gcc/testsuite/rust/compile/generic-default1.rs
@@ -1,5 +1,5 @@
struct Foo<A = i321>(A);
-// { dg-error "failed to resolve TypePath: i321" "" { target *-*-* } .-1 }
+// { dg-error "could not resolve type path .i321." "" { target *-*-* } .-1 }
fn main() {
let a;
diff --git a/gcc/testsuite/rust/compile/generics1.rs b/gcc/testsuite/rust/compile/generics1.rs
index 9e440af..cf3c9e4 100644
--- a/gcc/testsuite/rust/compile/generics1.rs
+++ b/gcc/testsuite/rust/compile/generics1.rs
@@ -1,5 +1,6 @@
// { dg-error "mismatched types, expected .i32. but got .i8." "" { target *-*-* } 0 }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/generics11.rs b/gcc/testsuite/rust/compile/generics11.rs
index 10b5880..7202baf 100644
--- a/gcc/testsuite/rust/compile/generics11.rs
+++ b/gcc/testsuite/rust/compile/generics11.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/generics12.rs b/gcc/testsuite/rust/compile/generics12.rs
index b32f566..21613fb 100644
--- a/gcc/testsuite/rust/compile/generics12.rs
+++ b/gcc/testsuite/rust/compile/generics12.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/generics14.rs b/gcc/testsuite/rust/compile/generics14.rs
new file mode 100644
index 0000000..d97fd35
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics14.rs
@@ -0,0 +1 @@
+struct Foo<const N: i32, 'a>; // { dg-error "invalid order for generic parameters: lifetime parameters must be declared prior to type and const parameters" }
diff --git a/gcc/testsuite/rust/compile/generics2.rs b/gcc/testsuite/rust/compile/generics2.rs
index 4c95fd1..0ed8a5f 100644
--- a/gcc/testsuite/rust/compile/generics2.rs
+++ b/gcc/testsuite/rust/compile/generics2.rs
@@ -1,5 +1,6 @@
// { dg-error "mismatched types, expected .i32. but got .i8." "" { target *-*-* } 0 }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/generics3.rs b/gcc/testsuite/rust/compile/generics3.rs
index 514d713..112a247 100644
--- a/gcc/testsuite/rust/compile/generics3.rs
+++ b/gcc/testsuite/rust/compile/generics3.rs
@@ -1,4 +1,5 @@
// { dg-error "mismatched types, expected .i32. but got .i8." "" { target *-*-* } 0 }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/generics4.rs b/gcc/testsuite/rust/compile/generics4.rs
index 31b681a..e8333d6 100644
--- a/gcc/testsuite/rust/compile/generics4.rs
+++ b/gcc/testsuite/rust/compile/generics4.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -6,7 +7,6 @@ struct GenericStruct<T>(T, usize);
fn main() {
let a2;
a2 = GenericStruct::<i8, i32>(1, 456); // { dg-error "generic item takes at most 1 type arguments but 2 were supplied" }
- // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-1 }
let b2: i32 = a2.0;
// { dg-error {Expected Tuple or ADT got: T\?} "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/generics5.rs b/gcc/testsuite/rust/compile/generics5.rs
index 6c847b5..f861038 100644
--- a/gcc/testsuite/rust/compile/generics5.rs
+++ b/gcc/testsuite/rust/compile/generics5.rs
@@ -3,7 +3,7 @@ struct GenericStruct<T>(T, usize);
fn main() {
let a2;
a2 = GenericStruct::<i8, T>(1, 456);
- // { dg-error "failed to resolve TypePath: T" "" { target *-*-* } .-1 }
+ // { dg-error "could not resolve type path .T." "" { target *-*-* } .-1 }
let b2: i32 = a2.0;
let c2: usize = a2.1;
diff --git a/gcc/testsuite/rust/compile/generics6.rs b/gcc/testsuite/rust/compile/generics6.rs
index 33093cf..67029cd0 100644
--- a/gcc/testsuite/rust/compile/generics6.rs
+++ b/gcc/testsuite/rust/compile/generics6.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -27,6 +28,5 @@ impl Foo<f32> {
fn main() {
let a: i32 = Foo::test(); // { dg-error "multiple applicable items in scope for: .test." }
- // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/generics7.rs b/gcc/testsuite/rust/compile/generics7.rs
index dcedead..e2283a4 100644
--- a/gcc/testsuite/rust/compile/generics7.rs
+++ b/gcc/testsuite/rust/compile/generics7.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/generics8.rs b/gcc/testsuite/rust/compile/generics8.rs
index 88c4bac..b38b277 100644
--- a/gcc/testsuite/rust/compile/generics8.rs
+++ b/gcc/testsuite/rust/compile/generics8.rs
@@ -1,10 +1,11 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
struct Foo<A, B>(A, B);
impl<T> Foo<i32, T> {
- fn test(a: T) -> T {
+ fn test(a: T) -> T { // { dg-error "duplicate definitions with name .test." }
a
}
}
diff --git a/gcc/testsuite/rust/compile/generics9.rs b/gcc/testsuite/rust/compile/generics9.rs
index 3766703..949fbb1 100644
--- a/gcc/testsuite/rust/compile/generics9.rs
+++ b/gcc/testsuite/rust/compile/generics9.rs
@@ -1,5 +1,5 @@
struct Foo<A, B = (A, B)>(A, B);
-// { dg-error "failed to resolve TypePath: B" "" { target *-*-* } .-1 }
+// { dg-error "type parameters with a default cannot use forward declared identifiers" "" { target *-*-* } .-1 }
fn main() {
let a: Foo<bool>;
diff --git a/gcc/testsuite/rust/compile/glob_import_enum.rs b/gcc/testsuite/rust/compile/glob_import_enum.rs
new file mode 100644
index 0000000..032a1db
--- /dev/null
+++ b/gcc/testsuite/rust/compile/glob_import_enum.rs
@@ -0,0 +1,16 @@
+use self::Ordering::*;
+use Ordering::*;
+
+enum Ordering {
+ A,
+ B,
+}
+
+fn foo(_: Ordering) {}
+
+fn main() {
+ let a = A;
+
+ foo(a);
+ foo(B);
+}
diff --git a/gcc/testsuite/rust/compile/global-path-array.rs b/gcc/testsuite/rust/compile/global-path-array.rs
new file mode 100644
index 0000000..c3aa024
--- /dev/null
+++ b/gcc/testsuite/rust/compile/global-path-array.rs
@@ -0,0 +1,5 @@
+const X: i32 = 1;
+
+pub fn foo() -> [i32; 1] {
+ [::X]
+}
diff --git a/gcc/testsuite/rust/compile/if-without-else.rs b/gcc/testsuite/rust/compile/if-without-else.rs
new file mode 100644
index 0000000..1a0f644
--- /dev/null
+++ b/gcc/testsuite/rust/compile/if-without-else.rs
@@ -0,0 +1,9 @@
+fn foo(pred: bool) -> u8 {
+ if pred { // { dg-error "mismatched types" }
+ 1
+ }
+ 3
+}
+
+fn main(){
+}
diff --git a/gcc/testsuite/rust/compile/if_let_expr.rs b/gcc/testsuite/rust/compile/if_let_expr.rs
index 7bab19a..407abd4 100644
--- a/gcc/testsuite/rust/compile/if_let_expr.rs
+++ b/gcc/testsuite/rust/compile/if_let_expr.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -7,8 +8,9 @@ pub enum Option<T> {
}
fn main() {
- let x = Option::Some(3); // { dg-warning "unused name" }
- let a = if let Option::Some(1) = x {
+ let x = Option::Some(3);
+
+ let a = if let Option::Some(1) = x {// { dg-warning "unused name" }
1
} else if x == Option::Some(2) {
2
diff --git a/gcc/testsuite/rust/compile/if_let_expr_simple.rs b/gcc/testsuite/rust/compile/if_let_expr_simple.rs
new file mode 100644
index 0000000..d7fb0af
--- /dev/null
+++ b/gcc/testsuite/rust/compile/if_let_expr_simple.rs
@@ -0,0 +1,12 @@
+enum MyOption {
+ Some(i32),
+ None,
+}
+
+pub fn toto(i : MyOption) -> i32 {
+ if let MyOption::Some(v) = i {
+ v
+ } else {
+ 23i32
+ }
+}
diff --git a/gcc/testsuite/rust/compile/iflet.rs b/gcc/testsuite/rust/compile/iflet.rs
new file mode 100644
index 0000000..6d46339
--- /dev/null
+++ b/gcc/testsuite/rust/compile/iflet.rs
@@ -0,0 +1,32 @@
+pub fn simple_iflet() -> i32 {
+ let mut res = 0;
+
+ enum E {
+ X(i32),
+ }
+ let v = E::X(4);
+
+ if let E::X(n) = v {
+ res = 1;
+ }
+
+ res
+}
+
+pub fn simple_iflet_else() -> i32 {
+ let mut res = 0;
+
+ enum E {
+ X(i32),
+ Y,
+ }
+ let v = E::X(4);
+
+ if let E::Y = v {
+ res = 1;
+ } else {
+ res = 2;
+ }
+
+ res
+}
diff --git a/gcc/testsuite/rust/compile/impl_fnptr.rs b/gcc/testsuite/rust/compile/impl_fnptr.rs
new file mode 100644
index 0000000..e7c1bb1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/impl_fnptr.rs
@@ -0,0 +1,19 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+impl<Ret> PartialEq for extern "C" fn() -> Ret {
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ *self as usize == *other as usize
+ }
+}
diff --git a/gcc/testsuite/rust/compile/impl_trait_diag.rs b/gcc/testsuite/rust/compile/impl_trait_diag.rs
new file mode 100644
index 0000000..e78d2f5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/impl_trait_diag.rs
@@ -0,0 +1,18 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+trait Foo {
+ fn method(&self);
+}
+
+struct Bar;
+impl Foo for Bar {}
+
+fn main() {
+ let x: impl Foo = Bar; // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+
+ struct Wrapper {
+ field: impl Foo, // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs b/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs
new file mode 100644
index 0000000..a304bd6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs
@@ -0,0 +1,26 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> u8;
+}
+
+struct Bar;
+
+impl Foo for Bar {
+ fn id(&self) -> u8 {
+ 1
+ }
+}
+
+fn takes(val: impl Foo) -> u8 {
+ val.id()
+}
+
+fn main() {
+ let b = Bar;
+ let x = takes::<Bar>(b);
+ // { dg-error "cannot provide explicit generic arguments when .impl Trait. is used in argument position .E0632." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/implicit_returns_err3.rs b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
index ac98213..f0330ac 100644
--- a/gcc/testsuite/rust/compile/implicit_returns_err3.rs
+++ b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
@@ -1,6 +1,6 @@
fn test(x: i32) -> i32 { // { dg-error "mismatched types, expected .i32. but got ...." }
if x > 1 {
- 1
+ return 1;
}
}
diff --git a/gcc/testsuite/rust/compile/import_wildcards.rs b/gcc/testsuite/rust/compile/import_wildcards.rs
new file mode 100644
index 0000000..3fc3658
--- /dev/null
+++ b/gcc/testsuite/rust/compile/import_wildcards.rs
@@ -0,0 +1,8 @@
+mod x {}
+
+mod y {}
+
+fn main() {
+ use x as _;
+ use y as _;
+}
diff --git a/gcc/testsuite/rust/compile/invalid_label_name.rs b/gcc/testsuite/rust/compile/invalid_label_name.rs
index 5c850da..d1c5a33 100644
--- a/gcc/testsuite/rust/compile/invalid_label_name.rs
+++ b/gcc/testsuite/rust/compile/invalid_label_name.rs
@@ -3,18 +3,21 @@ pub fn function() {
// { dg-error "invalid label name .'continue." "" { target *-*-* } .-1 }
break 'extern;
// { dg-error "invalid label name .'extern." "" { target *-*-* } .-1 }
+ // { dg-error "use of undeclared label .'extern." "" { target *-*-* } .-2 }
}
'break: loop {
// { dg-error "invalid label name .'break." "" { target *-*-* } .-1 }
break 'for;
// { dg-error "invalid label name .'for." "" { target *-*-* } .-1 }
+ // { dg-error "use of undeclared label .'for." "" { target *-*-* } .-2 }
}
'crate: loop {
// { dg-error "invalid label name .'crate." "" { target *-*-* } .-1 }
break 'loop;
// { dg-error "invalid label name .'loop." "" { target *-*-* } .-1 }
+ // { dg-error "use of undeclared label .'loop." "" { target *-*-* } .-2 }
}
'a: loop {
diff --git a/gcc/testsuite/rust/compile/issue-1005.rs b/gcc/testsuite/rust/compile/issue-1005.rs
index 15d4bef..4c51b30 100644
--- a/gcc/testsuite/rust/compile/issue-1005.rs
+++ b/gcc/testsuite/rust/compile/issue-1005.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1019.rs b/gcc/testsuite/rust/compile/issue-1019.rs
index 1f77ba9..5bf786c5 100644
--- a/gcc/testsuite/rust/compile/issue-1019.rs
+++ b/gcc/testsuite/rust/compile/issue-1019.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1031.rs b/gcc/testsuite/rust/compile/issue-1031.rs
index cd1da47..785573a 100644
--- a/gcc/testsuite/rust/compile/issue-1031.rs
+++ b/gcc/testsuite/rust/compile/issue-1031.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1034.rs b/gcc/testsuite/rust/compile/issue-1034.rs
index d40005e..ef5f7c7 100644
--- a/gcc/testsuite/rust/compile/issue-1034.rs
+++ b/gcc/testsuite/rust/compile/issue-1034.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1048.rs b/gcc/testsuite/rust/compile/issue-1048.rs
new file mode 100644
index 0000000..8d4053a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1048.rs
@@ -0,0 +1,8 @@
+macro_rules! maybe_return { ($e:expr) => ($e); }
+
+fn frob(x: i32) -> i32{
+ maybe_return! {x}
+ // { dg-error "mismatched types. expected .... but got .i32. .E0308." "" { target *-*-* } .-1 }
+ // should return -1
+ -1
+}
diff --git a/gcc/testsuite/rust/compile/issue-1128.rs b/gcc/testsuite/rust/compile/issue-1128.rs
index 8960ebb..de46919 100644
--- a/gcc/testsuite/rust/compile/issue-1128.rs
+++ b/gcc/testsuite/rust/compile/issue-1128.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1129-2.rs b/gcc/testsuite/rust/compile/issue-1129-2.rs
index cfe01b5..4b4f004 100644
--- a/gcc/testsuite/rust/compile/issue-1129-2.rs
+++ b/gcc/testsuite/rust/compile/issue-1129-2.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1130.rs b/gcc/testsuite/rust/compile/issue-1130.rs
index 115e6aa..0219ed2 100644
--- a/gcc/testsuite/rust/compile/issue-1130.rs
+++ b/gcc/testsuite/rust/compile/issue-1130.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1131.rs b/gcc/testsuite/rust/compile/issue-1131.rs
index 86eeb98..c014e73 100644
--- a/gcc/testsuite/rust/compile/issue-1131.rs
+++ b/gcc/testsuite/rust/compile/issue-1131.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1165.rs b/gcc/testsuite/rust/compile/issue-1165.rs
index a637823..ce57ebf 100644
--- a/gcc/testsuite/rust/compile/issue-1165.rs
+++ b/gcc/testsuite/rust/compile/issue-1165.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1173.rs b/gcc/testsuite/rust/compile/issue-1173.rs
index a8fd93e..59b0adf 100644
--- a/gcc/testsuite/rust/compile/issue-1173.rs
+++ b/gcc/testsuite/rust/compile/issue-1173.rs
@@ -2,6 +2,7 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1235.rs b/gcc/testsuite/rust/compile/issue-1235.rs
index 7c85ac4..6376e9e 100644
--- a/gcc/testsuite/rust/compile/issue-1235.rs
+++ b/gcc/testsuite/rust/compile/issue-1235.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1237.rs b/gcc/testsuite/rust/compile/issue-1237.rs
index 79b60b0..506a6bf 100644
--- a/gcc/testsuite/rust/compile/issue-1237.rs
+++ b/gcc/testsuite/rust/compile/issue-1237.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1289.rs b/gcc/testsuite/rust/compile/issue-1289.rs
index 9251d79..58ab0b6 100644
--- a/gcc/testsuite/rust/compile/issue-1289.rs
+++ b/gcc/testsuite/rust/compile/issue-1289.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1383.rs b/gcc/testsuite/rust/compile/issue-1383.rs
index dac4b2a..f8ccd57 100644
--- a/gcc/testsuite/rust/compile/issue-1383.rs
+++ b/gcc/testsuite/rust/compile/issue-1383.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1446.rs b/gcc/testsuite/rust/compile/issue-1446.rs
index 8bfa42b..969ad38 100644
--- a/gcc/testsuite/rust/compile/issue-1446.rs
+++ b/gcc/testsuite/rust/compile/issue-1446.rs
@@ -1,3 +1,11 @@
+// fake function
+pub fn swap_bytes(this: u32) -> u32 {
+ (((this) & 0xff000000) >> 24)
+ | (((this) & 0x00ff0000) >> 8)
+ | (((this) & 0x0000ff00) << 8)
+ | (((this) & 0x000000ff) << 24)
+}
+
pub fn to_le(this: u32) -> u32 {
#[cfg(target_endian = "little")]
{
@@ -5,6 +13,6 @@ pub fn to_le(this: u32) -> u32 {
}
#[cfg(not(target_endian = "little"))]
{
- this.swap_bytes()
+ swap_bytes(this)
}
}
diff --git a/gcc/testsuite/rust/compile/issue-1447.rs b/gcc/testsuite/rust/compile/issue-1447.rs
index 6d58f7a..afeef17 100644
--- a/gcc/testsuite/rust/compile/issue-1447.rs
+++ b/gcc/testsuite/rust/compile/issue-1447.rs
@@ -1,4 +1,5 @@
// { dg-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1483.rs b/gcc/testsuite/rust/compile/issue-1483.rs
index eda7e13..96ca72e 100644
--- a/gcc/testsuite/rust/compile/issue-1483.rs
+++ b/gcc/testsuite/rust/compile/issue-1483.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1485.rs b/gcc/testsuite/rust/compile/issue-1485.rs
new file mode 100644
index 0000000..958fcd1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1485.rs
@@ -0,0 +1,17 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+struct BinOpInvalid {
+ lhs: i32,
+ rhs: i32,
+ f: impl FnOnce(i32) -> i32, // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1487.rs b/gcc/testsuite/rust/compile/issue-1487.rs
new file mode 100644
index 0000000..dd34651
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1487.rs
@@ -0,0 +1,17 @@
+// { dg-options "-w" }
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Printable {
+ fn print(&self);
+}
+
+struct Foo;
+
+impl Printable for Foo {
+ fn print(&self) {}
+}
+
+fn take_printable(_: impl Printable) {}
diff --git a/gcc/testsuite/rust/compile/issue-1525.rs b/gcc/testsuite/rust/compile/issue-1525.rs
new file mode 100644
index 0000000..b2247cd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1525.rs
@@ -0,0 +1,4 @@
+fn main() {
+ const slice: &[i32] = &[1, 2, 3];
+ let _slice2: &[i32] = slice;
+}
diff --git a/gcc/testsuite/rust/compile/issue-1589.rs b/gcc/testsuite/rust/compile/issue-1589.rs
index 1dd7a45..dd7b4c0 100644
--- a/gcc/testsuite/rust/compile/issue-1589.rs
+++ b/gcc/testsuite/rust/compile/issue-1589.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1725-1.rs b/gcc/testsuite/rust/compile/issue-1725-1.rs
index a02e6f6..5891f71 100644
--- a/gcc/testsuite/rust/compile/issue-1725-1.rs
+++ b/gcc/testsuite/rust/compile/issue-1725-1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1725-2.rs b/gcc/testsuite/rust/compile/issue-1725-2.rs
index 726d967..3386f27 100644
--- a/gcc/testsuite/rust/compile/issue-1725-2.rs
+++ b/gcc/testsuite/rust/compile/issue-1725-2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -26,6 +27,5 @@ pub fn foo<T: core::ops::Add<Output = i32>>(a: T) -> i32 {
pub fn main() {
foo(123f32);
- // { dg-error "type mismatch, expected .i32. but got .f32." "" { target *-*-* } .-1 }
- // { dg-error "bounds not satisfied for f32 .Add. is not satisfied" "" { target *-*-* } .-2 }
+ // { dg-error "bounds not satisfied for f32 .Add. is not satisfied" "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/issue-1773.rs b/gcc/testsuite/rust/compile/issue-1773.rs
index 468497a..41c82f0 100644
--- a/gcc/testsuite/rust/compile/issue-1773.rs
+++ b/gcc/testsuite/rust/compile/issue-1773.rs
@@ -1,8 +1,4 @@
-#[lang = "sized"]
-// { dg-skip-if "" { *-*-* } }
-pub trait Sized {}
-
-trait Foo<T> {
+trait Foo {
type A;
fn test(a: Self::A) -> Self::A {
@@ -10,9 +6,14 @@ trait Foo<T> {
}
}
-struct Bar<T>(T);
-impl<T> Foo<T> for Bar<i32> {
- type A = T;
+struct Bar(i32);
+impl Foo for Bar {
+ type A = i32;
+}
+
+struct Baz(f32);
+impl Foo for Baz {
+ type A = f32;
}
fn main() {
@@ -21,4 +22,10 @@ fn main() {
let b;
b = Bar::test(a.0);
+
+ let c;
+ c = Baz(123f32);
+
+ let d;
+ d = Baz::test(c.0);
}
diff --git a/gcc/testsuite/rust/compile/issue-1786.rs b/gcc/testsuite/rust/compile/issue-1786.rs
index 1c46fee..e4f94bd 100644
--- a/gcc/testsuite/rust/compile/issue-1786.rs
+++ b/gcc/testsuite/rust/compile/issue-1786.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1893.rs b/gcc/testsuite/rust/compile/issue-1893.rs
index 46c53e9..47cde45 100644
--- a/gcc/testsuite/rust/compile/issue-1893.rs
+++ b/gcc/testsuite/rust/compile/issue-1893.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1901.rs b/gcc/testsuite/rust/compile/issue-1901.rs
index cfd8ef4..110b939 100644
--- a/gcc/testsuite/rust/compile/issue-1901.rs
+++ b/gcc/testsuite/rust/compile/issue-1901.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -13,14 +14,14 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
}
diff --git a/gcc/testsuite/rust/compile/issue-1930.rs b/gcc/testsuite/rust/compile/issue-1930.rs
index 071b3da..5eea229 100644
--- a/gcc/testsuite/rust/compile/issue-1930.rs
+++ b/gcc/testsuite/rust/compile/issue-1930.rs
@@ -1,4 +1,5 @@
// { dg-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-1981.rs b/gcc/testsuite/rust/compile/issue-1981.rs
index bfd8d2c..c71cecf 100644
--- a/gcc/testsuite/rust/compile/issue-1981.rs
+++ b/gcc/testsuite/rust/compile/issue-1981.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -16,30 +17,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -47,12 +48,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -60,7 +61,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -69,31 +70,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -106,7 +107,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -116,7 +117,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
@@ -126,7 +127,7 @@ trait Step {
impl Step for i32 {
fn replace_zero(&mut self) -> Self {
- mem::replace(self, 0)
+ crate::mem::replace(self, 0)
}
}
diff --git a/gcc/testsuite/rust/compile/issue-2015.rs b/gcc/testsuite/rust/compile/issue-2015.rs
new file mode 100644
index 0000000..5763096
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2015.rs
@@ -0,0 +1,22 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+macro_rules! impl_foo {
+ () => { impl Foo }
+}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+pub fn foo(_value: impl Bar<Baz = impl_foo!()>) -> i32 {
+ 15
+}
+
+pub fn bar(_value: impl Bar<Baz = impl Foo>) -> i32 {
+ 16
+}
diff --git a/gcc/testsuite/rust/compile/issue-2019-1.rs b/gcc/testsuite/rust/compile/issue-2019-1.rs
index e91e347..e3174b1 100644
--- a/gcc/testsuite/rust/compile/issue-2019-1.rs
+++ b/gcc/testsuite/rust/compile/issue-2019-1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2019-2.rs b/gcc/testsuite/rust/compile/issue-2019-2.rs
index 9f7c0c0..eefe44d 100644
--- a/gcc/testsuite/rust/compile/issue-2019-2.rs
+++ b/gcc/testsuite/rust/compile/issue-2019-2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2019-3.rs b/gcc/testsuite/rust/compile/issue-2019-3.rs
index c95ce43..7f00d82 100644
--- a/gcc/testsuite/rust/compile/issue-2019-3.rs
+++ b/gcc/testsuite/rust/compile/issue-2019-3.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2035.rs b/gcc/testsuite/rust/compile/issue-2035.rs
new file mode 100644
index 0000000..c0817d5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2035.rs
@@ -0,0 +1,10 @@
+fn func(i: i32) {
+ i();
+ // { dg-error "expected function, found .i32. .E0618." "" { target *-*-* } .-1 }
+}
+
+fn main() {
+ let i = 0i32;
+ i();
+ // { dg-error "expected function, found .i32. .E0618." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-2036.rs b/gcc/testsuite/rust/compile/issue-2036.rs
index 8701b20..03b8ed0 100644
--- a/gcc/testsuite/rust/compile/issue-2036.rs
+++ b/gcc/testsuite/rust/compile/issue-2036.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2037.rs b/gcc/testsuite/rust/compile/issue-2037.rs
index 8adcb97..0d929d5 100644
--- a/gcc/testsuite/rust/compile/issue-2037.rs
+++ b/gcc/testsuite/rust/compile/issue-2037.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2043.rs b/gcc/testsuite/rust/compile/issue-2043.rs
index efa1ded..92532b7 100644
--- a/gcc/testsuite/rust/compile/issue-2043.rs
+++ b/gcc/testsuite/rust/compile/issue-2043.rs
@@ -6,7 +6,6 @@ struct Foo<'a> {
impl<'a> Foo<'a> {
fn bar(self: &mut Foo<'a>) {}
// { dg-warning "associated function is never used: .bar." "" { target *-*-* } .-1 }
- // { dg-warning "unused name .self." "" { target *-*-* } .-2 }
}
fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-2070.rs b/gcc/testsuite/rust/compile/issue-2070.rs
index 981e599..f4dc360 100644
--- a/gcc/testsuite/rust/compile/issue-2070.rs
+++ b/gcc/testsuite/rust/compile/issue-2070.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2105.rs b/gcc/testsuite/rust/compile/issue-2105.rs
index 28f170e..4446b26 100644
--- a/gcc/testsuite/rust/compile/issue-2105.rs
+++ b/gcc/testsuite/rust/compile/issue-2105.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2106.rs b/gcc/testsuite/rust/compile/issue-2106.rs
index 4af57c8..a75d21b 100644
--- a/gcc/testsuite/rust/compile/issue-2106.rs
+++ b/gcc/testsuite/rust/compile/issue-2106.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2135.rs b/gcc/testsuite/rust/compile/issue-2135.rs
index 9f4d3e1..e2d5ed2 100644
--- a/gcc/testsuite/rust/compile/issue-2135.rs
+++ b/gcc/testsuite/rust/compile/issue-2135.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2136-1.rs b/gcc/testsuite/rust/compile/issue-2136-1.rs
index f0af551..eee8a68 100644
--- a/gcc/testsuite/rust/compile/issue-2136-1.rs
+++ b/gcc/testsuite/rust/compile/issue-2136-1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2136-2.rs b/gcc/testsuite/rust/compile/issue-2136-2.rs
index b25820d..b30c9d2 100644
--- a/gcc/testsuite/rust/compile/issue-2136-2.rs
+++ b/gcc/testsuite/rust/compile/issue-2136-2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2139.rs b/gcc/testsuite/rust/compile/issue-2139.rs
index 65f82f3..ba3736f 100644
--- a/gcc/testsuite/rust/compile/issue-2139.rs
+++ b/gcc/testsuite/rust/compile/issue-2139.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2142.rs b/gcc/testsuite/rust/compile/issue-2142.rs
index a3ec228..e4c0c92 100644
--- a/gcc/testsuite/rust/compile/issue-2142.rs
+++ b/gcc/testsuite/rust/compile/issue-2142.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2165.rs b/gcc/testsuite/rust/compile/issue-2165.rs
index 5bbde65..38288e9 100644
--- a/gcc/testsuite/rust/compile/issue-2165.rs
+++ b/gcc/testsuite/rust/compile/issue-2165.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2166.rs b/gcc/testsuite/rust/compile/issue-2166.rs
index 318f0a6..d9e07a6 100644
--- a/gcc/testsuite/rust/compile/issue-2166.rs
+++ b/gcc/testsuite/rust/compile/issue-2166.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -11,7 +12,6 @@ impl Add for u32 {
type Output = u32;
fn add(self) -> u32 {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
0
}
}
@@ -20,7 +20,6 @@ impl<'a> Add for &'a u32 {
type Output = u32;
fn add(self) -> <u32 as Add>::Output {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
0
}
}
diff --git a/gcc/testsuite/rust/compile/issue-2187.rs b/gcc/testsuite/rust/compile/issue-2187.rs
index deef417..78d843e 100644
--- a/gcc/testsuite/rust/compile/issue-2187.rs
+++ b/gcc/testsuite/rust/compile/issue-2187.rs
@@ -8,4 +8,3 @@ const D: &'static str = "
";
ERROR_TIME
// { dg-error "unrecognised token" "" { target *-*-* } .-1 }
-// { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/issue-2190-1.rs b/gcc/testsuite/rust/compile/issue-2190-1.rs
index 927f90d..ad0f168 100644
--- a/gcc/testsuite/rust/compile/issue-2190-1.rs
+++ b/gcc/testsuite/rust/compile/issue-2190-1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2190-2.rs b/gcc/testsuite/rust/compile/issue-2190-2.rs
index 1c93338..c1abfb6 100644
--- a/gcc/testsuite/rust/compile/issue-2190-2.rs
+++ b/gcc/testsuite/rust/compile/issue-2190-2.rs
@@ -1,4 +1,5 @@
// { dg-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2195.rs b/gcc/testsuite/rust/compile/issue-2195.rs
index fc158c3..0a917a8 100644
--- a/gcc/testsuite/rust/compile/issue-2195.rs
+++ b/gcc/testsuite/rust/compile/issue-2195.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2238.rs b/gcc/testsuite/rust/compile/issue-2238.rs
index 38871b3..6bbbca4 100644
--- a/gcc/testsuite/rust/compile/issue-2238.rs
+++ b/gcc/testsuite/rust/compile/issue-2238.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -10,7 +11,6 @@ fn main() {
impl Bar for Foo {
fn foo(&self) {}
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
}
let s = Foo;
diff --git a/gcc/testsuite/rust/compile/issue-2304.rs b/gcc/testsuite/rust/compile/issue-2304.rs
index 8313033..cef8fc8 100644
--- a/gcc/testsuite/rust/compile/issue-2304.rs
+++ b/gcc/testsuite/rust/compile/issue-2304.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2323.rs b/gcc/testsuite/rust/compile/issue-2323.rs
new file mode 100644
index 0000000..2c69214
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2323.rs
@@ -0,0 +1,11 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub struct S<T>(T);
+
+pub fn foo<T>(x: T) {
+ let y = S(x);
+ y.0;
+}
diff --git a/gcc/testsuite/rust/compile/issue-2330.rs b/gcc/testsuite/rust/compile/issue-2330.rs
index 97c1503..21637cb 100644
--- a/gcc/testsuite/rust/compile/issue-2330.rs
+++ b/gcc/testsuite/rust/compile/issue-2330.rs
@@ -1,5 +1,5 @@
// { dg-options "-w" }
-#![feature(intrinsics)]
+#![feature(intrinsics, lang_items)]
pub use option::Option::{self, None, Some};
pub use result::Result::{self, Err, Ok};
@@ -95,30 +95,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -126,12 +126,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -139,7 +139,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -148,31 +148,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -185,7 +185,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -195,6 +195,6 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
diff --git a/gcc/testsuite/rust/compile/issue-2369.rs b/gcc/testsuite/rust/compile/issue-2369.rs
new file mode 100644
index 0000000..e5a3030
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2369.rs
@@ -0,0 +1,23 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+fn main() {
+ pub trait Foo {
+ type A;
+ fn boo(&self) -> <Self as Foo>::A;
+ }
+
+ struct Bar;
+
+ impl Foo for isize {
+ type A = usize;
+ fn boo(&self) -> usize {
+ 42
+ }
+ }
+
+ fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+ // { dg-error "associated type bindings are not allowed here .E0229." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-2375.rs b/gcc/testsuite/rust/compile/issue-2375.rs
index a61fef8..e3b9c9f 100644
--- a/gcc/testsuite/rust/compile/issue-2375.rs
+++ b/gcc/testsuite/rust/compile/issue-2375.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2394.rs b/gcc/testsuite/rust/compile/issue-2394.rs
new file mode 100644
index 0000000..b5b5394
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2394.rs
@@ -0,0 +1,15 @@
+const A: i32 = (1 / 0);
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+// { dg-error "is not a constant expression" "" { target *-*-* } .-2 }
+
+fn main() {
+ let a = 1 / 0;
+ // { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+ let b = 3;
+ let c = b / 0;
+ // { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+ let a = 1 << 500;
+ // { dg-error "left shift count >= width of type" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-2423.rs b/gcc/testsuite/rust/compile/issue-2423.rs
new file mode 100644
index 0000000..6fcd32f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2423.rs
@@ -0,0 +1,14 @@
+impl NonExistant {
+ // { dg-error "could not resolve" "" { target *-*-* } .-1 }
+ fn test() {}
+}
+
+impl NotFound for NonExistant {
+ // { dg-error "could not resolve" "" { target *-*-* } .-1 }
+ fn test() {}
+}
+
+trait A {}
+
+impl A for NotFound {}
+// { dg-error "could not resolve" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/issue-2478.rs b/gcc/testsuite/rust/compile/issue-2478.rs
index 7fe4e2d..1cce4b2 100644
--- a/gcc/testsuite/rust/compile/issue-2478.rs
+++ b/gcc/testsuite/rust/compile/issue-2478.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2499.rs b/gcc/testsuite/rust/compile/issue-2499.rs
index 662d58f..f6d40d8 100644
--- a/gcc/testsuite/rust/compile/issue-2499.rs
+++ b/gcc/testsuite/rust/compile/issue-2499.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2567-1.rs b/gcc/testsuite/rust/compile/issue-2567-1.rs
new file mode 100644
index 0000000..f5af249
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2567-1.rs
@@ -0,0 +1,8 @@
+// { dg-options "-w" }
+enum Empty {}
+
+fn foo(x: Empty) {
+ let x: Empty = match x {
+ // empty
+ };
+}
diff --git a/gcc/testsuite/rust/compile/issue-2567-2.rs b/gcc/testsuite/rust/compile/issue-2567-2.rs
new file mode 100644
index 0000000..719511d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2567-2.rs
@@ -0,0 +1,8 @@
+// { dg-options "-w" }
+enum Empty {}
+
+fn foo(x: Empty) {
+ let x: i32 = match x {
+ // empty
+ };
+}
diff --git a/gcc/testsuite/rust/compile/issue-2567-3.rs b/gcc/testsuite/rust/compile/issue-2567-3.rs
new file mode 100644
index 0000000..09efaf0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2567-3.rs
@@ -0,0 +1,8 @@
+// { dg-options "-w" }
+enum Empty {}
+
+fn foo(x: Empty) {
+ match x {
+ // empty
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-266.rs b/gcc/testsuite/rust/compile/issue-266.rs
new file mode 100644
index 0000000..11196cb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-266.rs
@@ -0,0 +1,3 @@
+fn main() {
+ 'label: while break 'label {}
+}
diff --git a/gcc/testsuite/rust/compile/issue-2680.rs b/gcc/testsuite/rust/compile/issue-2680.rs
new file mode 100644
index 0000000..d5ae2ff44
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2680.rs
@@ -0,0 +1,6 @@
+// { dg-additional-options "-fdump-tree-gimple" }
+pub fn test_cast() {
+ let i = 1;
+ // { dg-final { scan-tree-dump-times {const i32 i;} 1 gimple } }
+ let _j = i as i64;
+}
diff --git a/gcc/testsuite/rust/compile/issue-2723-1.rs b/gcc/testsuite/rust/compile/issue-2723-1.rs
index 261956d..5c77383 100644
--- a/gcc/testsuite/rust/compile/issue-2723-1.rs
+++ b/gcc/testsuite/rust/compile/issue-2723-1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2723-2.rs b/gcc/testsuite/rust/compile/issue-2723-2.rs
index c7609d1..4baf088 100644
--- a/gcc/testsuite/rust/compile/issue-2723-2.rs
+++ b/gcc/testsuite/rust/compile/issue-2723-2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2725.rs b/gcc/testsuite/rust/compile/issue-2725.rs
index a344bc8..06b1a89 100644
--- a/gcc/testsuite/rust/compile/issue-2725.rs
+++ b/gcc/testsuite/rust/compile/issue-2725.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
trait Trait: ?Sized {} // { dg-error ".?Trait. is not permitted in supertraits" }
diff --git a/gcc/testsuite/rust/compile/issue-2747.rs b/gcc/testsuite/rust/compile/issue-2747.rs
index a9c09e7..fe4b572 100644
--- a/gcc/testsuite/rust/compile/issue-2747.rs
+++ b/gcc/testsuite/rust/compile/issue-2747.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2772-1.rs b/gcc/testsuite/rust/compile/issue-2772-1.rs
index 69977db..aad8591 100644
--- a/gcc/testsuite/rust/compile/issue-2772-1.rs
+++ b/gcc/testsuite/rust/compile/issue-2772-1.rs
@@ -1,4 +1,5 @@
// { dg-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2772-2.rs b/gcc/testsuite/rust/compile/issue-2772-2.rs
index b05f2b1..0e18324 100644
--- a/gcc/testsuite/rust/compile/issue-2772-2.rs
+++ b/gcc/testsuite/rust/compile/issue-2772-2.rs
@@ -1,4 +1,5 @@
// { dg-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2775.rs b/gcc/testsuite/rust/compile/issue-2775.rs
index 3ad7085..d67ced3 100644
--- a/gcc/testsuite/rust/compile/issue-2775.rs
+++ b/gcc/testsuite/rust/compile/issue-2775.rs
@@ -1,4 +1,5 @@
// { dg-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2782.rs b/gcc/testsuite/rust/compile/issue-2782.rs
index e199c88..61fc20c 100644
--- a/gcc/testsuite/rust/compile/issue-2782.rs
+++ b/gcc/testsuite/rust/compile/issue-2782.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2812.rs b/gcc/testsuite/rust/compile/issue-2812.rs
index 173259b..0de1738 100644
--- a/gcc/testsuite/rust/compile/issue-2812.rs
+++ b/gcc/testsuite/rust/compile/issue-2812.rs
@@ -1,4 +1,4 @@
// { dg-additional-options "-frust-compile-until=astvalidation" }
fn foo_1(&self);
-fn foo_1(&mut self);
-fn foo_1(self);
+fn foo_2(&mut self);
+fn foo_3(self);
diff --git a/gcc/testsuite/rust/compile/issue-2847.rs b/gcc/testsuite/rust/compile/issue-2847.rs
new file mode 100644
index 0000000..2bc5566
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2847.rs
@@ -0,0 +1,8 @@
+pub fn myfun1((x, _): (i32, i32)) -> i32 {
+ x
+}
+
+pub fn myfun2() -> i32 {
+ let (x, _) = (1, 2);
+ x
+}
diff --git a/gcc/testsuite/rust/compile/issue-2905-1.rs b/gcc/testsuite/rust/compile/issue-2905-1.rs
new file mode 100644
index 0000000..9b0c19d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2905-1.rs
@@ -0,0 +1,27 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub struct A<T>(T);
+
+pub trait B {
+ type C;
+}
+
+// ------
+// swap these two items
+
+impl B for i32 {
+ type C = Weird<i32>;
+}
+
+pub struct Weird<T>(A<(T,)>);
+
+// ------
+
+trait Foo {}
+
+impl Foo for Weird<i32> {}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-2905-2.rs b/gcc/testsuite/rust/compile/issue-2905-2.rs
new file mode 100644
index 0000000..1c9516d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2905-2.rs
@@ -0,0 +1,136 @@
+// { dg-options "-w" }
+#![feature(intrinsics)]
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+extern "rust-intrinsic" {
+ fn transmute<T, U>(_: T) -> U;
+ fn offset<T>(src: *const T, offset: isize) -> *const T;
+}
+
+pub mod core {
+ pub mod marker {
+ #[lang = "phantom_data"]
+ pub struct PhantomData<T>;
+ }
+
+ pub mod slice {
+ use crate::core::marker::PhantomData;
+ use crate::core::option::Option;
+
+ impl<T> crate::core::iter::IntoIterator for &[T] {
+ type Item = &T;
+ type IntoIter = Weird<T>;
+
+ fn into_iter(self) -> Weird<T> {
+ self.iter()
+ }
+ }
+
+ pub struct Weird<T> {
+ ptr: *const T, // should be NonNull<T> but here it does not matter
+ end: *const T,
+ _marker: PhantomData<&T>,
+ }
+
+ impl<T> Weird<T> {
+ pub(super) fn new(slice: &[T]) -> Self {
+ let ptr = slice.as_ptr();
+ // SAFETY: Similar to `IterMut::new`.
+ unsafe {
+ // should be: ptr.add(slice.len())
+ let end = transmute::<*const T, usize>(ptr) + slice.len(); // TODO(Arthur): Missing `* size_of::<T>()`?
+ let end = transmute::<usize, *const T>(end);
+
+ Self {
+ ptr,
+ end,
+ _marker: PhantomData,
+ }
+ }
+ }
+
+ fn is_empty(&self) -> bool {
+ self.ptr == self.end
+ }
+
+ fn next_unchecked(&mut self) -> *const T {
+ let old = self.ptr;
+
+ self.ptr = unsafe { offset(self.ptr, 1) };
+
+ old
+ }
+ }
+
+ trait Foo {}
+
+ impl<T> Foo for Weird<T> {}
+
+ // impl<T> core::iter::Iterator for Iter<T> {
+ // type Item = &T;
+
+ // fn next(&mut self) -> Option<&T> {
+ // if self.is_empty() {
+ // Option::None
+ // } else {
+ // Option::Some(&*self.next_unchecked())
+ // }
+ // }
+ // }
+
+ union Repr<T> {
+ pub(crate) rust: *const [T],
+ rust_mut: *mut [T],
+ pub(crate) raw: FatPtr<T>,
+ }
+
+ struct FatPtr<T> {
+ data: *const T,
+ pub(crate) len: usize,
+ }
+
+ impl<T> [T] {
+ pub fn iter(&self) -> Weird<T> {
+ Weird::new(self)
+ }
+
+ pub fn as_ptr(&self) -> *const T {
+ self as *const [T] as *const T
+ }
+
+ pub fn len(&self) -> usize {
+ unsafe { Repr { rust: self }.raw.len }
+ }
+ }
+ }
+
+ pub mod iter {
+ use crate::core::option::Option;
+
+ pub trait IntoIterator {
+ type Item;
+
+ type IntoIter: Iterator<Item = Self::Item>;
+
+ fn into_iter(self) -> Self::IntoIter;
+ }
+
+ pub trait Iterator {
+ type Item;
+
+ fn next(&mut self) -> Option<Self::Item>;
+ }
+ }
+
+ pub mod option {
+ pub enum Option<T> {
+ Some(T),
+ None,
+ }
+ }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-2907.rs b/gcc/testsuite/rust/compile/issue-2907.rs
new file mode 100644
index 0000000..8c0d496
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2907.rs
@@ -0,0 +1,33 @@
+#![feature(lang_items)]
+
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+pub trait Bar {}
+
+pub trait Foo {
+ type Ty;
+
+ fn foo(self) -> Self::Ty;
+}
+
+impl<B: Bar> Foo for B {
+ type Ty = u32;
+
+ fn foo(self) -> Self::Ty {
+ 14
+ }
+}
+
+struct Qux;
+
+impl Bar for Qux {}
+
+fn main() {
+ let a = Qux;
+ a.foo();
+
+ let b = Qux;
+ Foo::foo(b);
+}
diff --git a/gcc/testsuite/rust/compile/issue-2951.rs b/gcc/testsuite/rust/compile/issue-2951.rs
index d30a3bf..218332d 100644
--- a/gcc/testsuite/rust/compile/issue-2951.rs
+++ b/gcc/testsuite/rust/compile/issue-2951.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-2953-1.rs b/gcc/testsuite/rust/compile/issue-2953-1.rs
new file mode 100644
index 0000000..d3289b9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2953-1.rs
@@ -0,0 +1,29 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+pub trait Sized {
+ // Empty.
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ /// The returned type after the call operator is used.
+ #[lang = "fn_once_output"]
+ type Output;
+
+ /// Performs the call operation.
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ Greater = 1,
+}
+
+pub fn f<F: FnOnce(i32) -> Ordering>(g: F) -> Ordering {
+ g(1)
+}
diff --git a/gcc/testsuite/rust/compile/issue-2953-2.rs b/gcc/testsuite/rust/compile/issue-2953-2.rs
new file mode 100644
index 0000000..5fbd6c4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2953-2.rs
@@ -0,0 +1,39 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+pub trait Sized {
+ // Empty.
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ /// The returned type after the call operator is used.
+ #[lang = "fn_once_output"]
+ type Output;
+
+ /// Performs the call operation.
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ Greater = 1,
+}
+
+pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
+ match compare(&v1, &v2) {
+ Ordering::Less | Ordering::Equal => v2,
+ Ordering::Greater => v1,
+ }
+}
+
+pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
+ match compare(&v1, &v2) {
+ Ordering::Less | Ordering::Equal => v1,
+ Ordering::Greater => v2,
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-2954.rs b/gcc/testsuite/rust/compile/issue-2954.rs
new file mode 100644
index 0000000..973ee0a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2954.rs
@@ -0,0 +1,19 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "receiver"]
+#[unstable(feature = "receiver_trait", issue = "none")]
+// #[doc(hidden)]
+pub trait Receiver {
+ // Empty.
+}
+
+#[unstable(feature = "receiver_trait", issue = "none")]
+impl<T: ?Sized> Receiver for &T {}
+
+#[unstable(feature = "receiver_trait", issue = "none")]
+impl<T: ?Sized> Receiver for &mut T {}
+
+
diff --git a/gcc/testsuite/rust/compile/issue-2987.rs b/gcc/testsuite/rust/compile/issue-2987.rs
index 1ab5fdc..9560bde 100644
--- a/gcc/testsuite/rust/compile/issue-2987.rs
+++ b/gcc/testsuite/rust/compile/issue-2987.rs
@@ -1,5 +1,6 @@
// { dg-options "-w" } Currently there are a lot of warnings produced from inside clone/copy
// builtins
+#![feature(lang_items)]
#[lang = "copy"]
trait Copy {}
diff --git a/gcc/testsuite/rust/compile/issue-3009.rs b/gcc/testsuite/rust/compile/issue-3009.rs
new file mode 100644
index 0000000..3d6fb9f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3009.rs
@@ -0,0 +1,26 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo {
+ // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+ t: u64,
+}
+
+impl Foo {
+ fn of<T>() -> Foo {
+ // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+ Foo { t: 14 }
+ }
+}
+
+trait Bar {
+ fn bar() -> Foo;
+}
+
+impl<T> Bar for T {
+ fn bar() -> Foo {
+ Foo::of::<T>()
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3022.rs b/gcc/testsuite/rust/compile/issue-3022.rs
new file mode 100644
index 0000000..e9358c9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3022.rs
@@ -0,0 +1,20 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo<T> {
+ fn foo(self) -> T;
+}
+
+struct Bar<T, U> {
+ // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+ value: U,
+ valte: T,
+}
+
+impl<T: Foo<U>, U> Foo<U> for Bar<T, U> {
+ fn foo(self) -> U {
+ self.value
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3030.rs b/gcc/testsuite/rust/compile/issue-3030.rs
index 0a1866d..94222b7 100644
--- a/gcc/testsuite/rust/compile/issue-3030.rs
+++ b/gcc/testsuite/rust/compile/issue-3030.rs
@@ -1,5 +1,6 @@
#![feature(negative_impls)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-3031.rs b/gcc/testsuite/rust/compile/issue-3031.rs
new file mode 100644
index 0000000..33f5bf0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3031.rs
@@ -0,0 +1,15 @@
+#![feature(no_core)]
+#![feature(lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait A<T: ?Sized> {}
+
+struct Cell<X> {
+ // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+ x: X,
+}
+
+impl<T, U> A<Cell<U>> for Cell<T> where T: A<U> {}
diff --git a/gcc/testsuite/rust/compile/issue-3032-1.rs b/gcc/testsuite/rust/compile/issue-3032-1.rs
new file mode 100644
index 0000000..7338cb9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3032-1.rs
@@ -0,0 +1,58 @@
+#![feature(negative_impls, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "deref"]
+pub trait Deref {
+ /// The resulting type after dereferencing.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_target"]
+ type Target: ?Sized;
+
+ /// Dereferences the value.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_method"]
+ fn deref(&self) -> &Self::Target;
+}
+
+impl<T: ?Sized> Deref for &T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+// this is added because of #3030
+extern "C" {
+ fn never() -> !;
+}
+
+impl<T: ?Sized> !DerefMut for &T {
+ fn deref_mut(&mut self) -> &mut T {
+ unsafe { never() }
+ }
+}
+
+impl<T: ?Sized> Deref for &mut T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+#[lang = "deref_mut"]
+pub trait DerefMut: Deref {
+ /// Mutably dereferences the value.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+impl<T: ?Sized> DerefMut for &mut T {
+ fn deref_mut(&mut self) -> &mut T {
+ *self
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3032-2.rs b/gcc/testsuite/rust/compile/issue-3032-2.rs
new file mode 100644
index 0000000..37c081b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3032-2.rs
@@ -0,0 +1,49 @@
+#![feature(negative_impls, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "deref"]
+pub trait Deref {
+ /// The resulting type after dereferencing.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_target"]
+ type Target: ?Sized;
+
+ /// Dereferences the value.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_method"]
+ fn deref(&self) -> &Self::Target;
+}
+
+impl<T: ?Sized> Deref for &T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+impl<T: ?Sized> !DerefMut for &T {}
+
+impl<T: ?Sized> Deref for &mut T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+#[lang = "deref_mut"]
+pub trait DerefMut: Deref {
+ /// Mutably dereferences the value.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+impl<T: ?Sized> DerefMut for &mut T {
+ fn deref_mut(&mut self) -> &mut T {
+ *self
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3033.rs b/gcc/testsuite/rust/compile/issue-3033.rs
new file mode 100644
index 0000000..7adce5b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3033.rs
@@ -0,0 +1,144 @@
+#![feature(negative_impls, lang_items)]
+
+#[lang = "copy"]
+trait Copy {}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[repr(transparent)]
+#[repr(no_niche)] // rust-lang/rust#68303.
+pub struct UnsafeCell<T: ?Sized> {
+ value: T,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl<T: ?Sized> UnsafeCell<T> {
+ /// Gets a mutable pointer to the wrapped value.
+ ///
+ /// This can be cast to a pointer of any kind.
+ /// Ensure that the access is unique (no active references, mutable or not)
+ /// when casting to `&mut T`, and ensure that there are no mutations
+ /// or mutable aliases going on when casting to `&T`
+ ///
+ /// # Examples
+ ///
+ ///
+ /// use std::cell::UnsafeCell;
+ ///
+ /// let uc = UnsafeCell::new(5);
+ ///
+ /// let five = uc.get();
+ ///
+ #[inline]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")]
+ pub const fn get(&self) -> *mut T {
+ // We can just cast the pointer from `UnsafeCell<T>` to `T` because of
+ // #[repr(transparent)]. This exploits libstd's special status, there is
+ // no guarantee for user code that this will work in future versions of the compiler!
+ self as *const UnsafeCell<T> as *const T as *mut T
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[repr(transparent)]
+pub struct Cell<T: ?Sized> {
+ value: UnsafeCell<T>,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl<T: Copy> Cell<T> {
+ /// Returns a copy of the contained value.
+ ///
+ /// # Examples
+ ///
+ ///
+ /// use std::cell::Cell;
+ ///
+ /// let c = Cell::new(5);
+ ///
+ /// let five = c.get();
+ ///
+ #[inline]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn get(&self) -> T {
+ // SAFETY: This can cause data races if called from a separate thread,
+ // but `Cell` is `!Sync` so this won't happen.
+ unsafe { *self.value.get() }
+ }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "deref"]
+pub trait Deref {
+ /// The resulting type after dereferencing.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_target"]
+ type Target: ?Sized;
+
+ /// Dereferences the value.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_method"]
+ fn deref(&self) -> &Self::Target;
+}
+
+impl<T: ?Sized> Deref for &T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+// this is added because of #3030
+extern "C" {
+ fn never() -> !;
+}
+
+impl<T: ?Sized> !DerefMut for &T {
+ fn deref_mut(&mut self) -> &mut T {
+ unsafe { never() }
+ }
+}
+
+impl<T: ?Sized> Deref for &mut T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+#[lang = "deref_mut"]
+pub trait DerefMut: Deref {
+ /// Mutably dereferences the value.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+#[inline]
+pub fn new<'b>(borrow: &'b Cell<i32>) {
+ let b = borrow.get();
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3035.rs b/gcc/testsuite/rust/compile/issue-3035.rs
index 3266d84..80c2ab6 100644
--- a/gcc/testsuite/rust/compile/issue-3035.rs
+++ b/gcc/testsuite/rust/compile/issue-3035.rs
@@ -1,3 +1,5 @@
+#![feature(lang_items)]
+
#[lang = "sized"]
trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-3036.rs b/gcc/testsuite/rust/compile/issue-3036.rs
index 4418ccc..39856d5 100644
--- a/gcc/testsuite/rust/compile/issue-3036.rs
+++ b/gcc/testsuite/rust/compile/issue-3036.rs
@@ -1,3 +1,5 @@
+#![feature(lang_items)]
+
#[lang = "sized"]
trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-3045-1.rs b/gcc/testsuite/rust/compile/issue-3045-1.rs
index a1328f2..1f62e368 100644
--- a/gcc/testsuite/rust/compile/issue-3045-1.rs
+++ b/gcc/testsuite/rust/compile/issue-3045-1.rs
@@ -1,4 +1,4 @@
-#![feature(dropck_eyepatch)]
+#![feature(dropck_eyepatch, lang_items)]
#[allow(dead_code)]
#[lang = "sized"]
diff --git a/gcc/testsuite/rust/compile/issue-3045-2.rs b/gcc/testsuite/rust/compile/issue-3045-2.rs
index 177707fb..4c90d4d 100644
--- a/gcc/testsuite/rust/compile/issue-3045-2.rs
+++ b/gcc/testsuite/rust/compile/issue-3045-2.rs
@@ -1,4 +1,4 @@
-#![feature(dropck_eyepatch)]
+#![feature(dropck_eyepatch, lang_items)]
#[allow(dead_code)]
#[lang = "sized"]
diff --git a/gcc/testsuite/rust/compile/issue-3046.rs b/gcc/testsuite/rust/compile/issue-3046.rs
index c982cc9..f0c72a3 100644
--- a/gcc/testsuite/rust/compile/issue-3046.rs
+++ b/gcc/testsuite/rust/compile/issue-3046.rs
@@ -12,12 +12,10 @@ fn test(v: LOption) -> Res {
return Res::BAD;
}
-
fn main() {
// Should be:
// test(LOption::Some(2));
- //
+ //
test(LOption(2));
// { dg-error "expected function, tuple struct or tuple variant, found enum" "" { target *-*-* } .-1 }
- // { dg-error "failed to resolve type for argument expr in CallExpr" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/issue-3140.rs b/gcc/testsuite/rust/compile/issue-3140.rs
new file mode 100644
index 0000000..dcf86db
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3140.rs
@@ -0,0 +1,27 @@
+enum State {
+ Succeeded,
+ Failed,
+}
+
+fn print_on_failure(state: &State) {
+ let mut num = 0;
+ match *state {
+ // error: expected unit struct, unit variant or constant, found tuple
+ // variant `State::Failed`
+ State::Failed => {
+ num = 1;
+ }
+ State::Succeeded => {
+ num = 2;
+ }
+ _ => (),
+ }
+}
+
+fn main() {
+ let b = State::Failed(1);
+ // { dg-error "expected function, tuple struct or tuple variant, found struct .State." "" { target *-*-* } .-1 }
+
+ print_on_failure(&b);
+ // { dg-error "cannot find value .b. in this scope" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3144.rs b/gcc/testsuite/rust/compile/issue-3144.rs
new file mode 100644
index 0000000..02c6ff6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3144.rs
@@ -0,0 +1,30 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "clone"]
+pub trait Clone {
+ fn clone(&self) -> Self;
+}
+
+impl Clone for i32 {
+ fn clone(&self) -> i32 {
+ *self
+ }
+}
+
+struct S {}
+
+#[derive(Clone, Copy)]
+// { dg-error {bounds not satisfied for S .Clone. is not satisfied .E0277.} "" { target *-*-* } .-1 }
+struct S2 {
+ a: i32,
+ s: S,
+}
+
+fn main() -> i32 {
+ 0
+}
diff --git a/gcc/testsuite/rust/compile/issue-3174.rs b/gcc/testsuite/rust/compile/issue-3174.rs
new file mode 100644
index 0000000..87588e1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3174.rs
@@ -0,0 +1,28 @@
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+enum Option {
+ Some(i32),
+ None,
+}
+
+impl Option {
+ fn add(&mut self) {
+ match *self {
+ Option::Some(ref mut a) => *a += 1,
+ Option::None => {}
+ }
+ }
+}
+
+fn main() {
+ unsafe {
+ let mut a = Option::None;
+ a.add();
+ let _s = "%d\n\0";
+ let _s = _s as *const str;
+ let s = _s as *const i8;
+ printf(s, a);
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3231.rs b/gcc/testsuite/rust/compile/issue-3231.rs
new file mode 100644
index 0000000..59726cb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3231.rs
@@ -0,0 +1,8 @@
+// { dg-options "-w" }
+pub enum X {}
+
+pub fn foo(x: X) {
+ let _a: i32 = match x {};
+}
+
+pub fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3242.rs b/gcc/testsuite/rust/compile/issue-3242.rs
new file mode 100644
index 0000000..a6bd1c8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3242.rs
@@ -0,0 +1,24 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+trait Foo<T> {
+ type A;
+
+ fn test(a: Self::A) -> Self::A {
+ a
+ }
+}
+
+struct Bar<T>(T);
+impl<T> Foo<T> for Bar<i32> {
+ type A = T;
+}
+
+fn main() {
+ let a;
+ a = Bar(123);
+
+ let b;
+ b = Bar::test(a.0);
+}
diff --git a/gcc/testsuite/rust/compile/issue-3261.rs b/gcc/testsuite/rust/compile/issue-3261.rs
new file mode 100644
index 0000000..37e974d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3261.rs
@@ -0,0 +1,18 @@
+// { dg-options "-w" }
+fn main() {
+ let a: i8 = 50;
+ let b = a as f32;
+ let c = a as f64;
+
+ let a: i16 = 1337;
+ let b = a as f32;
+ let c = a as f64;
+
+ let a: i32 = 1337;
+ let b = a as f32;
+ let c = a as f64;
+
+ let a: i64 = 1337;
+ let b = a as f32;
+ let c = a as f64;
+}
diff --git a/gcc/testsuite/rust/compile/issue-3304.rs b/gcc/testsuite/rust/compile/issue-3304.rs
new file mode 100644
index 0000000..aa857e2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3304.rs
@@ -0,0 +1,11 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub enum ROption<T> {
+ RSome(T),
+ RNone,
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3315-1.rs b/gcc/testsuite/rust/compile/issue-3315-1.rs
new file mode 100644
index 0000000..07581da
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3315-1.rs
@@ -0,0 +1,8 @@
+//You should be able to create a module of the same name as a builtin type
+
+mod i32 {
+}
+
+fn main() -> isize {
+ 0
+}
diff --git a/gcc/testsuite/rust/compile/issue-3315-2.rs b/gcc/testsuite/rust/compile/issue-3315-2.rs
new file mode 100644
index 0000000..71abd6c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3315-2.rs
@@ -0,0 +1,7 @@
+mod i32 {
+}
+
+fn main() -> isize {
+ let i:i32 = 0 as i32;
+ i as isize
+}
diff --git a/gcc/testsuite/rust/compile/issue-3350.rs b/gcc/testsuite/rust/compile/issue-3350.rs
new file mode 100644
index 0000000..8880659
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3350.rs
@@ -0,0 +1,10 @@
+static FOO: i32 = 0;
+
+pub fn bar() -> i32 {
+ FOO
+}
+
+pub fn baz() -> i32 {
+ static QUX: i32 = 0;
+ QUX
+}
diff --git a/gcc/testsuite/rust/compile/issue-3382.rs b/gcc/testsuite/rust/compile/issue-3382.rs
new file mode 100644
index 0000000..c26494c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3382.rs
@@ -0,0 +1,63 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ #[lang = "Ok"]
+ Ok(T),
+ #[lang = "Err"]
+ Err(E),
+}
+
+#[lang = "try"]
+pub trait Try {
+ /// The type of this value when viewed as successful.
+ // #[unstable(feature = "try_trait", issue = "42327")]
+ type Ok;
+ /// The type of this value when viewed as failed.
+ // #[unstable(feature = "try_trait", issue = "42327")]
+ type Error;
+
+ /// Applies the "?" operator. A return of `Ok(t)` means that the
+ /// execution should continue normally, and the result of `?` is the
+ /// value `t`. A return of `Err(e)` means that execution should branch
+ /// to the innermost enclosing `catch`, or return from the function.
+ ///
+ /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+ /// in the return type of the enclosing scope (which must itself implement
+ /// `Try`). Specifically, the value `X::from_error(From::from(e))`
+ /// is returned, where `X` is the return type of the enclosing function.
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+ /// Wrap an error value to construct the composite result. For example,
+ /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: Self::Ok) -> Self;
+
+ /// Wrap an OK value to construct the composite result. For example,
+ /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: Self::Error) -> Self;
+}
+
+impl<T, E> Try for Result<T, E> {
+ type Ok = T;
+ type Error = E;
+
+ fn into_result(self) -> Result<T, E> {
+ self
+ }
+
+ fn from_ok(v: T) -> Self {
+ Result::Ok(v)
+ }
+
+ fn from_error(v: E) -> Self {
+ Result::Err(v)
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3402-1.rs b/gcc/testsuite/rust/compile/issue-3402-1.rs
new file mode 100644
index 0000000..cd13b74
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3402-1.rs
@@ -0,0 +1,31 @@
+#![feature(lang_items)]
+
+pub struct Foo {
+ a: i32,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+pub struct Bar(i32);
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod default {
+ pub trait Default: Sized {
+ fn default() -> Self;
+ }
+
+ impl Default for i32 {
+ fn default() -> Self {
+ 0
+ }
+ }
+ }
+}
+
+impl ::core::default::Default for Bar {
+ #[inline]
+ fn default() -> Bar {
+ Bar(core::default::Default::default())
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3402-2.rs b/gcc/testsuite/rust/compile/issue-3402-2.rs
new file mode 100644
index 0000000..33d72e0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3402-2.rs
@@ -0,0 +1,20 @@
+#![feature(lang_items)]
+
+pub struct Bar(i32);
+
+#[lang = "sized"]
+trait Sized {}
+
+pub trait A: Sized {
+ fn foo() -> Self;
+}
+
+impl A for i32 {
+ fn foo() -> Self {
+ 0
+ }
+}
+
+pub fn bar() {
+ let _ = Bar(A::foo());
+}
diff --git a/gcc/testsuite/rust/compile/issue-3403.rs b/gcc/testsuite/rust/compile/issue-3403.rs
new file mode 100644
index 0000000..6a3f720
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3403.rs
@@ -0,0 +1,40 @@
+#![feature(lang_items)]
+
+pub struct Foo {
+ a: i32,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+pub struct Bar(i32);
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod default {
+ pub trait Default: Sized {
+ fn default() -> Self;
+ }
+
+ impl Default for i32 {
+ fn default() -> Self {
+ 0
+ }
+ }
+ }
+}
+
+impl ::core::default::Default for Bar {
+ #[inline]
+ fn default() -> Bar {
+ Bar(core::default::Default::default())
+ }
+}
+
+impl ::core::default::Default for Foo {
+ #[inline]
+ fn default() -> Foo {
+ Foo {
+ a: core::default::Default::default(),
+ }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3454.rs b/gcc/testsuite/rust/compile/issue-3454.rs
new file mode 100644
index 0000000..e2a5a39
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3454.rs
@@ -0,0 +1,21 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+macro_rules! impl_foo {
+ () => { impl Foo }
+}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+pub fn foo(_value: impl Bar<Baz = impl_foo!()>) -> i32 {
+ 15
+}
+
+pub fn bar(_value: impl Bar<Baz = impl Foo>) -> i32 {
+ 16
+}
diff --git a/gcc/testsuite/rust/compile/issue-3524.rs b/gcc/testsuite/rust/compile/issue-3524.rs
new file mode 100644
index 0000000..62c8c35
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3524.rs
@@ -0,0 +1,9 @@
+struct A {}
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+impl A {
+ fn main() {}
+ // { dg-warning "associated function is never used: .main." "" { target *-*-* } .-1 }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3525.rs b/gcc/testsuite/rust/compile/issue-3525.rs
new file mode 100644
index 0000000..84a7ebe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3525.rs
@@ -0,0 +1,6 @@
+// { dg-options "-w" }
+
+struct Foo(usize);
+
+const B: usize = A.0;
+const A: Foo = Foo(123);
diff --git a/gcc/testsuite/rust/compile/issue-3530-1.rs b/gcc/testsuite/rust/compile/issue-3530-1.rs
new file mode 100644
index 0000000..b38b5cd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3530-1.rs
@@ -0,0 +1,2 @@
+#[repr(i32)]
+enum NightsWatch {} // { dg-error "unsupported representation for zero-variant enum" }
diff --git a/gcc/testsuite/rust/compile/issue-3530-2.rs b/gcc/testsuite/rust/compile/issue-3530-2.rs
new file mode 100644
index 0000000..7432730
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3530-2.rs
@@ -0,0 +1,2 @@
+#[repr(C)]
+enum NightsWatch {} // { dg-error "unsupported representation for zero-variant enum" }
diff --git a/gcc/testsuite/rust/compile/issue-3538.rs b/gcc/testsuite/rust/compile/issue-3538.rs
new file mode 100644
index 0000000..7269457
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3538.rs
@@ -0,0 +1,9 @@
+enum A {
+ Value(()),
+}
+
+fn main() {
+ let a = A::Value(());
+ a == A::Value;
+ // { dg-error "variant expected constructor call" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3541-1.rs b/gcc/testsuite/rust/compile/issue-3541-1.rs
new file mode 100644
index 0000000..6b47b7e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3541-1.rs
@@ -0,0 +1,5 @@
+impl B for u32 {
+ const BAR: i32; // { dg-error "associated constant in .impl." }
+}
+
+trait B {}
diff --git a/gcc/testsuite/rust/compile/issue-3541-2.rs b/gcc/testsuite/rust/compile/issue-3541-2.rs
new file mode 100644
index 0000000..9f17eed
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3541-2.rs
@@ -0,0 +1,3 @@
+trait B {
+ const BAR: i32;
+}
diff --git a/gcc/testsuite/rust/compile/issue-3546.rs b/gcc/testsuite/rust/compile/issue-3546.rs
new file mode 100644
index 0000000..d4ec0bb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3546.rs
@@ -0,0 +1,16 @@
+const L: usize = 3;
+
+fn main() {
+ let p = Printer {};
+ p.print();
+}
+
+trait Print<const N: usize> {
+ fn print(&self) -> usize {
+ 3
+ }
+}
+
+struct Printer {}
+impl Print<L> for Printer {}
+// { dg-error "generic item takes at most 1 type arguments but 1 were supplied" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/issue-3549.rs b/gcc/testsuite/rust/compile/issue-3549.rs
new file mode 100644
index 0000000..cedbb5a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3549.rs
@@ -0,0 +1,3 @@
+fn main() {
+ r#""#;
+}
diff --git a/gcc/testsuite/rust/compile/issue-3551.rs b/gcc/testsuite/rust/compile/issue-3551.rs
new file mode 100644
index 0000000..55303b2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3551.rs
@@ -0,0 +1,16 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+struct Bug {
+ a: [(); (|| 0)()],
+ // { dg-error "calls in constants are limited to constant functions, tuple structs and tuple variants" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3552.rs b/gcc/testsuite/rust/compile/issue-3552.rs
new file mode 100644
index 0000000..9a4451b14b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3552.rs
@@ -0,0 +1,14 @@
+trait Foo {
+ const BAR: u32;
+}
+
+const TRAIT_REF_BAR: u32 = <Foo>::BAR;
+// { dg-error "no default expression on trait constant" "" { target *-*-* } .-1 }
+
+struct GlobalTraitRef;
+
+impl Foo for GlobalTraitRef {
+ const BAR: u32 = TRAIT_REF_BAR;
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3553.rs b/gcc/testsuite/rust/compile/issue-3553.rs
new file mode 100644
index 0000000..546f3c1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3553.rs
@@ -0,0 +1,18 @@
+trait Foo {
+ fn f(&self) -> isize;
+}
+
+trait Bar: Foo {
+ fn g(&self) -> isize;
+}
+
+struct A {
+ x: isize,
+}
+
+impl Bar for A {
+ // { dg-error "the trait bound .A: Foo. is not satisfied .E0277." "" { target *-*-* } .-1 }
+ fn g(&self) -> isize {
+ self.f()
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3554-1.rs b/gcc/testsuite/rust/compile/issue-3554-1.rs
new file mode 100644
index 0000000..a66be35
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3554-1.rs
@@ -0,0 +1,8 @@
+trait Tr {
+ fn foo();
+
+ fn bar(&self) {
+ self.foo()
+ // { dg-error "no method named .foo. found in the current scope .E0599." "" { target *-*-* } .-1 }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3554-2.rs b/gcc/testsuite/rust/compile/issue-3554-2.rs
new file mode 100644
index 0000000..3710e57
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3554-2.rs
@@ -0,0 +1,19 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+trait Tr {
+ fn foo();
+
+ fn bar(&self) {
+ (|| self.foo())()
+ // { dg-error "no method named .foo. found in the current scope .E0599." "" { target *-*-* } .-1 }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3556.rs b/gcc/testsuite/rust/compile/issue-3556.rs
new file mode 100644
index 0000000..be7d85a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3556.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let ref mut a @ (ref mut b,);
+ // { dg-error "expected T\\?, found tuple" "" { target *-*-* } .-1 }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/issue-3563.rs b/gcc/testsuite/rust/compile/issue-3563.rs
new file mode 100644
index 0000000..46e7624
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3563.rs
@@ -0,0 +1,17 @@
+pub struct AA {
+ pub data: [u8; 10],
+}
+
+impl AA {
+ pub const fn new() -> Self {
+ let mut res: AA = AA { data: [0; 10] };
+ res.data[0] = 5;
+ res
+ }
+}
+
+static mut BB: AA = AA::new();
+
+fn main() {
+ let _ptr = unsafe { &mut BB };
+}
diff --git a/gcc/testsuite/rust/compile/issue-3566-1.rs b/gcc/testsuite/rust/compile/issue-3566-1.rs
new file mode 100644
index 0000000..b7e5be0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3566-1.rs
@@ -0,0 +1,8 @@
+mod a {
+ pub mod b {
+
+ pub fn f(x: [u8; { 100 }]) -> [u8; { 100 }] {
+ x
+ }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3566-2.rs b/gcc/testsuite/rust/compile/issue-3566-2.rs
new file mode 100644
index 0000000..3f3ea73
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3566-2.rs
@@ -0,0 +1,22 @@
+// run-pass
+
+#![allow(H8)]
+#![allow(dead_code)]
+
+
+// pretty-expanded FIXME #23616
+
+mod a {
+ pub mod b {
+ pub type t = isize;
+
+ pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8; { let z = 18; 100 }] {
+ //~^ WARN unused variable: `s`
+ //~| WARN unused variable: `z`
+ x
+}
+ }
+}
+
+pub fn main() { //~ ERROR cannot move out
+ }
diff --git a/gcc/testsuite/rust/compile/issue-3567.rs b/gcc/testsuite/rust/compile/issue-3567.rs
new file mode 100644
index 0000000..021d9c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3567.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let _: &[i8] = &[i8];
+ // { dg-error "expected value .E0423." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3568.rs b/gcc/testsuite/rust/compile/issue-3568.rs
new file mode 100644
index 0000000..fef43b5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3568.rs
@@ -0,0 +1,7 @@
+pub type T = ();
+mod foo {
+ pub use super::T;
+}
+
+pub use foo::super::foo::S as T;
+// { dg-error ".super. in paths can only be used in start position" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/issue-3581-1.rs b/gcc/testsuite/rust/compile/issue-3581-1.rs
new file mode 100644
index 0000000..eb2f5f0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3581-1.rs
@@ -0,0 +1,12 @@
+enum Foo {
+ Bar,
+}
+
+struct Baz;
+
+fn main() {
+ Foo::Bar.a;
+ // { dg-error "no field .a. on type .Foo. .E0609." "" { target *-*-* } .-1 }
+ Baz.a;
+ // { dg-error "no field .a. on type .Baz. .E0609." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3581-2.rs b/gcc/testsuite/rust/compile/issue-3581-2.rs
new file mode 100644
index 0000000..5059784
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3581-2.rs
@@ -0,0 +1,9 @@
+enum A {
+ X { inner: i32 },
+ Y,
+}
+
+pub fn test() {
+ let _ = A::Y.inner;
+ // { dg-error "no field .inner. on type .A. .E0609." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3588.rs b/gcc/testsuite/rust/compile/issue-3588.rs
new file mode 100644
index 0000000..744d967
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3588.rs
@@ -0,0 +1,5 @@
+const FOO: i32 = if true { [1, 2, 3] } else { [2, 3, 4] }[0];
+
+pub fn test() -> i32 {
+ FOO
+}
diff --git a/gcc/testsuite/rust/compile/issue-3592.rs b/gcc/testsuite/rust/compile/issue-3592.rs
new file mode 100644
index 0000000..34018d1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3592.rs
@@ -0,0 +1,7 @@
+pub trait X {
+ fn x() {
+ fn f(&mut self) {}
+ // { dg-error ".self. parameter is only allowed in associated functions" "" { target *-*-* } .-1 }
+ f();
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3599.rs b/gcc/testsuite/rust/compile/issue-3599.rs
new file mode 100644
index 0000000..a41d2b3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3599.rs
@@ -0,0 +1,10 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Bar {}
+
+struct S; // { dg-warning "struct is never constructed" }
+
+pub fn test(foo: impl Bar) {}
diff --git a/gcc/testsuite/rust/compile/issue-3605.rs b/gcc/testsuite/rust/compile/issue-3605.rs
new file mode 100644
index 0000000..05e6e48
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3605.rs
@@ -0,0 +1,5 @@
+enum Foo<'a> {}
+
+enum Bar<'a> {
+ in_band_def_explicit_impl(Foo<'a>),
+}
diff --git a/gcc/testsuite/rust/compile/issue-3606.rs b/gcc/testsuite/rust/compile/issue-3606.rs
new file mode 100644
index 0000000..73b0bd6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3606.rs
@@ -0,0 +1,6 @@
+// { dg-options "-w" }
+#[repr()]
+pub struct Coord {
+ x: u32,
+ y: u32,
+}
diff --git a/gcc/testsuite/rust/compile/issue-3612.rs b/gcc/testsuite/rust/compile/issue-3612.rs
new file mode 100644
index 0000000..5256d0a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3612.rs
@@ -0,0 +1,7 @@
+trait _St1 {
+ pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) };
+ // { dg-error "no method named .as_ptr. found in the current scope .E0599." "" { target *-*-* } .-1 }
+ // { dg-error "failed to resolve receiver in MethodCallExpr" "" { target *-*-* } .-2 }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3613.rs b/gcc/testsuite/rust/compile/issue-3613.rs
new file mode 100644
index 0000000..f2e1092
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3613.rs
@@ -0,0 +1,18 @@
+mod m1 {
+ pub enum Baz4 {
+ foo1,
+ foo2,
+ }
+}
+
+fn bar(x: m1::foo) {
+ // { dg-error "unknown reference for resolved name: .foo." "" { target *-*-* } .-1 }
+ match x {
+ m1::foo::foo1 => {}
+ // { dg-error "failed to type resolve root segment" "" { target *-*-* } .-1 }
+ m1::NodePosition::foo2 => {}
+ // { dg-error "failed to type resolve root segment" "" { target *-*-* } .-1 }
+ }
+}
+
+pub fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3614.rs b/gcc/testsuite/rust/compile/issue-3614.rs
new file mode 100644
index 0000000..350a7e4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3614.rs
@@ -0,0 +1,3 @@
+#[repr] // { dg-error "malformed .repr. attribute" }
+
+struct _B {}
diff --git a/gcc/testsuite/rust/compile/issue-3615.rs b/gcc/testsuite/rust/compile/issue-3615.rs
new file mode 100644
index 0000000..e5c5072
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3615.rs
@@ -0,0 +1,7 @@
+pub trait Trait {
+ pub fn nrvo(init: fn()) -> [u8; 4096] {
+ let mut buf = [0; 4096];
+
+ buf
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3617.rs b/gcc/testsuite/rust/compile/issue-3617.rs
new file mode 100644
index 0000000..64c2166
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3617.rs
@@ -0,0 +1,14 @@
+macro_rules! quote_tokens {
+ () => {
+ #[macro_export]
+ macro_rules! inner {
+ () => {
+ $crate::
+ }
+ }
+ };
+}
+
+pub fn main() {
+ quote_tokens!();
+}
diff --git a/gcc/testsuite/rust/compile/issue-3618.rs b/gcc/testsuite/rust/compile/issue-3618.rs
new file mode 100644
index 0000000..3bf2c7e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3618.rs
@@ -0,0 +1,2 @@
+static _X : ()
+ = loop{}; // { dg-error "'loop' is not allowed in const context" }
diff --git a/gcc/testsuite/rust/compile/issue-3625.rs b/gcc/testsuite/rust/compile/issue-3625.rs
new file mode 100644
index 0000000..91e0dc9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3625.rs
@@ -0,0 +1,2 @@
+type A = crate::A;
+// { dg-error "failed to resolve type path segment: .A." "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/issue-3628.rs b/gcc/testsuite/rust/compile/issue-3628.rs
new file mode 100644
index 0000000..5f59789
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3628.rs
@@ -0,0 +1,10 @@
+pub enum Enum {
+ Variant1(isize),
+}
+
+impl Enum {
+ fn static_meth_enum() -> Enum {
+ Enum { x: 1 }
+ // { dg-error "expected a struct, variant or union type, found enum .Enum. .E0574." "" { target *-*-* } .-1 }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3642.rs b/gcc/testsuite/rust/compile/issue-3642.rs
new file mode 100644
index 0000000..30abfd3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3642.rs
@@ -0,0 +1,11 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub trait T<X> {
+ const D: i32 = {
+ // { dg-error "mismatched types, expected .i32. but got .()." "" { target *-*-* } .-1 }
+ const C: X;
+ };
+}
diff --git a/gcc/testsuite/rust/compile/issue-3643.rs b/gcc/testsuite/rust/compile/issue-3643.rs
new file mode 100644
index 0000000..bed9ffc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3643.rs
@@ -0,0 +1,4 @@
+fn foo() {
+ let x: usize<foo>;
+ // { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3645.rs b/gcc/testsuite/rust/compile/issue-3645.rs
new file mode 100644
index 0000000..91285f1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3645.rs
@@ -0,0 +1,6 @@
+// { dg-warning "unused name 'y'" "" { target *-*-* } 5 }
+// { dg-warning "unused name 'z'" "" { target *-*-* } 5 }
+
+fn main() {
+ let (ref y,z) = (1i32, 2u32);
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/issue-3646.rs b/gcc/testsuite/rust/compile/issue-3646.rs
new file mode 100644
index 0000000..80693cb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3646.rs
@@ -0,0 +1,7 @@
+trait Foo {
+ type T;
+ fn foo() -> Foo<main>;
+ // { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3647.rs b/gcc/testsuite/rust/compile/issue-3647.rs
new file mode 100644
index 0000000..51d9478d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3647.rs
@@ -0,0 +1,7 @@
+#![allow(dead_code)]
+type A = fn();
+
+type B = for<'static> fn();
+// { dg-error "invalid lifetime parameter name: .static. .E0262." "" { target *-*-* } .-1 }
+
+pub fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3648.rs b/gcc/testsuite/rust/compile/issue-3648.rs
new file mode 100644
index 0000000..52ecbbf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3648.rs
@@ -0,0 +1,8 @@
+struct B; // { dg-warning "struct is never constructed" }
+
+impl B {
+ fn main() {}
+ // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3649.rs b/gcc/testsuite/rust/compile/issue-3649.rs
new file mode 100644
index 0000000..b85b193
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3649.rs
@@ -0,0 +1,2 @@
+struct T(Box<>);
+// { dg-error "could not resolve type path .Box. .E0412." "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/issue-3652.rs b/gcc/testsuite/rust/compile/issue-3652.rs
new file mode 100644
index 0000000..537ca9f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3652.rs
@@ -0,0 +1,7 @@
+trait Foo {
+ type T;
+ fn foo() -> T<<Self as Foo>::T>;
+ // { dg-error "could not resolve type path .T. .E0412." "" { target *-*-* } .-1 }
+}
+
+fn foo() {}
diff --git a/gcc/testsuite/rust/compile/issue-3654.rs b/gcc/testsuite/rust/compile/issue-3654.rs
new file mode 100644
index 0000000..923488e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3654.rs
@@ -0,0 +1,3 @@
+type Meeshka = Mow<!>;
+// { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 }
+type Mow = &'static fn(!) -> !;
diff --git a/gcc/testsuite/rust/compile/issue-3656.rs b/gcc/testsuite/rust/compile/issue-3656.rs
new file mode 100644
index 0000000..e0bec2f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3656.rs
@@ -0,0 +1,10 @@
+enum Foo {
+ Bar(isize),
+}
+
+fn main() {
+ match Foo::Bar(205) {
+ Foo { i } => (),
+ // { dg-error "expected struct, variant or union type, found enum .Foo. .E0574." "" { target *-*-* } .-1 }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3657.rs b/gcc/testsuite/rust/compile/issue-3657.rs
new file mode 100644
index 0000000..978f3ce
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3657.rs
@@ -0,0 +1,8 @@
+struct Foo<'_>(&'_ u8);
+
+impl Foo<'a> {
+ // { dg-error "unresolved lifetime" "" { target *-*-* } .-1 }
+ fn x() {}
+}
+
+fn x() {}
diff --git a/gcc/testsuite/rust/compile/issue-3659.rs b/gcc/testsuite/rust/compile/issue-3659.rs
new file mode 100644
index 0000000..ffbc634
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3659.rs
@@ -0,0 +1,10 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ let x = 3;
+
+ match x {
+ 0..-1 => 2, // { dg-error "lower range bound must be less than upper .E0579." }
+ _ => 3,
+ };
+}
diff --git a/gcc/testsuite/rust/compile/issue-3660.rs b/gcc/testsuite/rust/compile/issue-3660.rs
new file mode 100644
index 0000000..1f1c583
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3660.rs
@@ -0,0 +1,3 @@
+pub static A: [u32; 2] = [1, 2];
+
+pub static B: [u8; 2] = [3, 4];
diff --git a/gcc/testsuite/rust/compile/issue-3661.rs b/gcc/testsuite/rust/compile/issue-3661.rs
new file mode 100644
index 0000000..8d03c36
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3661.rs
@@ -0,0 +1,10 @@
+pub macro m($inner_str:expr) {
+ #[m = $inner_str]
+ // { dg-error "macro not found" "" { target *-*-* } .-1 }
+
+ struct S;
+}
+
+fn main() {
+ m!(stringify!(foo));
+}
diff --git a/gcc/testsuite/rust/compile/issue-3662.rs b/gcc/testsuite/rust/compile/issue-3662.rs
new file mode 100644
index 0000000..88baa2e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3662.rs
@@ -0,0 +1,8 @@
+pub fn rlib() {
+ let _ = ((-1 as i8) << 8 - 1) as f32;
+ let _ = 0u8 as char;
+ let _ = true > false;
+ let _ = true >= false;
+ let _ = true < false;
+ let _ = true >= false;
+}
diff --git a/gcc/testsuite/rust/compile/issue-3663.rs b/gcc/testsuite/rust/compile/issue-3663.rs
new file mode 100644
index 0000000..0f0559c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3663.rs
@@ -0,0 +1,6 @@
+pub trait TypeFn {}
+
+impl TypeFn for Output<{ 42 }> {
+ // { dg-error "could not resolve type path .Output. .E0412." "" { target *-*-* } .-1 }
+ type Output = ();
+}
diff --git a/gcc/testsuite/rust/compile/issue-3664.rs b/gcc/testsuite/rust/compile/issue-3664.rs
new file mode 100644
index 0000000..c52a758
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3664.rs
@@ -0,0 +1,5 @@
+const ARR: [usize; 1] = [2];
+
+pub fn l8() {
+ let _ = 5 << ARR[0];
+}
diff --git a/gcc/testsuite/rust/compile/issue-3665.rs b/gcc/testsuite/rust/compile/issue-3665.rs
new file mode 100644
index 0000000..d66a81f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3665.rs
@@ -0,0 +1,6 @@
+pub const uint_val: usize = 1;
+pub const uint_expr: usize = 1 << uint_val;
+
+pub fn test() -> usize {
+ uint_expr
+}
diff --git a/gcc/testsuite/rust/compile/issue-3667.rs b/gcc/testsuite/rust/compile/issue-3667.rs
new file mode 100644
index 0000000..e72069c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3667.rs
@@ -0,0 +1,24 @@
+// { dg-options "-w" }
+#![feature(raw_ref_op)]
+
+const pq1: () = {
+ let mut x = 2;
+ &raw mut x;
+}; //~ mutable reference
+
+static B: () = {
+ let mut x = 2;
+ &raw mut x;
+}; //~ mutable reference
+
+static mut C: () = {
+ let mut x = 2;
+ &raw mut x;
+}; //~ mutable reference
+
+const fn foo() {
+ let mut x = 0;
+ let y = &raw mut x; //~ mutable reference
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3671.rs b/gcc/testsuite/rust/compile/issue-3671.rs
new file mode 100644
index 0000000..8015653
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3671.rs
@@ -0,0 +1,2 @@
+impl Foo<0> {}
+// { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/issue-3711.rs b/gcc/testsuite/rust/compile/issue-3711.rs
new file mode 100644
index 0000000..911d4ad
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3711.rs
@@ -0,0 +1,18 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn returns_closure() -> _ {
+ // { dg-error "the type placeholder ._. is not allowed within types on item signatures .E0121." "" { target *-*-* } .-1 }
+ || 0
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3726.rs b/gcc/testsuite/rust/compile/issue-3726.rs
new file mode 100644
index 0000000..ced87a5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3726.rs
@@ -0,0 +1,17 @@
+pub enum TypeCtor {
+ Slice,
+ Array,
+}
+pub struct ApplicationTy(TypeCtor);
+
+macro_rules! ty_app {
+ ($ctor:pat) => {
+ ApplicationTy($ctor)
+ };
+}
+
+pub fn foo(ty: ApplicationTy) {
+ match ty {
+ ty_app!(TypeCtor::Array) => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3836.rs b/gcc/testsuite/rust/compile/issue-3836.rs
new file mode 100644
index 0000000..8cc661f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3836.rs
@@ -0,0 +1,69 @@
+// { dg-options "-w" }
+#![feature(lang_items)]
+
+mod core {
+ mod option {
+ pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+ }
+ }
+
+ mod marker {
+ #[lang = "sized"]
+ pub trait Sized {}
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ pub enum Ordering {
+ Less = -1,
+ Equal = 0,
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[lang = "partial_ord"]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ }
+ }
+}
+
+use core::cmp::{Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ false
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Option::Some(Ordering::Equal)
+ }
+}
+
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &'_ Self) -> bool {
+ ::core::cmp::PartialEq::eq(&self.a, &other.a)
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3874.rs b/gcc/testsuite/rust/compile/issue-3874.rs
new file mode 100644
index 0000000..ebce4b6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3874.rs
@@ -0,0 +1,4 @@
+fn wow(){
+ &#[serde]
+ // { dg-error "found unexpected token .#. in null denotation" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3876.rs b/gcc/testsuite/rust/compile/issue-3876.rs
new file mode 100644
index 0000000..17b1590
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3876.rs
@@ -0,0 +1,8 @@
+enum test {
+ A(i32),
+}
+
+fn fun(x: i32) {
+ test::A { x }
+ // { dg-error "unknown field" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3885.rs b/gcc/testsuite/rust/compile/issue-3885.rs
new file mode 100644
index 0000000..050a59c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3885.rs
@@ -0,0 +1,7 @@
+pub fn test() {
+ let _u: [_; _] = [15u32];
+ let _v: [u8; _] = [1, 2, 3];
+ let _w: [_; 2] = [1.0, 2.0];
+ let _x = [42; 5];
+ let _y: [_; _] = _x;
+}
diff --git a/gcc/testsuite/rust/compile/issue-3898.rs b/gcc/testsuite/rust/compile/issue-3898.rs
new file mode 100644
index 0000000..8199267
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3898.rs
@@ -0,0 +1,113 @@
+// { dg-additional-options "-frust-compile-until=lowering" }
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ Ok(T),
+ Err(E),
+}
+
+use Result::{Err, Ok};
+
+struct Utf8Error;
+
+const CONT_MASK: u8 = 15;
+const TAG_CONT_U8: u8 = 15;
+
+#[inline(always)]
+pub fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
+ let mut index = 0;
+ let len = 64;
+
+ let usize_bytes = 8;
+ let ascii_block_size = 2 * usize_bytes;
+ let blocks_end = if len >= ascii_block_size {
+ len - ascii_block_size + 1
+ } else {
+ 0
+ };
+
+ while index < len {
+ let old_offset = index;
+ macro_rules! err {
+ ($error_len: expr) => {
+ return Err(Utf8Error)
+ };
+ }
+
+ macro_rules! next {
+ () => {{
+ index += 1;
+ // we needed data, but there was none: error!
+ if index >= len {
+ err!(None)
+ }
+ v[index]
+ }};
+ }
+
+ let first = v[index];
+ if first >= 128 {
+ let w = 15;
+ // 2-byte encoding is for codepoints \u{0080} to \u{07ff}
+ // first C2 80 last DF BF
+ // 3-byte encoding is for codepoints \u{0800} to \u{ffff}
+ // first E0 A0 80 last EF BF BF
+ // excluding surrogates codepoints \u{d800} to \u{dfff}
+ // ED A0 80 to ED BF BF
+ // 4-byte encoding is for codepoints \u{1000}0 to \u{10ff}ff
+ // first F0 90 80 80 last F4 8F BF BF
+ //
+ // Use the UTF-8 syntax from the RFC
+ //
+ // https://tools.ietf.org/html/rfc3629
+ // UTF8-1 = %x00-7F
+ // UTF8-2 = %xC2-DF UTF8-tail
+ // UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
+ // %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
+ // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
+ // %xF4 %x80-8F 2( UTF8-tail )
+ match w {
+ 2 => {
+ if next!() & !CONT_MASK != TAG_CONT_U8 {
+ err!(Some(1))
+ }
+ }
+ 3 => {
+ match (first, next!()) {
+ (0xE0, 0xA0..=0xBF)
+ | (0xE1..=0xEC, 0x80..=0xBF)
+ | (0xED, 0x80..=0x9F)
+ | (0xEE..=0xEF, 0x80..=0xBF) => {}
+ _ => err!(Some(1)),
+ }
+ if next!() & !CONT_MASK != TAG_CONT_U8 {
+ err!(Some(2))
+ }
+ }
+ 4 => {
+ match (first, next!()) {
+ (0xF0, 0x90..=0xBF) | (0xF1..=0xF3, 0x80..=0xBF) | (0xF4, 0x80..=0x8F) => {}
+ _ => err!(Some(1)),
+ }
+ if next!() & !CONT_MASK != TAG_CONT_U8 {
+ err!(Some(2))
+ }
+ if next!() & !CONT_MASK != TAG_CONT_U8 {
+ err!(Some(3))
+ }
+ }
+ _ => err!(Some(1)),
+ }
+ index += 1;
+ } else {
+ index += 1;
+ }
+ }
+
+ Ok(())
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3915.rs b/gcc/testsuite/rust/compile/issue-3915.rs
new file mode 100644
index 0000000..5cd8dc0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3915.rs
@@ -0,0 +1,30 @@
+// { dg-options "-w" }
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Trait {
+ fn do_thing();
+}
+
+struct MyType;
+
+impl Trait for MyType {
+ fn do_thing() {}
+}
+
+struct Wrapper<T: Trait> {
+ value: T,
+}
+
+impl<T: Trait> Wrapper<T> {
+ fn call_it() {
+ T::do_thing();
+ }
+}
+
+fn main() {
+ let _ = Wrapper::<MyType> { value: MyType };
+ Wrapper::<MyType>::call_it();
+}
diff --git a/gcc/testsuite/rust/compile/issue-3916.rs b/gcc/testsuite/rust/compile/issue-3916.rs
new file mode 100644
index 0000000..c4adb64
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3916.rs
@@ -0,0 +1,36 @@
+#![feature(rustc_attrs, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "add"]
+trait Add<Rhs = Self> {
+ type Output;
+
+ fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ impl Add for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn add(self, other: $t) -> $t { self + other }
+ }
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+pub fn test(len: usize) -> u64 {
+ let mut i = 0;
+ let mut out = 0;
+ if i + 3 < len {
+ out = 123;
+ } else {
+ out = 456;
+ }
+ out
+}
diff --git a/gcc/testsuite/rust/compile/issue-3922.rs b/gcc/testsuite/rust/compile/issue-3922.rs
new file mode 100644
index 0000000..3c07f94
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3922.rs
@@ -0,0 +1,12 @@
+struct S(
+ [u8; {
+ {
+ // { dg-error "mismatched types. expected .... but got ..integer.. .E0308." "" { target *-*-* } .-1 }
+ struct Z;
+ 0
+ }
+ 0
+ }],
+);
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3924.rs b/gcc/testsuite/rust/compile/issue-3924.rs
new file mode 100644
index 0000000..cc423ce
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3924.rs
@@ -0,0 +1,6 @@
+pub fn main() {
+ const S: usize = 23 as i64;
+ // { dg-error {mismatched types, expected .usize. but got .i64.} "" { target *-*-* } .-1 }
+ [0; S];
+ ()
+}
diff --git a/gcc/testsuite/rust/compile/issue-3928.rs b/gcc/testsuite/rust/compile/issue-3928.rs
new file mode 100644
index 0000000..639d4c8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3928.rs
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-options "-fsyntax-only" }
+
+#![feature(exclusive_range_pattern)]
+
+fn Foo() {
+ let x = 1u32;
+
+ match x {
+ 3..-1 => 4,
+ };
+}
diff --git a/gcc/testsuite/rust/compile/issue-3929-1.rs b/gcc/testsuite/rust/compile/issue-3929-1.rs
new file mode 100644
index 0000000..3d7b056
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3929-1.rs
@@ -0,0 +1,9 @@
+// { dg-options "-w" }
+struct S();
+
+fn main() {
+ let s = S{};
+ match s {
+ S{..} => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3929-2.rs b/gcc/testsuite/rust/compile/issue-3929-2.rs
new file mode 100644
index 0000000..5f45a7c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3929-2.rs
@@ -0,0 +1,12 @@
+// { dg-options "-w" }
+struct S {
+ x: i32,
+ y: i32,
+}
+
+fn main() {
+ let s = S{x: 1, y: 2};
+ match s {
+ S{x: 1, ..} => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3930.rs b/gcc/testsuite/rust/compile/issue-3930.rs
new file mode 100644
index 0000000..dfcd19a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3930.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-w" }
+fn main() {
+ let (a, .., b) = (2, 3);
+}
diff --git a/gcc/testsuite/rust/compile/issue-3947.rs b/gcc/testsuite/rust/compile/issue-3947.rs
new file mode 100644
index 0000000..58ccde6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3947.rs
@@ -0,0 +1,10 @@
+enum _Enum {
+ A(),
+}
+
+type _E = _Enum;
+
+// { dg-warning "function is never used: '_a'" "" { target *-*-* } .+1 }
+const fn _a() -> _Enum {
+ _E::A()
+}
diff --git a/gcc/testsuite/rust/compile/issue-3958.rs b/gcc/testsuite/rust/compile/issue-3958.rs
new file mode 100644
index 0000000..935b512
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3958.rs
@@ -0,0 +1,11 @@
+// { dg-options "-fsyntax-only" }
+trait A {
+ fn a(&self) -> <Self as A>::X;
+}
+
+impl A for u32 {}
+
+fn main() {
+ let a: u32 = 0;
+ let b: u32 = a.a();
+}
diff --git a/gcc/testsuite/rust/compile/issue-3960.rs b/gcc/testsuite/rust/compile/issue-3960.rs
new file mode 100644
index 0000000..57329f0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3960.rs
@@ -0,0 +1,7 @@
+fn main() {
+ struct G {
+ g: (),
+ }
+ let g = [0; G { g: () }];
+ // { dg-error "mismatched types, expected .usize. but got .G. .E0308." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3965-1.rs b/gcc/testsuite/rust/compile/issue-3965-1.rs
new file mode 100644
index 0000000..291a220
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3965-1.rs
@@ -0,0 +1,4 @@
+fn main() {
+ [(); { continue }];
+ // { dg-error ".continue. outside of a loop .E0268." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3965-2.rs b/gcc/testsuite/rust/compile/issue-3965-2.rs
new file mode 100644
index 0000000..d48503f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3965-2.rs
@@ -0,0 +1,7 @@
+fn main() {
+ loop { continue }
+
+ [(); {while true {break}; 0}];
+
+ [(); {while true {break}; 0}];
+}
diff --git a/gcc/testsuite/rust/compile/issue-3966.rs b/gcc/testsuite/rust/compile/issue-3966.rs
new file mode 100644
index 0000000..20d3031
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3966.rs
@@ -0,0 +1,5 @@
+struct S {
+ #[cfg_attr()]
+ field: u8,
+ // { dg-error "malformed .cfg_attr. attribute input" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3969.rs b/gcc/testsuite/rust/compile/issue-3969.rs
new file mode 100644
index 0000000..6715978
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3969.rs
@@ -0,0 +1,32 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+pub trait Sized {
+ // Empty.
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn main() {
+ [(); {
+ while true {
+ // { dg-error ".constexpr. loop iteration count exceeds limit" "" { target *-*-* } .-1 }
+ break 9;
+ // { dg-error "can only .break. with a value inside a .loop. block .E0571." "" { target *-*-* } .-1 }
+ }
+ 51
+ }];
+
+ while true {
+ break (|| {
+ // { dg-error "can only .break. with a value inside a .loop. block .E0571." "" { target *-*-* } .-1 }
+ let while_true = 9;
+ });
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3971.rs b/gcc/testsuite/rust/compile/issue-3971.rs
new file mode 100644
index 0000000..5607d2d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3971.rs
@@ -0,0 +1,11 @@
+#[lang = "copy"]
+trait Copy {}
+
+// since the macro expansion fails, the current nameres fixpoint error is emitted - just accept it for now
+#[derive(Copy)]
+// { dg-error "derive may only be applied to structs, enums and unions" "" { target *-*-* } .-1 }
+// { dg-excess-errors "could not resolve trait" }
+
+pub fn check_ge(a: i32, b: i32) -> bool {
+ a >= b
+}
diff --git a/gcc/testsuite/rust/compile/issue-3974.rs b/gcc/testsuite/rust/compile/issue-3974.rs
new file mode 100644
index 0000000..dfd693a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3974.rs
@@ -0,0 +1,8 @@
+impl<'a, F> RunUntil<'a, F> {
+ // { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
+ fn project<'pin>() -> Projection<'pin, 'a, F> {
+ // { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
+ Self!()
+ // { dg-error "could not resolve macro invocation" "" { target *-*-* } .-1 }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3978.rs b/gcc/testsuite/rust/compile/issue-3978.rs
new file mode 100644
index 0000000..4f17d3d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3978.rs
@@ -0,0 +1,8 @@
+type Dimension = usize;
+
+pub fn main() {}
+
+mod m2 {
+ fn main() {}
+ // { dg-warning "function is never used" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-4006.rs b/gcc/testsuite/rust/compile/issue-4006.rs
new file mode 100644
index 0000000..328c7b6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4006.rs
@@ -0,0 +1,13 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+ () => {};
+}
+
+pub fn main() {
+ asm!(
+ "xor eax, eax"
+ "xor eax, eax");
+ // { dg-error "expected token .;." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-402.rs b/gcc/testsuite/rust/compile/issue-402.rs
new file mode 100644
index 0000000..ec398e9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-402.rs
@@ -0,0 +1,15 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+struct GenericStruct<T>(T, usize);
+
+pub fn test() -> GenericStruct<_> {
+ // { dg-error "the type placeholder ._. is not allowed within types on item signatures .E0121." "" { target *-*-* } .-1 }
+ GenericStruct(1, 2)
+}
+
+fn square(num: i32) -> _ {
+ // { dg-error "the type placeholder ._. is not allowed within types on item signatures .E0121." "" { target *-*-* } .-1 }
+ num * num
+}
diff --git a/gcc/testsuite/rust/compile/issue-407-2.rs b/gcc/testsuite/rust/compile/issue-407-2.rs
index 2d60d6d..6dad861 100644
--- a/gcc/testsuite/rust/compile/issue-407-2.rs
+++ b/gcc/testsuite/rust/compile/issue-407-2.rs
@@ -2,15 +2,8 @@
pub fn loopy() {
let mut a = 1;
loop {
- // { dg-error {failed to parse statement or expression in block expression} "" { target *-*-* } .-1 }
if a < 40 {
- // { dg-error {failed to parse statement or expression in block expression} "" { target *-*-* } .-1 }
a + = 1; // { dg-error "found unexpected token '=' in null denotation" }
- // { dg-error {failed to parse statement or expression in block expression} "" { target *-*-* } .-1 }
- // { dg-error {failed to parse if body block expression in if expression} "" { target *-*-* } .-2 }
- // { dg-error {could not parse loop body in \(infinite\) loop expression} "" { target *-*-* } .-3 }
- // { dg-error {unrecognised token 'integer literal' for start of item} "" { target *-*-* } .-4 }
- // { dg-error {failed to parse item in crate} "" { target *-*-* } .-5 }
} else {
break;
}
diff --git a/gcc/testsuite/rust/compile/issue-407.rs b/gcc/testsuite/rust/compile/issue-407.rs
index bd0d306..3a9dbeb 100644
--- a/gcc/testsuite/rust/compile/issue-407.rs
+++ b/gcc/testsuite/rust/compile/issue-407.rs
@@ -2,7 +2,4 @@
fn test() {
let mut a = 1;
a + = 1; // { dg-error "found unexpected token '=' in null denotation" }
- // { dg-error {failed to parse statement or expression in block expression} "" { target *-*-* } .-1 }
- // { dg-error {unrecognised token 'integer literal' for start of item} "" { target *-*-* } .-2 }
- // { dg-error {failed to parse item in crate} "" { target *-*-* } .-3 }
}
diff --git a/gcc/testsuite/rust/compile/issue-4090-1.rs b/gcc/testsuite/rust/compile/issue-4090-1.rs
new file mode 100644
index 0000000..0411943
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4090-1.rs
@@ -0,0 +1,70 @@
+#![feature(lang_items)]
+
+mod core {
+ mod marker {
+ #[lang = "sized"]
+ pub trait Sized {}
+
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+ }
+
+ pub mod cmp {
+ use super::marker::Sized;
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ pub trait Eq: PartialEq<Self> {
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+ }
+
+ pub mod ptr {
+
+ use super::cmp::{Eq, PartialEq};
+
+ macro_rules! fnptr_impls_safety_abi {
+ ($FnTy: ty, $($Arg: ident),*) => {
+ #[stable(feature = "fnptr_impls", since = "1.4.0")]
+ impl<Ret, $($Arg),*> PartialEq for $FnTy {
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ *self as usize == *other as usize
+ }
+ }
+
+ #[stable(feature = "fnptr_impls", since = "1.4.0")]
+ impl<Ret, $($Arg),*> Eq for $FnTy {}
+
+ }
+ }
+
+ fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, }
+ }
+}
+
+#[derive(PartialEq, Eq)]
+struct AllowedBelow {
+ // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+ f: fn(),
+}
diff --git a/gcc/testsuite/rust/compile/issue-4090-2.rs b/gcc/testsuite/rust/compile/issue-4090-2.rs
new file mode 100644
index 0000000..7b76c0a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4090-2.rs
@@ -0,0 +1,73 @@
+#![feature(lang_items)]
+
+mod core {
+ mod marker {
+ #[lang = "sized"]
+ pub trait Sized {}
+
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+ }
+
+ pub mod cmp {
+ use super::marker::Sized;
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ pub trait Eq: PartialEq<Self> {
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+ }
+
+ pub mod ptr {
+
+ use super::cmp::{Eq, PartialEq};
+
+ macro_rules! fnptr_impls_safety_abi {
+ ($FnTy: ty, $($Arg: ident),*) => {
+ #[stable(feature = "fnptr_impls", since = "1.4.0")]
+ impl<Ret, $($Arg),*> PartialEq for $FnTy {
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ *self as usize == *other as usize
+ }
+ }
+
+ #[stable(feature = "fnptr_impls", since = "1.4.0")]
+ impl<Ret, $($Arg),*> Eq for $FnTy {}
+
+ }
+ }
+
+ fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, }
+ fnptr_impls_safety_abi! { extern "C" fn() -> Ret, }
+ fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, }
+ fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, }
+ }
+}
+
+#[derive(PartialEq, Eq)]
+struct AllowedBelow {
+ // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+ f: fn(),
+}
diff --git a/gcc/testsuite/rust/compile/issue-4139.rs b/gcc/testsuite/rust/compile/issue-4139.rs
new file mode 100644
index 0000000..dc62d1c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4139.rs
@@ -0,0 +1,7 @@
+// { dg-skip-if "" { *-*-* } { "-m32" } { "" } }
+const X: i32 = const {
+ let a = 0x736f6d6570736575;
+ // { dg-error "integer overflows the respective type" "" { target *-*-* } .-1 }
+ let b = 14;
+ a + b
+};
diff --git a/gcc/testsuite/rust/compile/issue-4140-1.rs b/gcc/testsuite/rust/compile/issue-4140-1.rs
new file mode 100644
index 0000000..8b68b3e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4140-1.rs
@@ -0,0 +1,18 @@
+pub enum TypeCtor {
+ Slice,
+ Array,
+}
+pub struct B<T>(T);
+
+macro_rules! ty_app {
+ ($_a:pat) => {
+ ApplicationTy($ctor) // { dg-error "unexpected token" }
+ // { dg-error "failed to parse tuple struct items" "" { target *-*-* } .-1 }
+ };
+}
+
+pub fn foo(ty: ApplicationTy) { // { dg-error "could not resolve type path 'ApplicationTy'" }
+ match ty {
+ ty_app!(bean::Array) => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-4140-2.rs b/gcc/testsuite/rust/compile/issue-4140-2.rs
new file mode 100644
index 0000000..bcccddb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4140-2.rs
@@ -0,0 +1,12 @@
+macro_rules! ty_app {
+ ($_a:pat) => {
+ ($ctor)
+ };
+}
+
+pub fn foo() {
+ match ty {
+ // { dg-error "Cannot find path" "4140" { target *-*-* } 0 }
+ ty_app!(bean::Array) => {} // { dg-error "unrecognised token" "4140" { target *-*-* } 0 }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-4145.rs b/gcc/testsuite/rust/compile/issue-4145.rs
new file mode 100644
index 0000000..98b33ca
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4145.rs
@@ -0,0 +1,13 @@
+// { dg-excess-errors "warnings" }
+
+struct S {
+ field: [u8; {
+ #[path = "outer/inner.rs"]
+ // { dg-warning "error handling module file for .inner." "#4145" { xfail *-*-* } .+1 }
+ mod inner;
+ // OK
+ 0
+ }],
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-4146.rs b/gcc/testsuite/rust/compile/issue-4146.rs
new file mode 100644
index 0000000..efb3ee2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4146.rs
@@ -0,0 +1,3 @@
+const _NISIZE_DIV_P: &isize = &(1isize / 0);
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+// { dg-error "is not a constant expression" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/issue-4148.rs b/gcc/testsuite/rust/compile/issue-4148.rs
new file mode 100644
index 0000000..599d739
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4148.rs
@@ -0,0 +1,26 @@
+// { dg-excess-errors "warnings" }
+
+// TODO: all `xfail` conditions should be changed to `target` once the ICE in #4148 is resolved
+
+pub fn ret_parens(x: i32) -> i32 {
+ // { dg-warning "unnecessary parentheses around block return value" "#4148" { xfail *-*-* } .+1 }
+ ((x+1))
+}
+
+// { dg-warning "unnecessary parentheses around type" "#4148" { xfail *-*-* } .+1 }
+// { dg-warning "unnecessary parentheses around pattern" "#4148" { xfail *-*-* } .+1 }
+pub fn arg_ret_parens((x): (i32)) -> (i32) {
+ // { dg-warning "unnecessary parentheses around block return value" "#4148" { xfail *-*-* } .+1 }
+ ((x+1))
+}
+
+// { dg-warning "unnecessary parentheses around type" "#4148" { xfail *-*-* } .+1 }
+pub fn ret_rpit_parens2(x: i32) -> (i32) {
+ // { dg-warning "unnecessary parentheses around block return value" "#4148" { xfail *-*-* } .+1 }
+ ((x+1))
+}
+
+pub fn ret_parens3(x: i32) -> i32 {
+ // { dg-warning "unnecessary parentheses around block return value" "#4148" { xfail *-*-* } .+1 }
+ ((x+1))
+}
diff --git a/gcc/testsuite/rust/compile/issue-4155.rs b/gcc/testsuite/rust/compile/issue-4155.rs
new file mode 100644
index 0000000..9fae613
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4155.rs
@@ -0,0 +1,7 @@
+struct Bug {
+ inner: [(); match Vec::new {
+ f @ |n() => 1
+// { dg-error "failed to parse pattern to bind" "" { target *-*-* } .-1 }
+// { dg-error "unexpected token .|. in pattern" "" { target *-*-* } .-2 }
+ }],
+}
diff --git a/gcc/testsuite/rust/compile/issue-4162.rs b/gcc/testsuite/rust/compile/issue-4162.rs
new file mode 100644
index 0000000..ffaa92d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4162.rs
@@ -0,0 +1,6 @@
+pub fn main() {
+ while let = 5
+ // { dg-error "should be at least 1 pattern" "" { target *-*-* } .-1 }
+ {}
+}
+
diff --git a/gcc/testsuite/rust/compile/issue-4165.rs b/gcc/testsuite/rust/compile/issue-4165.rs
new file mode 100644
index 0000000..bc513da
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4165.rs
@@ -0,0 +1,12 @@
+const N: usize = 2;
+const ARR: [i32; N] = [42; X];
+// { dg-error {cannot find value .X. in this scope \[E0425\]} "" { target *-*-* } .-1 }
+// { dg-error {mismatched types, expected .\[i32; 2]. but got .<tyty::error>. \[E0308\]} "" { target *-*-* } .-2 }
+// { dg-error {mismatched types, expected .usize. but got .bool. \[E0308\]} "" { target *-*-* } .-3 }
+const X: bool = (N[0] == 99) && (ARR[0] == 0);
+// { dg-error {the type .usize. cannot be indexed by .<integer>. \[E0277\]} "" { target *-*-* } .-1 }
+// { dg-error {mismatched types, expected .<tyty::error>. but got .<integer>. \[E0308\]} "" { target *-*-* } .-2 }
+
+fn main() {
+ let _ = X;
+}
diff --git a/gcc/testsuite/rust/compile/issue-4168.rs b/gcc/testsuite/rust/compile/issue-4168.rs
new file mode 100644
index 0000000..abb1190
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4168.rs
@@ -0,0 +1,7 @@
+const fn add(x: usize, y: usize) -> i32 {
+ add + y
+ // { dg-error "cannot apply operator .+. to types fn .x usize,y usize,. -> i32 and usize" "" { target *-*-* } .-1 }
+}
+const ARR: [i32; add(1, 2)] = [5, 6, 1];
+// { dg-error "mismatched types, expected .usize. but got .i32. .E0308." "" { target *-*-* } .-1 }
+// { dg-error "mismatched types" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/issue-4188.rs b/gcc/testsuite/rust/compile/issue-4188.rs
new file mode 100644
index 0000000..32b175d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4188.rs
@@ -0,0 +1,13 @@
+trait MemoryUnit {
+ extern "C" fn read_dword(&'s self) -> u16 {}
+ // { dg-error {failed to resolve lifetime} "" { target *-*-* } .-1 }
+ // { dg-error {mismatched types} "" { target *-*-* } .-2 }
+}
+
+impl MemoryUnit for MemoryUnit {
+ extern "C" fn read_dword(&'s self) -> u16 {
+ let b16 = self.read_word() as u16;
+
+ b16 << 8
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-4212.rs b/gcc/testsuite/rust/compile/issue-4212.rs
new file mode 100644
index 0000000..e7bf113
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4212.rs
@@ -0,0 +1,5 @@
+#![derive(PartialOrd, PartialEq)]
+// { dg-error "attribute cannot be used at crate level" "" { target *-*-* } .-1 }
+pub fn check_ge(a: i32, b: i32) -> bool {
+ a >= b
+}
diff --git a/gcc/testsuite/rust/compile/issue-4219.rs b/gcc/testsuite/rust/compile/issue-4219.rs
new file mode 100644
index 0000000..d6e70e9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4219.rs
@@ -0,0 +1,5 @@
+#![inline]
+// { dg-error "attribute cannot be used at crate level" "" { target *-*-* } .-1 }
+pub fn check_ge(a: i32, b: i32) -> bool {
+ a >= b
+}
diff --git a/gcc/testsuite/rust/compile/issue-4222.rs b/gcc/testsuite/rust/compile/issue-4222.rs
new file mode 100644
index 0000000..b829c6f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4222.rs
@@ -0,0 +1,3 @@
+#![cfg(false)]
+// { dg-error ".false. predicate key cannot be a literal" "" { target *-*-* } .-1 }
+fn a() {}
diff --git a/gcc/testsuite/rust/compile/issue-4226.rs b/gcc/testsuite/rust/compile/issue-4226.rs
new file mode 100644
index 0000000..553faf2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4226.rs
@@ -0,0 +1,3 @@
+#[doc]
+// { dg-error "attribute must be of the form ...doc.hidden.inline....... or ...doc = string.." "" { target *-*-* } .-1 }
+pub fn a(){}
diff --git a/gcc/testsuite/rust/compile/issue-4231.rs b/gcc/testsuite/rust/compile/issue-4231.rs
new file mode 100644
index 0000000..4629baa
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4231.rs
@@ -0,0 +1,6 @@
+#[repr = ""] // { dg-error "malformed .repr. attribute" }
+struct ThreeInts {
+ first: i16,
+ second: i8,
+ third: i32
+}
diff --git a/gcc/testsuite/rust/compile/issue-4242.rs b/gcc/testsuite/rust/compile/issue-4242.rs
new file mode 100644
index 0000000..ecbe258
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4242.rs
@@ -0,0 +1,10 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ let x = 1;
+
+ match x {
+ -55..0 => 2,
+ -99..-55 => 3,
+ };
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/issue-4261.rs b/gcc/testsuite/rust/compile/issue-4261.rs
new file mode 100644
index 0000000..32beafa
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4261.rs
@@ -0,0 +1,3 @@
+#[cfg()]
+// { dg-error "malformed .cfg. attribute input" "" { target *-*-* } .-1 }
+fn a() {}
diff --git a/gcc/testsuite/rust/compile/issue-4262.rs b/gcc/testsuite/rust/compile/issue-4262.rs
new file mode 100644
index 0000000..2ce1cb4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4262.rs
@@ -0,0 +1,3 @@
+#[cfg]
+// { dg-error ".cfg. is not followed by parentheses" "" { target *-*-* } .-1 }
+fn a() {}
diff --git a/gcc/testsuite/rust/compile/issue-4267.rs b/gcc/testsuite/rust/compile/issue-4267.rs
new file mode 100644
index 0000000..f507748
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4267.rs
@@ -0,0 +1,3 @@
+#[cfg(a,a)]
+// { dg-error "multiple .cfg. predicates are specified" "" { target *-*-* } .-1 }
+fn a(){}
diff --git a/gcc/testsuite/rust/compile/issue-850.rs b/gcc/testsuite/rust/compile/issue-850.rs
index e42b557..c6a5f31 100644
--- a/gcc/testsuite/rust/compile/issue-850.rs
+++ b/gcc/testsuite/rust/compile/issue-850.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-855.rs b/gcc/testsuite/rust/compile/issue-855.rs
index 9e450dd..3736d08 100644
--- a/gcc/testsuite/rust/compile/issue-855.rs
+++ b/gcc/testsuite/rust/compile/issue-855.rs
@@ -1,3 +1,5 @@
+#![feature(lang_items)]
+
pub use result::Result::{self, Err, Ok};
#[lang = "sized"]
diff --git a/gcc/testsuite/rust/compile/issue-867.rs b/gcc/testsuite/rust/compile/issue-867.rs
index e5f9b29..1aa29b3 100644
--- a/gcc/testsuite/rust/compile/issue-867.rs
+++ b/gcc/testsuite/rust/compile/issue-867.rs
@@ -1,8 +1,4 @@
fn main() {
let _ = 42;
let a = _ + 123; // { dg-error "use of '_' is not allowed on the right-side of an assignment" }
- // { dg-error {failed to parse expression in let statement} "" { target *-*-* } .-1 }
- // { dg-error {failed to parse statement or expression in block expression} "" { target *-*-* } .-2 }
- // { dg-error {unrecognised token '\}' for start of item} "" { target *-*-* } .+2 }
- // { dg-error {failed to parse item in crate} "" { target *-*-* } .+1 }
}
diff --git a/gcc/testsuite/rust/compile/issue-925.rs b/gcc/testsuite/rust/compile/issue-925.rs
index 507fe94..34c611b 100644
--- a/gcc/testsuite/rust/compile/issue-925.rs
+++ b/gcc/testsuite/rust/compile/issue-925.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/iterators1.rs b/gcc/testsuite/rust/compile/iterators1.rs
index 35fea5a..4bbc47e 100644
--- a/gcc/testsuite/rust/compile/iterators1.rs
+++ b/gcc/testsuite/rust/compile/iterators1.rs
@@ -1,4 +1,4 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, lang_items)]
pub use option::Option::{self, None, Some};
pub use result::Result::{self, Err, Ok};
@@ -98,30 +98,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -129,12 +129,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -142,7 +142,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -151,31 +151,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -190,7 +190,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -200,7 +200,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
@@ -210,48 +210,30 @@ macro_rules! impl_uint {
impl $ty {
pub fn wrapping_add(self, rhs: Self) -> Self {
unsafe {
- intrinsics::wrapping_add(self, rhs)
+ crate::intrinsics::wrapping_add(self, rhs)
}
}
pub fn wrapping_sub(self, rhs: Self) -> Self {
unsafe {
- intrinsics::wrapping_sub(self, rhs)
+ crate::intrinsics::wrapping_sub(self, rhs)
}
}
pub fn rotate_left(self, n: u32) -> Self {
unsafe {
- intrinsics::rotate_left(self, n as Self)
+ crate::intrinsics::rotate_left(self, n as Self)
}
}
pub fn rotate_right(self, n: u32) -> Self {
unsafe {
- intrinsics::rotate_right(self, n as Self)
+ crate::intrinsics::rotate_right(self, n as Self)
}
}
- pub fn to_le(self) -> Self {
- #[cfg(target_endian = "little")]
- {
- self
- }
- }
-
- pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
- Self::from_le(Self::from_ne_bytes(bytes))
- }
-
- pub const fn from_le(x: Self) -> Self {
- #[cfg(target_endian = "little")]
- {
- x
- }
- }
-
- pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
- unsafe { mem::transmute(bytes) }
+ pub const fn from_ne_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self {
+ unsafe { crate::mem::transmute(bytes) }
}
pub fn checked_add(self, rhs: Self) -> Option<Self> {
@@ -264,7 +246,7 @@ macro_rules! impl_uint {
}
pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
- let (a, b) = unsafe { intrinsics::add_with_overflow(self as $ty, rhs as $ty) };
+ let (a, b) = unsafe { crate::intrinsics::add_with_overflow(self as $ty, rhs as $ty) };
(a as Self, b)
}
}
@@ -380,12 +362,12 @@ macro_rules! step_identical_methods {
() => {
#[inline]
fn replace_one(&mut self) -> Self {
- mem::replace(self, 1)
+ crate::mem::replace(self, 1)
}
#[inline]
fn replace_zero(&mut self) -> Self {
- mem::replace(self, 0)
+ crate::mem::replace(self, 0)
}
#[inline]
@@ -500,7 +482,7 @@ impl<A: Step> Iterator for Range<A> {
// and this won't actually result in an extra check in an optimized build.
match self.start.add_usize(1) {
Option::Some(mut n) => {
- mem::swap(&mut n, &mut self.start);
+ crate::mem::swap(&mut n, &mut self.start);
Option::Some(n)
}
Option::None => Option::None,
diff --git a/gcc/testsuite/rust/compile/lang_feature_gate.rs b/gcc/testsuite/rust/compile/lang_feature_gate.rs
new file mode 100644
index 0000000..4cd485e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/lang_feature_gate.rs
@@ -0,0 +1,2 @@
+#[lang = "sized"] // { dg-error "lang items are subject to change. add .#!.feature.lang_items... to the crate attributes to enable" }
+pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/loop_constant_context.rs b/gcc/testsuite/rust/compile/loop_constant_context.rs
new file mode 100644
index 0000000..ed0782b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/loop_constant_context.rs
@@ -0,0 +1,5 @@
+// { dg-error "'loop' is not allowed in const context" "" { target *-*-* } .+1 }
+const CONST_LOOP : () = loop{};
+
+// { dg-error "'loop' is not allowed in const context" "" { target *-*-* } .+1 }
+static STATIC_LOOP : () = loop{}; \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/macros/builtin/eager1.rs b/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
index 65a80fd..7c6f6f9 100644
--- a/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
+++ b/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
@@ -15,7 +15,7 @@ macro_rules! b {
}
fn main() {
- // { dg-final { scan-tree-dump-times {"test1canary"} 1 gimple } }
+ // { dg-final { scan-assembler {"test1canary"} } }
let _ = concat!(a!(), 1, b!());
// should not error
concat!(a!(), true, b!(),);
diff --git a/gcc/testsuite/rust/compile/macros/builtin/option_env1.rs b/gcc/testsuite/rust/compile/macros/builtin/option_env1.rs
new file mode 100644
index 0000000..b96c1ee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/builtin/option_env1.rs
@@ -0,0 +1,29 @@
+#![feature(rustc_attrs, lang_items)]
+
+#[rustc_builtin_macro]
+macro_rules! option_env {
+ () => {}
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod option {
+ pub enum Option<T> {
+ #[lang = "Some"]
+ Some(T),
+ #[lang = "None"]
+ None,
+ }
+ }
+}
+
+use core::option::Option;
+
+
+fn main() {
+ // Both a guaranteed-to-exist variable and a failed find should compile
+ let _: Option<&str> = option_env!("PWD");
+ let _: Option<&str> = option_env!("PROBABLY_DOESNT_EXIST");
+}
diff --git a/gcc/testsuite/rust/compile/macros/builtin/option_env2.rs b/gcc/testsuite/rust/compile/macros/builtin/option_env2.rs
new file mode 100644
index 0000000..ef0e563
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/builtin/option_env2.rs
@@ -0,0 +1,27 @@
+#![feature(rustc_attrs, lang_items)]
+
+#[rustc_builtin_macro]
+macro_rules! option_env {
+ () => {}
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod option {
+ pub enum Option<T> {
+ #[lang = "Some"]
+ Some(T),
+ #[lang = "None"]
+ None,
+ }
+ }
+}
+
+use core::option::Option;
+
+fn main() {
+ let _: Option<&str> = option_env!(42);
+ // { dg-error "argument must be a string literal" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/macros/builtin/option_env3.rs b/gcc/testsuite/rust/compile/macros/builtin/option_env3.rs
new file mode 100644
index 0000000..545f3c8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/builtin/option_env3.rs
@@ -0,0 +1,28 @@
+#![feature(rustc_attrs, lang_items)]
+
+#[rustc_builtin_macro]
+macro_rules! option_env {
+ () => {}
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod option {
+ pub enum Option<T> {
+ #[lang = "Some"]
+ Some(T),
+ #[lang = "None"]
+ None,
+ }
+ }
+}
+
+use core::option::Option;
+
+
+fn main() {
+ let _: Option<&str> = option_env!("A","B");
+ // { dg-error "'option_env!' takes 1 argument" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
index 2e73ab5..fbb4b10 100644
--- a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
+++ b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
@@ -15,7 +15,29 @@ macro_rules! a {
};
}
+extern "C" {
+ fn printf(fmt: *const i8, ...);
+}
+
+fn print_ptr(s: &str) {
+ unsafe {
+ printf("%p\n\0" as *const str as *const i8, s as *const str);
+ }
+}
+
+fn print_str(s: &str) {
+ unsafe {
+ printf(
+ "%s\n\0" as *const str as *const i8,
+ s as *const str as *const i8,
+ );
+ }
+}
+
+// { dg-final { scan-assembler {"abheyho(\\0)?"} } }
+static S: &str = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0');
+
fn main() {
- // { dg-final { scan-tree-dump-times {"abheyho"} 1 gimple } }
- let _ = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0');
+ print_ptr(S);
+ print_str(S);
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs
new file mode 100644
index 0000000..e3e702e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs
@@ -0,0 +1,11 @@
+mod foo {
+ macro_rules! bar {
+ () => ()
+ }
+
+ bar! ();
+
+ pub struct S;
+}
+
+pub fn buzz(_: foo::S) {}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue1053-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1053-2.rs
index 3145990..fc96caa 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro-issue1053-2.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1053-2.rs
@@ -1,5 +1,4 @@
macro_rules! m {
($e:expr $(forbidden)*) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-1 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue1395-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1395-2.rs
index 1df6a3a..7ff380d 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro-issue1395-2.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1395-2.rs
@@ -2,6 +2,5 @@
macro_rules! try {
// { dg-error "expecting .identifier. but .try. found" "" { target *-*-* } .-1 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
() => {};
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue1400.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1400.rs
index 5c51b78..0708128 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro-issue1400.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1400.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs
index 637d572..eeae6eb 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs
@@ -18,10 +18,9 @@ fn main() {
// Error
let _ = ReadDir {
+ // { dg-error "unknown field .end_of_stream_but_different. .E0560." "" { target *-*-* } .-1 }
inner: 14,
end_of_stream: false,
- end_of_stream_but_different: false, // { dg-error "failed to resolve type for field" }
- // { dg-error "unknown field" "" { target *-*-* } .-1 }
- // { dg-prune-output "compilation terminated" }
+ end_of_stream_but_different: false,
};
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3608.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3608.rs
new file mode 100644
index 0000000..b081d45
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3608.rs
@@ -0,0 +1,10 @@
+include!(;
+
+struct Baz {
+
+impl Bar for
+
+
+fn main() { )// { dg-error "unexpected closing delimiter .\\)." }
+ // { dg-error "unexpected token .end of file. - expecting closing delimiter .\}. .for a delimited token tree." "" { target *-*-* } .+2 }
+ // { dg-error "unexpected token .end of file. - expecting closing delimiter .\\). .for a macro invocation semi." "" { target *-*-* } .+1 }
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs
new file mode 100644
index 0000000..e990c8b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs
@@ -0,0 +1,10 @@
+macro_rules! generate_pattern_iterators {
+ {
+ $(#[$forward_iterator_attribute:meta])*
+ } => {
+ }
+}
+
+generate_pattern_iterators! {
+ /// Created with the method [`split`].
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
new file mode 100644
index 0000000..bbf0276
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
@@ -0,0 +1,81 @@
+// { dg-additional-options "-frust-compile-until=lowering" }
+#![feature(lang_items)]
+
+macro_rules! impl_fn_for_zst {
+ ($(
+ $( #[$attr: meta] )*
+ struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
+ |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
+ $body: block;
+ )+) => {
+ $(
+ $( #[$attr] )*
+ struct $Name;
+
+ impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
+ #[inline]
+ extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+ $body
+ }
+ }
+
+ impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
+ #[inline]
+ extern "rust-call" fn call_mut(
+ &mut self,
+ ($( $arg, )*): ($( $ArgTy, )*)
+ ) -> $ReturnTy {
+ Fn::call(&*self, ($( $arg, )*))
+ }
+ }
+
+ impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
+ type Output = $ReturnTy;
+
+ #[inline]
+ extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+ Fn::call(&self, ($( $arg, )*))
+ }
+ }
+ )+
+ }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "fn"]
+pub trait Fn<Args>: FnMut<Args> {
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_mut"]
+#[must_use = "closures are lazy and do nothing unless called"]
+pub trait FnMut<Args>: FnOnce<Args> {
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ /// The returned type after the call operator is used.
+ #[lang = "fn_once_output"]
+ #[stable(feature = "fn_once_output", since = "1.12.0")]
+ type Output;
+
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+impl_fn_for_zst! {
+ #[derive(Copy)]
+ struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> () {
+ };
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs
new file mode 100644
index 0000000..6fc3a31
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs
@@ -0,0 +1,10 @@
+macro_rules! doc_comment {
+ (#[ $attr: meta ]) => {
+ #[$attr]
+ struct Generated; // { dg-warning "never constructed" }
+ };
+}
+
+doc_comment! {
+ /// This is a generated struct
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs
new file mode 100644
index 0000000..4d76497
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs
@@ -0,0 +1,82 @@
+// { dg-additional-options "-frust-compile-until=lowering" }
+#![feature(lang_items)]
+
+macro_rules! impl_fn_for_zst {
+ ($(
+ $( #[$attr: meta] )*
+ struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
+ |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
+ $body: block;
+ )+) => {
+ $(
+ $( #[$attr] )*
+ struct $Name;
+
+ impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
+ #[inline]
+ extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+ $body
+ }
+ }
+
+ impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
+ #[inline]
+ extern "rust-call" fn call_mut(
+ &mut self,
+ ($( $arg, )*): ($( $ArgTy, )*)
+ ) -> $ReturnTy {
+ Fn::call(&*self, ($( $arg, )*))
+ }
+ }
+
+ impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
+ type Output = $ReturnTy;
+
+ #[inline]
+ extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+ Fn::call(&self, ($( $arg, )*))
+ }
+ }
+ )+
+ }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "fn"]
+pub trait Fn<Args>: FnMut<Args> {
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_mut"]
+#[must_use = "closures are lazy and do nothing unless called"]
+pub trait FnMut<Args>: FnOnce<Args> {
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ /// The returned type after the call operator is used.
+ #[lang = "fn_once_output"]
+ #[stable(feature = "fn_once_output", since = "1.12.0")]
+ type Output;
+
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+impl_fn_for_zst! {
+ /// Documentation for the zst
+ #[derive(Copy)]
+ struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> () {
+ };
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue4054.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue4054.rs
new file mode 100644
index 0000000..6dcab23
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue4054.rs
@@ -0,0 +1,14 @@
+#[allow(path_statements)]
+
+macro_rules! array_impl_default {
+ {$t:ident} => {
+ $t;
+ array_impl_default!{}
+ };
+ {} => {}
+}
+
+pub fn foo() {
+ let x = 12;
+ array_impl_default! {x}
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro20.rs b/gcc/testsuite/rust/compile/macros/mbe/macro20.rs
index e03455b..4481834 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro20.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro20.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro23.rs b/gcc/testsuite/rust/compile/macros/mbe/macro23.rs
index a6a2afd..3add715 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro23.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro23.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro27.rs b/gcc/testsuite/rust/compile/macros/mbe/macro27.rs
index ee7833b..b9f392f 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro27.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro27.rs
@@ -2,7 +2,6 @@ macro_rules! m {
($a:expr tok) => {
// { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
$a
};
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro28.rs b/gcc/testsuite/rust/compile/macros/mbe/macro28.rs
index 8002f28..bbe55a7 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro28.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro28.rs
@@ -2,7 +2,6 @@ macro_rules! m {
($a:expr $(tok $es:expr)*) => {
// { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
$a
};
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro29.rs b/gcc/testsuite/rust/compile/macros/mbe/macro29.rs
index 39f5021..a6c9eb5 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro29.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro29.rs
@@ -2,7 +2,6 @@ macro_rules! m {
($($es:expr)* tok) => {
// { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
$a
};
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro30.rs b/gcc/testsuite/rust/compile/macros/mbe/macro30.rs
index 35064bc0..097272e 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro30.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro30.rs
@@ -2,7 +2,6 @@ macro_rules! m {
($e:expr $f:expr) => {
// { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
$e
};
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro31.rs b/gcc/testsuite/rust/compile/macros/mbe/macro31.rs
index 6674a5f..30fae48 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro31.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro31.rs
@@ -2,7 +2,6 @@ macro_rules! m {
($($e:expr)* $($f:expr)*) => {
// { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
$e
};
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro33.rs b/gcc/testsuite/rust/compile/macros/mbe/macro33.rs
index 2ccd33e..a73d245 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro33.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro33.rs
@@ -1,5 +1,4 @@
macro_rules! forbidden_frag {
($t:ty $not_block:ident) => {{}}; // { dg-error "fragment specifier .ident. is not allowed after .ty. fragments" }
// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-1 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro35.rs b/gcc/testsuite/rust/compile/macros/mbe/macro35.rs
index 07b157b..8c295d4 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro35.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro35.rs
@@ -3,5 +3,4 @@ macro_rules! inside_matcher {
// { dg-error "failed to parse macro matcher" "" { target *-*-* } .-1 }
// { dg-error "failed to parse macro match" "" { target *-*-* } .-2 }
// { dg-error "required first macro rule" "" { target *-*-* } .-3 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-4 }
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro37.rs b/gcc/testsuite/rust/compile/macros/mbe/macro37.rs
index 5713d90..26f79d8 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro37.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro37.rs
@@ -1,5 +1,4 @@
macro_rules! invalid_after_zeroable {
($e:expr $(,)* forbidden) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
// { dg-error "required first macro rule" "" { target *-*-* } .-1 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro38.rs b/gcc/testsuite/rust/compile/macros/mbe/macro38.rs
index eb294ae..e297492 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro38.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro38.rs
@@ -1,5 +1,4 @@
macro_rules! invalid_after_zeroable_multi {
($e:expr $(,)? $(;)* $(=>)? forbidden) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
// { dg-error "required first macro rule" "" { target *-*-* } .-1 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro39.rs b/gcc/testsuite/rust/compile/macros/mbe/macro39.rs
index f5c498c..867ec21 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro39.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro39.rs
@@ -1,5 +1,4 @@
macro_rules! m {
($e:expr (, parenthesis_forbidden)) => {{}}; // { dg-error "token .\\(. at start of matcher is not allowed after .expr. fragment" }
// { dg-error "required first macro rule" "" { target *-*-* } .-1 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro40.rs b/gcc/testsuite/rust/compile/macros/mbe/macro40.rs
index f9d048e..39cbf5a 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro40.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro40.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro43.rs b/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
index 992bc77..0a7f038 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
@@ -1,3 +1,10 @@
+use Option::{None, Some};
+
+enum Option<T> {
+ None,
+ Some(T)
+}
+
macro_rules! nonzero_integers {
( $( $Ty: ident($Int: ty); )+ ) => {
$(
@@ -14,7 +21,7 @@ macro_rules! nonzero_integers {
// not all derive macros are implemented yet, and this test does not test these anyways
// #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
- pub struct $Ty(NonZero<$Int>);
+ pub struct $Ty($Int);
impl $Ty {
/// Create a non-zero without checking the value.
@@ -25,7 +32,7 @@ macro_rules! nonzero_integers {
#[stable(feature = "nonzero", since = "1.28.0")]
#[inline]
pub const unsafe fn new_unchecked(n: $Int) -> Self {
- $Ty(NonZero(n))
+ $Ty(n)
}
/// Create a non-zero if the given value is not zero.
@@ -33,7 +40,7 @@ macro_rules! nonzero_integers {
#[inline]
pub fn new(n: $Int) -> Option<Self> {
if n != 0 {
- Some($Ty(NonZero(n)))
+ Some($Ty(n))
} else {
None
}
@@ -43,12 +50,12 @@ macro_rules! nonzero_integers {
#[stable(feature = "nonzero", since = "1.28.0")]
#[inline]
pub fn get(self) -> $Int {
- self.0 .0
+ self.0
}
}
- impl_nonzero_fmt! { // { dg-error "unknown macro" }
+ impl_nonzero_fmt! { // { dg-error "could not resolve macro invocation" }
(Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
}
)+
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro44.rs b/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
index dabac6f..0cfd987 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
@@ -16,7 +16,7 @@ mod foo {
}
fn bar_f() {
- baz!(); // { dg-error "unknown macro" }
+ baz!(); // { dg-error "could not resolve macro invocation" }
}
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro48.rs b/gcc/testsuite/rust/compile/macros/mbe/macro48.rs
index 6b3b369..aff5d19 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro48.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro48.rs
@@ -1,8 +1,7 @@
// Check that "priv" is not in the follow set of :vis.
-// { dg-error "token .priv. is not allowed after .vis. fragment" "#359" { target *-*-* } .+4 }
-// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .+3 }
-// { dg-error "failed to parse item in crate" "" { target *-*-* } .+2 }
+// { dg-error "token .priv. is not allowed after .vis. fragment" "#359" { target *-*-* } .+3 }
+// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .+2 }
macro_rules! my_mac {
($v:vis priv) => {
$v struct Foo(i32);
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro49.rs b/gcc/testsuite/rust/compile/macros/mbe/macro49.rs
index 0900f7c..850cf44 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro49.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro49.rs
@@ -1,3 +1,15 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
macro_rules! closure {
() => {{
14 + 15
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro54.rs b/gcc/testsuite/rust/compile/macros/mbe/macro54.rs
index d3b3f80..1cc4b3d 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro54.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro54.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro58.rs b/gcc/testsuite/rust/compile/macros/mbe/macro58.rs
new file mode 100644
index 0000000..d8f7599
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro58.rs
@@ -0,0 +1,12 @@
+pub fn print(a: *const u8) {}
+#[macro_export]
+macro_rules! pr_warn (
+ ($($arg:tt)*) => (
+ $($crate::print($arg))*
+ )
+);
+
+fn main() {
+ pr_warn!("test\0", "test\0");
+ // { dg-error "expecting .;. but .identifier. found" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro6.rs b/gcc/testsuite/rust/compile/macros/mbe/macro6.rs
index 9c54a67..bbaaa25 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro6.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro6.rs
@@ -1,6 +1,6 @@
macro_rules! zero_or_one {
($($a:literal)?) => {
- f();
+ 1 + 2;
}
}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs b/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs
new file mode 100644
index 0000000..ed6e100
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs
@@ -0,0 +1,7 @@
+macro_rules! foo {
+ ($x:meta) => {0}
+}
+
+pub fn main() -> i32 {
+ foo!(Clone)
+}
diff --git a/gcc/testsuite/rust/compile/match-identifierpattern-enum.rs b/gcc/testsuite/rust/compile/match-identifierpattern-enum.rs
new file mode 100644
index 0000000..c712667
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-identifierpattern-enum.rs
@@ -0,0 +1,12 @@
+enum Foo {
+ I(i32),
+}
+
+fn main() {
+ let x = Foo::I(1);
+
+ match x {
+ a @ Foo::I(b) => {},
+ _ => {},
+ };
+}
diff --git a/gcc/testsuite/rust/compile/match-identifierpattern.rs b/gcc/testsuite/rust/compile/match-identifierpattern.rs
new file mode 100644
index 0000000..6c558ac
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-identifierpattern.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let x = 1;
+
+ match x {
+ 2 => {},
+ a @ 3 => {},
+ _ => {},
+ }
+}
diff --git a/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs b/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs
new file mode 100644
index 0000000..5cce3c4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let x = (1, 2, 3, 4);
+
+ match x {
+ (1, .., 4) => {},
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs b/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs
new file mode 100644
index 0000000..40900a3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let x = (1, 2, 3, 4);
+
+ match x {
+ (1, .., 2, 3, 4, 5) => {}, // { dg-error "expected a tuple with 4 elements, found one with 5 elements" }
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match-slicepattern-array.rs b/gcc/testsuite/rust/compile/match-slicepattern-array.rs
new file mode 100644
index 0000000..e48ca75
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-slicepattern-array.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let a = [0, 1];
+
+ match a {
+ [0, 1] => {},
+ _ => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/match-slicepattern-slice.rs b/gcc/testsuite/rust/compile/match-slicepattern-slice.rs
new file mode 100644
index 0000000..cc33d93
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-slicepattern-slice.rs
@@ -0,0 +1,10 @@
+fn main() {
+ let arr = [1, 2];
+ let slice: &[i32] = &arr;
+
+ match slice {
+ [1] => {},
+ [_, 2] => {},
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern-err.rs b/gcc/testsuite/rust/compile/match-tuplestructpattern-err.rs
new file mode 100644
index 0000000..efd1a89
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-tuplestructpattern-err.rs
@@ -0,0 +1,14 @@
+fn main() {
+ struct A (i32, i32);
+ let a = A (0, 1);
+
+ match a {
+ A (1, 2, 3, 4) => {},
+ // { dg-error "this pattern has 4 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 }
+ A (1, 2, .., 3, 4) => {},
+ // { dg-error "this pattern has 4 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 }
+ A (.., 3, 4, 5) => {},
+ // { dg-error "this pattern has 3 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 }
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern-non-variant.rs b/gcc/testsuite/rust/compile/match-tuplestructpattern-non-variant.rs
new file mode 100644
index 0000000..cf751cb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-tuplestructpattern-non-variant.rs
@@ -0,0 +1,20 @@
+enum Empty {}
+enum NonEmpty {
+ Foo(i32),
+}
+
+fn f(e: Empty) {
+ match e {
+ Empty(0) => {} // { dg-error "expected tuple struct or tuple variant, found enum 'Empty'" }
+ }
+
+ match e {
+ Empty(Empty(..)) => {} // { dg-error "expected tuple struct or tuple variant, found enum 'Empty'" }
+ }
+}
+
+fn g(e: NonEmpty) {
+ match e {
+ NonEmpty(0) => {} // { dg-error "expected tuple struct or tuple variant, found enum 'NonEmpty'" }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern-rest.rs b/gcc/testsuite/rust/compile/match-tuplestructpattern-rest.rs
new file mode 100644
index 0000000..4681acb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-tuplestructpattern-rest.rs
@@ -0,0 +1,9 @@
+fn main() {
+ struct A (i32, i32);
+ let a = A (0, 1);
+
+ match a {
+ A (0, ..) => {},
+ _ => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern.rs b/gcc/testsuite/rust/compile/match-tuplestructpattern.rs
new file mode 100644
index 0000000..0dae71e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-tuplestructpattern.rs
@@ -0,0 +1,9 @@
+fn main() {
+ struct A (i32, i32);
+ let a = A (0, 1);
+
+ match a {
+ A (0, 1) => {},
+ _ => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/method2.rs b/gcc/testsuite/rust/compile/method2.rs
index c8699f7..961a039 100644
--- a/gcc/testsuite/rust/compile/method2.rs
+++ b/gcc/testsuite/rust/compile/method2.rs
@@ -12,5 +12,5 @@ fn main() {
let b;
b = a.test::<asfasfr>(false);
- // { dg-error "failed to resolve TypePath: asfasfr" "" { target *-*-* } .-1 }
+ // { dg-error "could not resolve type path .asfasfr." "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/min_specialization1.rs b/gcc/testsuite/rust/compile/min_specialization1.rs
new file mode 100644
index 0000000..ba97f87
--- /dev/null
+++ b/gcc/testsuite/rust/compile/min_specialization1.rs
@@ -0,0 +1,15 @@
+#![feature(min_specialization)]
+
+pub trait Foo {
+ fn foo(&self) -> bool {
+ false
+ }
+}
+
+pub struct Bar;
+
+impl Foo for Bar {
+ default fn foo(&self) -> bool {
+ true
+ }
+}
diff --git a/gcc/testsuite/rust/compile/multiline-string.rs b/gcc/testsuite/rust/compile/multiline-string.rs
new file mode 100644
index 0000000..fcd6fa8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/multiline-string.rs
@@ -0,0 +1,14 @@
+fn main() {
+ let _a = "gcc
+
+ rs";
+
+ let _b = "rust
+
+ c
+ gcc
+
+
+
+ rs";
+}
diff --git a/gcc/testsuite/rust/compile/multiple_bindings1.rs b/gcc/testsuite/rust/compile/multiple_bindings1.rs
index e73dc2a..c433a0d 100644
--- a/gcc/testsuite/rust/compile/multiple_bindings1.rs
+++ b/gcc/testsuite/rust/compile/multiple_bindings1.rs
@@ -1,29 +1,39 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+ type Output;
+
+ fn call_once(self, args: Args) -> Self::Output;
+}
+
fn f1(i: i32, i: i32) {}
// { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
trait Foo {
- fn f2(i: i32, i: i32) {}
- // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
+ fn f2(i: i32, i: i32) {}
+ // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
}
trait Bar {
- fn f3(i: i32, j: i32) {}
+ fn f3(i: i32, j: i32) {}
}
struct S;
impl S {
- fn f4(i: i32, i: i32) {}
- // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
+ fn f4(i: i32, i: i32) {}
+ // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
}
impl Bar for S {
- fn f3(i: i32, i: i32) {}
- // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
+ fn f3(i: i32, i: i32) {}
+ // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
}
fn main() {
- let _ = |i, i| {};
- // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
+ let _ = |i, i| {};
+ // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 }
}
-
diff --git a/gcc/testsuite/rust/compile/mutability_checks1.rs b/gcc/testsuite/rust/compile/mutability_checks1.rs
new file mode 100644
index 0000000..4affae0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/mutability_checks1.rs
@@ -0,0 +1,15 @@
+pub fn test() {
+ let a;
+ a = 1;
+ a = 2 + 1;
+ // { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 }
+
+ struct Foo(i32);
+ let a = Foo(1);
+ a.0 = 2;
+ // { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 }
+
+ let a = [1, 2, 3, 4];
+ a[0] = 1 + 2;
+ // { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/name_resolution10.rs b/gcc/testsuite/rust/compile/name_resolution10.rs
index 33643bd..f156f98 100644
--- a/gcc/testsuite/rust/compile/name_resolution10.rs
+++ b/gcc/testsuite/rust/compile/name_resolution10.rs
@@ -1,4 +1,4 @@
-// { dg-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-options "-frust-compile-until=lowering" }
#![feature(decl_macro)]
diff --git a/gcc/testsuite/rust/compile/name_resolution11.rs b/gcc/testsuite/rust/compile/name_resolution11.rs
index a464d2a..329567a 100644
--- a/gcc/testsuite/rust/compile/name_resolution11.rs
+++ b/gcc/testsuite/rust/compile/name_resolution11.rs
@@ -1,4 +1,4 @@
-// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-additional-options "-frust-compile-until=lowering" }
fn foo() {
let b = 10;
fn bar() {
diff --git a/gcc/testsuite/rust/compile/name_resolution12.rs b/gcc/testsuite/rust/compile/name_resolution12.rs
index 9cce31c..0f217aa 100644
--- a/gcc/testsuite/rust/compile/name_resolution12.rs
+++ b/gcc/testsuite/rust/compile/name_resolution12.rs
@@ -1,4 +1,4 @@
-// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-additional-options "-frust-compile-until=lowering" }
const TOTO: i32 = 10;
diff --git a/gcc/testsuite/rust/compile/name_resolution13.rs b/gcc/testsuite/rust/compile/name_resolution13.rs
index 33edbf9..8356cf6 100644
--- a/gcc/testsuite/rust/compile/name_resolution13.rs
+++ b/gcc/testsuite/rust/compile/name_resolution13.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub macro bar() {}
}
diff --git a/gcc/testsuite/rust/compile/name_resolution14.rs b/gcc/testsuite/rust/compile/name_resolution14.rs
index eaef6a5..44c43aa 100644
--- a/gcc/testsuite/rust/compile/name_resolution14.rs
+++ b/gcc/testsuite/rust/compile/name_resolution14.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub macro bar() {}
}
diff --git a/gcc/testsuite/rust/compile/name_resolution15.rs b/gcc/testsuite/rust/compile/name_resolution15.rs
index 45f38da..e82c90e 100644
--- a/gcc/testsuite/rust/compile/name_resolution15.rs
+++ b/gcc/testsuite/rust/compile/name_resolution15.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
#![feature(decl_macro)]
pub mod foo {
diff --git a/gcc/testsuite/rust/compile/name_resolution16.rs b/gcc/testsuite/rust/compile/name_resolution16.rs
index 230722e..4db7b2e 100644
--- a/gcc/testsuite/rust/compile/name_resolution16.rs
+++ b/gcc/testsuite/rust/compile/name_resolution16.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
#![feature(decl_macro)]
pub mod foo {
diff --git a/gcc/testsuite/rust/compile/name_resolution17.rs b/gcc/testsuite/rust/compile/name_resolution17.rs
index 4859476..84ad380 100644
--- a/gcc/testsuite/rust/compile/name_resolution17.rs
+++ b/gcc/testsuite/rust/compile/name_resolution17.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
struct Foo;
fn Foo() {} // { dg-error ".Foo. defined multiple times" }
diff --git a/gcc/testsuite/rust/compile/name_resolution18.rs b/gcc/testsuite/rust/compile/name_resolution18.rs
index 5940149..17a3352 100644
--- a/gcc/testsuite/rust/compile/name_resolution18.rs
+++ b/gcc/testsuite/rust/compile/name_resolution18.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
struct Marker;
struct Foo {
diff --git a/gcc/testsuite/rust/compile/name_resolution2.rs b/gcc/testsuite/rust/compile/name_resolution2.rs
index 7e4f5a1..997bf55 100644
--- a/gcc/testsuite/rust/compile/name_resolution2.rs
+++ b/gcc/testsuite/rust/compile/name_resolution2.rs
@@ -1,10 +1,11 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
struct Bar;
trait Foo {
- fn bar(&self) {} // { dg-warning "unused name" }
+ fn bar(&self) {}
}
pub fn outer() {
diff --git a/gcc/testsuite/rust/compile/name_resolution20.rs b/gcc/testsuite/rust/compile/name_resolution20.rs
index e6c2dd5..f131bb4 100644
--- a/gcc/testsuite/rust/compile/name_resolution20.rs
+++ b/gcc/testsuite/rust/compile/name_resolution20.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub macro bar() {}
}
diff --git a/gcc/testsuite/rust/compile/name_resolution22.rs b/gcc/testsuite/rust/compile/name_resolution22.rs
index c49331e..bb5edda 100644
--- a/gcc/testsuite/rust/compile/name_resolution22.rs
+++ b/gcc/testsuite/rust/compile/name_resolution22.rs
@@ -1,4 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
struct Marker;
struct Foo(Marker);
diff --git a/gcc/testsuite/rust/compile/name_resolution23.rs b/gcc/testsuite/rust/compile/name_resolution23.rs
index 50b8e81..843be2a 100644
--- a/gcc/testsuite/rust/compile/name_resolution23.rs
+++ b/gcc/testsuite/rust/compile/name_resolution23.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
mod a {
pub mod b {
pub fn foo() {}
diff --git a/gcc/testsuite/rust/compile/name_resolution24.rs b/gcc/testsuite/rust/compile/name_resolution24.rs
index f4eb7b2..4350cd8 100644
--- a/gcc/testsuite/rust/compile/name_resolution24.rs
+++ b/gcc/testsuite/rust/compile/name_resolution24.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
mod a {
pub mod b {
pub fn baz() {}
diff --git a/gcc/testsuite/rust/compile/name_resolution25.rs b/gcc/testsuite/rust/compile/name_resolution25.rs
index 3cacac7..0cadd9e 100644
--- a/gcc/testsuite/rust/compile/name_resolution25.rs
+++ b/gcc/testsuite/rust/compile/name_resolution25.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
struct Test; // { dg-warning "struct is never constructed: .Test." }
impl Test {}
diff --git a/gcc/testsuite/rust/compile/name_resolution4.rs b/gcc/testsuite/rust/compile/name_resolution4.rs
index b2eadbe..2da1aae 100644
--- a/gcc/testsuite/rust/compile/name_resolution4.rs
+++ b/gcc/testsuite/rust/compile/name_resolution4.rs
@@ -1,8 +1,9 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
trait Foo {
- fn foo(&self) {} // { dg-warning "unused name" }
+ fn foo(&self) {}
}
struct Bar;
diff --git a/gcc/testsuite/rust/compile/name_resolution6.rs b/gcc/testsuite/rust/compile/name_resolution6.rs
index e4087e6..b2b5f6b 100644
--- a/gcc/testsuite/rust/compile/name_resolution6.rs
+++ b/gcc/testsuite/rust/compile/name_resolution6.rs
@@ -1,4 +1,4 @@
-// { dg-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-options "-frust-compile-until=lowering" }
pub mod foo {
pub mod bar {
diff --git a/gcc/testsuite/rust/compile/name_resolution7.rs b/gcc/testsuite/rust/compile/name_resolution7.rs
index fa84e2f..78cb0b2 100644
--- a/gcc/testsuite/rust/compile/name_resolution7.rs
+++ b/gcc/testsuite/rust/compile/name_resolution7.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
// check that macros by example do not get inserted in ribs like regular items
pub mod foo {
pub mod bar {
diff --git a/gcc/testsuite/rust/compile/name_resolution8.rs b/gcc/testsuite/rust/compile/name_resolution8.rs
index 6fb5170..aca1945 100644
--- a/gcc/testsuite/rust/compile/name_resolution8.rs
+++ b/gcc/testsuite/rust/compile/name_resolution8.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
// check that macros by example get exported to the crate's root with #[macro_export]
pub mod foo {
pub mod bar {
diff --git a/gcc/testsuite/rust/compile/name_resolution9.rs b/gcc/testsuite/rust/compile/name_resolution9.rs
index 93adb46..84ba3c5 100644
--- a/gcc/testsuite/rust/compile/name_resolution9.rs
+++ b/gcc/testsuite/rust/compile/name_resolution9.rs
@@ -1,16 +1,14 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub mod bar {
fn f() {
super::super::super::foo!(); // { dg-error "too many leading .super. keywords" }
// { dg-error "could not resolve macro invocation" "" { target *-*-* } .-1 }
- super::crate::foo!(); // { dg-error "leading path segment .crate. can only be used" }
+ super::crate::foo!(); // { dg-error ".crate. in paths can only be used" }
// { dg-error "could not resolve macro invocation" "" { target *-*-* } .-1 }
- crate::foo::bar::super::foo!(); // { dg-error "leading path segment .super. can only be used" }
+ crate::foo::bar::super::foo!(); // { dg-error ".super. in paths can only be used" }
// { dg-error "could not resolve macro invocation" "" { target *-*-* } .-1 }
}
}
diff --git a/gcc/testsuite/rust/compile/nested_generic.rs b/gcc/testsuite/rust/compile/nested_generic.rs
index 322b3c5..b7dae27 100644
--- a/gcc/testsuite/rust/compile/nested_generic.rs
+++ b/gcc/testsuite/rust/compile/nested_generic.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/nested_macro_definition.rs b/gcc/testsuite/rust/compile/nested_macro_definition.rs
index c0b7250..b71afbd 100644
--- a/gcc/testsuite/rust/compile/nested_macro_definition.rs
+++ b/gcc/testsuite/rust/compile/nested_macro_definition.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
macro_rules! toto {
() => {
macro_rules! tata {
diff --git a/gcc/testsuite/rust/compile/nested_macro_use2.rs b/gcc/testsuite/rust/compile/nested_macro_use2.rs
index 4659500..7bb6154 100644
--- a/gcc/testsuite/rust/compile/nested_macro_use2.rs
+++ b/gcc/testsuite/rust/compile/nested_macro_use2.rs
@@ -8,5 +8,5 @@ mod foo {
}
fn main() {
- baz!(); // { dg-error "unknown macro: .baz." }
+ baz!(); // { dg-error "could not resolve macro invocation .baz." }
}
diff --git a/gcc/testsuite/rust/compile/nonexistent-field.rs b/gcc/testsuite/rust/compile/nonexistent-field.rs
index e20c49d..9bcfb2f 100644
--- a/gcc/testsuite/rust/compile/nonexistent-field.rs
+++ b/gcc/testsuite/rust/compile/nonexistent-field.rs
@@ -6,7 +6,7 @@ fn main() {
let s = StructWithFields { x: 0 };
s.foo;
- // { dg-error "no field .foo. on type .StructWithFields.StructWithFields .x.u32... .E0609." "" { target *-*-* } .-1 }
+ // { dg-error "no field .foo. on type .StructWithFields. .E0609." "" { target *-*-* } .-1 }
let numbers = (1, 2, 3);
numbers.3;
diff --git a/gcc/testsuite/rust/compile/nr2/compile.exp b/gcc/testsuite/rust/compile/nr2/compile.exp
deleted file mode 100644
index 0afe36c..0000000
--- a/gcc/testsuite/rust/compile/nr2/compile.exp
+++ /dev/null
@@ -1,136 +0,0 @@
-# Copyright (C) 2021-2024 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3. If not see
-# <http://www.gnu.org/licenses/>.
-
-# Compile tests, no torture testing, for name resolution 2.0
-#
-# These tests raise errors in the front end; torture testing doesn't apply.
-
-# Load support procs.
-load_lib rust-dg.exp
-
-# Initialize `dg'.
-dg-init
-
-namespace eval rust-nr2-ns {
- # Exclude tests which aren't passing yet
- # These should be removed from the exclude file over time
-
- set exclude_fh [open $srcdir/$subdir/exclude r]
- set exclude_raw [lsort [split [read $exclude_fh] "\n"]]
- close $exclude_fh
- unset exclude_fh
-
- set exclude ""
- foreach ent $exclude_raw {
- if [regexp {^[^#].*} $ent] {
- lappend exclude $ent
- }
- }
- unset exclude_raw
-
- # Run tests in directories
- # Manually specifying these, in case some other test file
- # does something weird
- set test_dirs {. compile macros/builtin macros/mbe macros/proc}
-
- set tests_expect_ok ""
- set tests_expect_err ""
-
- foreach test_dir $test_dirs {
- foreach test [lsort [glob -nocomplain -tails -directory $srcdir/$subdir/../$test_dir *.rs]] {
- if {$test_dir == "."} {
- set test_lbl $test
- } else {
- set test_lbl "$test_dir/$test"
- }
- set idx [lsearch -exact -sorted $exclude $test_lbl]
- if {$idx == -1} {
- lappend tests_expect_ok $srcdir/$subdir/../$test_dir/$test
- } else {
- lappend tests_expect_err $srcdir/$subdir/../$test_dir/$test
- set exclude [lreplace $exclude $idx $idx]
- }
- }
- }
-
- # Generate failures for unmatched tests in the exclude list
- foreach ent $exclude {
- fail "$ent: could not exclude test"
- }
- unset exclude
-
- # run a test while catching record_test calls
- set record_test_out ""
- proc try_test { test } {
- variable record_test_out
- rename ::record_test record_test_old
-
- proc ::record_test { type msg args } {
- namespace eval ::rust-nr2-ns {
- set type [uplevel 1 {set type}]
- set msg [uplevel 1 {set msg}]
- variable record_test_out
- switch $type {
- FAIL {
- lappend record_test_out "$type: $msg"
- }
- XPASS {
- lappend record_test_out "$type: $msg"
- }
- }
- }
- }
-
- namespace eval :: {
- set saved-dg-do-what-default ${dg-do-what-default}
- set dg-do-what-default "compile"
- dg-runtest [list [uplevel 1 {set test}]] "-frust-name-resolution-2.0" ""
- set dg-do-what-default ${saved-dg-do-what-default}
- }
-
- rename ::record_test ""
- rename record_test_old ::record_test
-
- set record_test_cache $record_test_out
- set record_test_out ""
- return $record_test_cache
- }
-
- # check for unexpected failures
- foreach test $tests_expect_ok {
- set fails [try_test $test]
- if {[llength $fails] != 0} {
- foreach ent $fails {
- record_test FAIL "$test: nr2 failure: $ent"
- }
- } else {
- record_test PASS "$test: nr2 success"
- }
- }
-
- #check for unexpected successes
- foreach test $tests_expect_err {
- set fails [try_test $test]
- if {[llength $fails] == 0} {
- record_test XPASS "$test: nr2 unexpectedly passed"
- } else {
- record_test XFAIL "$test: nr2 was rightfully excluded"
- }
- }
-}
-
-# All done.
-dg-finish
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
deleted file mode 100644
index ecef6d2..0000000
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ /dev/null
@@ -1,237 +0,0 @@
-# relies on exact source file path match
-# TODO: patch this file or nr2/compile.exp to handle this
-debug-diagnostics-on.rs
-
-# main list
-attr-mismatch-crate-name.rs
-attr_deprecated.rs
-attr_deprecated_2.rs
-auto_trait_super_trait.rs
-auto_trait_valid.rs
-auto_trait_invalid.rs
-bad=file-name.rs
-bounds1.rs
-break-rust2.rs
-break-rust3.rs
-macros/builtin/eager1.rs
-macros/builtin/eager2.rs
-macros/builtin/recurse2.rs
-macros/builtin/include3.rs
-macros/builtin/include4.rs
-canonical_paths1.rs
-cfg1.rs
-cfg3.rs
-cfg4.rs
-cfg5.rs
-closure_no_type_anno.rs
-complex-path1.rs
-complex_qualified_path_in_expr.rs
-const-issue1440.rs
-const_generics_3.rs
-const_generics_4.rs
-const_generics_5.rs
-const_generics_7.rs
-derive_empty.rs
-derive_macro1.rs
-derive_macro3.rs
-derive_macro4.rs
-derive_macro6.rs
-expected_type_args2.rs
-expected_type_args3.rs
-feature_rust_attri0.rs
-feature_rust_attri1.rs
-for_lifetimes.rs
-format_args_basic_expansion.rs
-generic-default1.rs
-generics1.rs
-generics10.rs
-generics11.rs
-generics2.rs
-generics3.rs
-generics4.rs
-generics5.rs
-generics6.rs
-generics7.rs
-generics8.rs
-generics9.rs
-if_let_expr.rs
-infer-crate-name.rs
-issue-1019.rs
-issue-1031.rs
-issue-1034.rs
-issue-1128.rs
-issue-1129-2.rs
-issue-1130.rs
-issue-1165.rs
-issue-1173.rs
-issue-1235.rs
-issue-1237.rs
-issue-1272.rs
-issue-1289.rs
-issue-1447.rs
-issue-1483.rs
-issue-1589.rs
-issue-1725-1.rs
-issue-1725-2.rs
-issue-1786.rs
-issue-1813.rs
-issue-1893.rs
-issue-1901.rs
-issue-1930.rs
-issue-1981.rs
-issue-2019-1.rs
-issue-2019-2.rs
-issue-2019-3.rs
-issue-2036.rs
-issue-2037.rs
-issue-2043.rs
-issue-2070.rs
-issue-2105.rs
-issue-2106.rs
-issue-2135.rs
-issue-2136-1.rs
-issue-2136-2.rs
-issue-2139.rs
-issue-2142.rs
-issue-2165.rs
-issue-2166.rs
-issue-2190-1.rs
-issue-2190-2.rs
-issue-2195.rs
-issue-2238.rs
-issue-2304.rs
-issue-2330.rs
-issue-2375.rs
-issue-2478.rs
-issue-2479.rs
-issue-2514.rs
-issue-2723-1.rs
-issue-2723-2.rs
-issue-2772-1.rs
-issue-2772-2.rs
-issue-2775.rs
-issue-2747.rs
-issue-2782.rs
-issue-2812.rs
-issue-850.rs
-issue-852.rs
-issue-855.rs
-issue-925.rs
-iterators1.rs
-lookup_err1.rs
-macros/mbe/macro-issue1233.rs
-macros/mbe/macro-issue1400.rs
-macros/mbe/macro13.rs
-macros/mbe/macro15.rs
-macros/mbe/macro20.rs
-macros/mbe/macro23.rs
-macros/mbe/macro40.rs
-macros/mbe/macro43.rs
-macros/mbe/macro44.rs
-macros/mbe/macro50.rs
-macros/mbe/macro54.rs
-macros/mbe/macro6.rs
-macros/mbe/macro_rules_macro_rules.rs
-macros/mbe/macro_use1.rs
-match-never-ltype.rs
-match-never-rtype.rs
-match1.rs
-match2.rs
-match3.rs
-match4.rs
-match5.rs
-match9.rs
-method2.rs
-multi_reference_type.rs
-multiple_bindings1.rs
-multiple_bindings2.rs
-name_resolution2.rs
-name_resolution4.rs
-nested_generic.rs
-nested_macro_use1.rs
-nested_macro_use2.rs
-nested_macro_use3.rs
-non_member_const.rs
-not_find_value_in_scope.rs
-parse_associated_type_as_generic_arg.rs
-parse_associated_type_as_generic_arg2.rs
-parse_associated_type_as_generic_arg3.rs
-parse_complex_generic_application.rs
-parse_complex_generic_application2.rs
-path_as_generic_arg.rs
-pattern-struct.rs
-privacy1.rs
-privacy3.rs
-privacy4.rs
-privacy5.rs
-privacy6.rs
-privacy8.rs
-macros/proc/attribute_non_function.rs
-macros/proc/derive_non_function.rs
-macros/proc/non_function.rs
-pub_restricted_1.rs
-pub_restricted_2.rs
-pub_restricted_3.rs
-redef_error2.rs
-redef_error4.rs
-redef_error5.rs
-redef_error6.rs
-rustc_attr1.rs
-self-path1.rs
-self-path2.rs
-sizeof-stray-infer-var-bug.rs
-specify-crate-name.rs
-stmt_with_block_dot.rs
-struct-expr-parse.rs
-trait-cycle.rs
-traits1.rs
-traits10.rs
-traits11.rs
-traits12.rs
-traits2.rs
-traits3.rs
-traits4.rs
-traits5.rs
-traits6.rs
-traits7.rs
-traits8.rs
-traits9.rs
-type-bindings1.rs
-unconstrained_type_param.rs
-undeclared_label.rs
-unsafe1.rs
-unsafe11.rs
-unsafe2.rs
-unsafe3.rs
-unsafe6.rs
-unsafe7.rs
-use_1.rs
-use_2.rs
-v0-mangle1.rs
-v0-mangle2.rs
-while_break_expr.rs
-negative_impls.rs
-auto_trait.rs
-exhaustiveness1.rs
-exhaustiveness2.rs
-exhaustiveness3.rs
-trait13.rs
-trait14.rs
-issue-2324-1.rs
-issue-2324-2.rs
-issue-2725.rs
-issue-2987.rs
-issue-3045-1.rs
-issue-3045-2.rs
-issue-3046.rs
-unknown-associated-item.rs
-issue-3030.rs
-issue-3035.rs
-issue-3082.rs
-issue-3139-1.rs
-issue-3139-2.rs
-issue-3139-3.rs
-issue-3036.rs
-issue-2951.rs
-issue-2203.rs
-issue-2499.rs \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/offset_of1.rs b/gcc/testsuite/rust/compile/offset_of1.rs
new file mode 100644
index 0000000..5b79699
--- /dev/null
+++ b/gcc/testsuite/rust/compile/offset_of1.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-frust-compile-until=lowering -frust-assume-builtin-offset-of" }
+
+pub struct Foo {
+ a: i32,
+}
+
+fn main() {
+ let _ = offset_of!(Foo, a); // valid
+ let _ = offset_of!("bloop", a); // { dg-error "could not parse type" }
+ let _ = offset_of!(Foo, 15); // { dg-error "could not parse field" }
+}
diff --git a/gcc/testsuite/rust/compile/offset_of2.rs b/gcc/testsuite/rust/compile/offset_of2.rs
new file mode 100644
index 0000000..d4ad9c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/offset_of2.rs
@@ -0,0 +1,9 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-assume-builtin-offset-of" }
+
+pub struct Foo {
+ a: i32,
+}
+
+fn main() {
+ let _ = offset_of!(Foo, a); // valid
+}
diff --git a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs
index ba1042a..9190c40 100644
--- a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs
+++ b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs
index a2662c2..c50823b 100644
--- a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs
+++ b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs
index b4342e8..fa65b55 100644
--- a/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs
+++ b/gcc/testsuite/rust/compile/parse_associated_type_as_generic_arg3.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/parse_closure_bind.rs b/gcc/testsuite/rust/compile/parse_closure_bind.rs
new file mode 100644
index 0000000..4513846
--- /dev/null
+++ b/gcc/testsuite/rust/compile/parse_closure_bind.rs
@@ -0,0 +1,20 @@
+// { dg-additional-options "-frust-compile-until=typecheck" }
+// TODO: this should typecheck
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ /// The returned type after the call operator is used.
+ #[lang = "fn_once_output"]
+ type Output;
+
+ /// Performs the call operation.
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+pub fn foo() {
+ (|_a @ _b| {}) (1)
+}
diff --git a/gcc/testsuite/rust/compile/parse_complex_generic_application.rs b/gcc/testsuite/rust/compile/parse_complex_generic_application.rs
index 02877dd..b678cb2 100644
--- a/gcc/testsuite/rust/compile/parse_complex_generic_application.rs
+++ b/gcc/testsuite/rust/compile/parse_complex_generic_application.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/parse_complex_generic_application2.rs b/gcc/testsuite/rust/compile/parse_complex_generic_application2.rs
index 5ebc94f..41ce21a 100644
--- a/gcc/testsuite/rust/compile/parse_complex_generic_application2.rs
+++ b/gcc/testsuite/rust/compile/parse_complex_generic_application2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/parse_float_dot.rs b/gcc/testsuite/rust/compile/parse_float_dot.rs
new file mode 100644
index 0000000..bfe3da2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/parse_float_dot.rs
@@ -0,0 +1,3 @@
+// floating point literals can't start with a '.'
+// TODO: improve the error message emitted here
+const X: f32 = .5; // { dg-error ".*" }
diff --git a/gcc/testsuite/rust/compile/parse_invalid_specialization.rs b/gcc/testsuite/rust/compile/parse_invalid_specialization.rs
index 1ce7384..68e2120 100644
--- a/gcc/testsuite/rust/compile/parse_invalid_specialization.rs
+++ b/gcc/testsuite/rust/compile/parse_invalid_specialization.rs
@@ -1,4 +1,3 @@
default fn f() {
// { dg-error ".default. is only allowed on items within .impl. blocks" "" { target *-*-* } .-1 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/parse_simple_path_fail_1.rs b/gcc/testsuite/rust/compile/parse_simple_path_fail_1.rs
new file mode 100644
index 0000000..1d52abb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/parse_simple_path_fail_1.rs
@@ -0,0 +1,2 @@
+pub(in crate::) struct S;
+// { dg-error "expecting ... but .::. found" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/parse_simple_path_fail_2.rs b/gcc/testsuite/rust/compile/parse_simple_path_fail_2.rs
new file mode 100644
index 0000000..1205f19
--- /dev/null
+++ b/gcc/testsuite/rust/compile/parse_simple_path_fail_2.rs
@@ -0,0 +1,7 @@
+mod A {
+ struct B;
+}
+
+use A{B};
+// { dg-error "unexpected token" "" { target *-*-* } .-1 }
+// { dg-error "could not parse use tree" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/path_as_generic_arg.rs b/gcc/testsuite/rust/compile/path_as_generic_arg.rs
index 21baf80..aff4ce2 100644
--- a/gcc/testsuite/rust/compile/path_as_generic_arg.rs
+++ b/gcc/testsuite/rust/compile/path_as_generic_arg.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/primitive-import.rs b/gcc/testsuite/rust/compile/primitive-import.rs
new file mode 100644
index 0000000..cc750af
--- /dev/null
+++ b/gcc/testsuite/rust/compile/primitive-import.rs
@@ -0,0 +1,7 @@
+mod primitive {
+ pub use i32;
+}
+
+pub fn foo() -> primitive::i32 {
+ 1
+}
diff --git a/gcc/testsuite/rust/compile/privacy4.rs b/gcc/testsuite/rust/compile/privacy4.rs
index 7865f6a..5da43ff 100644
--- a/gcc/testsuite/rust/compile/privacy4.rs
+++ b/gcc/testsuite/rust/compile/privacy4.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/privacy6.rs b/gcc/testsuite/rust/compile/privacy6.rs
index e1e0fac..72d1a3b 100644
--- a/gcc/testsuite/rust/compile/privacy6.rs
+++ b/gcc/testsuite/rust/compile/privacy6.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/ptr_int_cast.rs b/gcc/testsuite/rust/compile/ptr_int_cast.rs
new file mode 100644
index 0000000..3a2a5d5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/ptr_int_cast.rs
@@ -0,0 +1,18 @@
+fn main(){
+ let foo = 1337;
+ let bar_ptr = &foo as *const i32;
+
+ let bar_ptr_usize = bar_ptr as usize;
+ let bar_ptr_isize = bar_ptr as isize;
+ let bar_ptr_u64 = bar_ptr as u64;
+ let bar_ptr_i64 = bar_ptr as i64;
+ let bar_ptr_i8 = bar_ptr as i8;
+ let bar_ptr_u8 = bar_ptr as u8;
+
+ let _ = bar_ptr_usize as *const i32;
+ let _ = bar_ptr_isize as *const i32;
+ let _ = bar_ptr_u64 as *const i32;
+ let _ = bar_ptr_i64 as *const i32;
+ let _ = bar_ptr_i8 as *const i32;
+ let _ = bar_ptr_u8 as *const i32;
+}
diff --git a/gcc/testsuite/rust/compile/pub_restricted_1.rs b/gcc/testsuite/rust/compile/pub_restricted_1.rs
index 9bda968..2afbeb4 100644
--- a/gcc/testsuite/rust/compile/pub_restricted_1.rs
+++ b/gcc/testsuite/rust/compile/pub_restricted_1.rs
@@ -6,8 +6,8 @@ pub mod foo {
}
}
-pub(in foo::fah::baz) struct A1; // { dg-error "cannot find simple path segment .fah." }
-pub(in fro::bulator::saindoux) struct A2; // { dg-error "cannot find simple path segment .fro." }
-pub(in foo::bar::saindoux) struct A3; // { dg-error "cannot find simple path segment .saindoux." }
+pub(in foo::fah::baz) struct A1; // { dg-error "could not resolve path .foo::fah::baz." }
+pub(in fro::bulator::saindoux) struct A2; // { dg-error "could not resolve path .fro::bulator::saindoux." }
+pub(in foo::bar::saindoux) struct A3; // { dg-error "could not resolve path .foo::bar::saindoux." }
fn main() {}
diff --git a/gcc/testsuite/rust/compile/pub_restricted_2.rs b/gcc/testsuite/rust/compile/pub_restricted_2.rs
index 8588f27..fea9379 100644
--- a/gcc/testsuite/rust/compile/pub_restricted_2.rs
+++ b/gcc/testsuite/rust/compile/pub_restricted_2.rs
@@ -3,16 +3,16 @@
mod foo {
mod bar {
mod baz {
- pub(in baz) struct A0;
- pub(in bar::baz) struct A1;
+ pub(in super::baz) struct A0;
+ pub(in super::super::bar::baz) struct A1;
pub(in foo::bar::baz) struct A2;
mod sain {
mod doux {}
}
- pub(in sain) struct A3; // { dg-error "restricted path is not an ancestor of the current module" }
- pub(in sain::doux) struct A4; // { dg-error "restricted path is not an ancestor of the current module" }
+ pub(in self::sain) struct A3; // { dg-error "restricted path is not an ancestor of the current module" }
+ pub(in self::sain::doux) struct A4; // { dg-error "restricted path is not an ancestor of the current module" }
}
}
}
diff --git a/gcc/testsuite/rust/compile/raw-byte-string-loc.rs b/gcc/testsuite/rust/compile/raw-byte-string-loc.rs
index b71b6e5..6082118 100644
--- a/gcc/testsuite/rust/compile/raw-byte-string-loc.rs
+++ b/gcc/testsuite/rust/compile/raw-byte-string-loc.rs
@@ -3,4 +3,3 @@ const X: &'static u8 = br#"12
BREAK
// { dg-error "unrecognised token" "" { target *-*-* } .-1 }
-// { dg-error "failed to parse item" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/raw-string-loc.rs b/gcc/testsuite/rust/compile/raw-string-loc.rs
index 26331ea..9e32790 100644
--- a/gcc/testsuite/rust/compile/raw-string-loc.rs
+++ b/gcc/testsuite/rust/compile/raw-string-loc.rs
@@ -3,4 +3,3 @@ const X: &'static str = r#"12
BREAK
// { dg-error "unrecognised token" "" { target *-*-* } .-1 }
-// { dg-error "failed to parse item" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/raw_ref_op_invalid.rs b/gcc/testsuite/rust/compile/raw_ref_op_invalid.rs
index 90e169f..42ec63d 100644
--- a/gcc/testsuite/rust/compile/raw_ref_op_invalid.rs
+++ b/gcc/testsuite/rust/compile/raw_ref_op_invalid.rs
@@ -7,6 +7,4 @@ pub struct Toto {
pub fn test(mut toto: Toto) {
let _c = &raw toto.u; //{ dg-error "expecting .;. but .identifier. found" "" { target *-*-* } }
- //{ dg-excess-errors "Additional errors for parent items" { target *-*-* } }
-
}
diff --git a/gcc/testsuite/rust/compile/redef_error2.rs b/gcc/testsuite/rust/compile/redef_error2.rs
index 65793bc..ed946f8 100644
--- a/gcc/testsuite/rust/compile/redef_error2.rs
+++ b/gcc/testsuite/rust/compile/redef_error2.rs
@@ -1,4 +1,4 @@
const TEST: i32 = 2;
-const TEST: f32 = 3.0; // { dg-error "redefined multiple times" }
+const TEST: f32 = 3.0; // { dg-error "defined multiple times" }
fn main() {}
diff --git a/gcc/testsuite/rust/compile/redef_error5.rs b/gcc/testsuite/rust/compile/redef_error5.rs
index dc6ad50..b3d71e1 100644
--- a/gcc/testsuite/rust/compile/redef_error5.rs
+++ b/gcc/testsuite/rust/compile/redef_error5.rs
@@ -2,7 +2,7 @@ struct Foo(i32, bool);
impl Foo {
const TEST: i32 = 123;
- const TEST: bool = false; // { dg-error "redefined multiple times" }
+ const TEST: bool = false; // { dg-error "defined multiple times" }
}
fn main() {}
diff --git a/gcc/testsuite/rust/compile/reference1.rs b/gcc/testsuite/rust/compile/reference1.rs
index 2f94754..28f7a26 100644
--- a/gcc/testsuite/rust/compile/reference1.rs
+++ b/gcc/testsuite/rust/compile/reference1.rs
@@ -2,5 +2,5 @@ fn main() {
let a = &123;
let b: &mut i32 = a;
// { dg-error "mismatched mutability" "" { target *-*-* } .-1 }
- // { dg-error "mismatched types, expected .&mut i32. but got .& i32." "" { target *-*-* } .-2 }
+ // { dg-error "mismatched types, expected .&mut i32. but got .& <integer>." "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/execute/same_field_name.rs b/gcc/testsuite/rust/compile/same_field_name.rs
index d57562b..8e5b78c 100644
--- a/gcc/testsuite/rust/execute/same_field_name.rs
+++ b/gcc/testsuite/rust/compile/same_field_name.rs
@@ -1,7 +1,7 @@
// https://doc.rust-lang.org/error_codes/E0124.html
fn main() {
struct Foo {
- field1: i32, // { dg-error "field .field1. is already declared" }
+ field1: i32,
field1: i32, // { dg-error "field .field1. is already declared" }
field1: i32, // { dg-error "field .field1. is already declared" }
}
diff --git a/gcc/testsuite/rust/compile/self-in-impl.rs b/gcc/testsuite/rust/compile/self-in-impl.rs
new file mode 100644
index 0000000..a567897
--- /dev/null
+++ b/gcc/testsuite/rust/compile/self-in-impl.rs
@@ -0,0 +1,15 @@
+// the error message here is what rustc >=1.66 emits
+// rustc <1.66 emits a "cycle detected" error when
+// trying to calculate the impl type
+//
+// since we aren't trying to match error messages too closely
+// and the >=1.66 error message is nicer
+// we may as well mimic that
+
+impl ((Self, i32)) {}
+// { dg-error ".Self. is not valid in the self" "" { target *-*-* } .-1 }
+
+trait Foo {}
+
+impl Foo for ((Self, i32)) {}
+// { dg-error ".Self. is not valid in the self" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/self-path2.rs b/gcc/testsuite/rust/compile/self-path2.rs
index b9b82ca..d955ed0 100644
--- a/gcc/testsuite/rust/compile/self-path2.rs
+++ b/gcc/testsuite/rust/compile/self-path2.rs
@@ -11,11 +11,11 @@ fn baz() {
crate::bar();
crate::self::foo();
- // { dg-error "failed to resolve: .self. in paths can only be used in start position" "" { target *-*-* } .-1 }
+ // { dg-error ".self. in paths can only be used in start position" "" { target *-*-* } .-1 }
}
type a = foo;
type b = crate::foo;
type c = self::foo;
type d = crate::self::foo;
-// { dg-error "failed to resolve: .self. in paths can only be used in start position" "" { target *-*-* } .-1 }
+// { dg-error ".self. in paths can only be used in start position" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/self_const_ptr.rs b/gcc/testsuite/rust/compile/self_const_ptr.rs
index 014fe1b..51e339e 100644
--- a/gcc/testsuite/rust/compile/self_const_ptr.rs
+++ b/gcc/testsuite/rust/compile/self_const_ptr.rs
@@ -4,5 +4,4 @@ impl MyStruct {
pub fn do_something(*const self) {}
// { dg-error "cannot pass .self. by raw pointer" "" { target *-*-* } .-1 }
// { dg-error "failed to parse inherent impl item in inherent impl" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
}
diff --git a/gcc/testsuite/rust/compile/self_import_namespace.rs b/gcc/testsuite/rust/compile/self_import_namespace.rs
new file mode 100644
index 0000000..a63c1d7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/self_import_namespace.rs
@@ -0,0 +1,12 @@
+mod bar {
+ pub mod foo {}
+ pub fn foo() {}
+}
+
+// This only imports the module `foo`. The function `foo` lives in
+// the value namespace and is not imported.
+use bar::foo::{self};
+
+fn main() {
+ foo(); // { dg-error "expected value" }
+}
diff --git a/gcc/testsuite/rust/compile/self_mut_ptr.rs b/gcc/testsuite/rust/compile/self_mut_ptr.rs
index 2a127b7..c986ef6 100644
--- a/gcc/testsuite/rust/compile/self_mut_ptr.rs
+++ b/gcc/testsuite/rust/compile/self_mut_ptr.rs
@@ -4,5 +4,4 @@ impl MyStruct {
pub fn do_something(*mut self) {}
// { dg-error "cannot pass .self. by raw pointer" "" { target *-*-* } .-1 }
// { dg-error "failed to parse inherent impl item in inherent impl" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
}
diff --git a/gcc/testsuite/rust/compile/self_ptr.rs b/gcc/testsuite/rust/compile/self_ptr.rs
index fd7ff6c..2b3128c 100644
--- a/gcc/testsuite/rust/compile/self_ptr.rs
+++ b/gcc/testsuite/rust/compile/self_ptr.rs
@@ -4,5 +4,4 @@ impl MyStruct {
pub fn do_something(*self) {}
// { dg-error "cannot pass .self. by raw pointer" "" { target *-*-* } .-1 }
// { dg-error "failed to parse inherent impl item in inherent impl" "" { target *-*-* } .-2 }
- // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
}
diff --git a/gcc/testsuite/rust/compile/silly-order-bug.rs b/gcc/testsuite/rust/compile/silly-order-bug.rs
new file mode 100644
index 0000000..cdc8b2f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/silly-order-bug.rs
@@ -0,0 +1,10 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+ type Output;
+}
diff --git a/gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs b/gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs
index 8275691..7377a26 100644
--- a/gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs
+++ b/gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -14,6 +15,6 @@ mod ptr {
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut T;
let y = y as *mut T;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
}
}
diff --git a/gcc/testsuite/rust/compile/slice_rest_pattern.rs b/gcc/testsuite/rust/compile/slice_rest_pattern.rs
index c27a8dd..bb3c414 100644
--- a/gcc/testsuite/rust/compile/slice_rest_pattern.rs
+++ b/gcc/testsuite/rust/compile/slice_rest_pattern.rs
@@ -1,5 +1,4 @@
-// { dg-options "-fsyntax-only" }
-fn foo(a: &[u32]) {
+pub fn foo(a: &[u32]) {
match a {
[first, ..] => {}
[.., last] => {}
diff --git a/gcc/testsuite/rust/compile/slicepattern-size-mismatch.rs b/gcc/testsuite/rust/compile/slicepattern-size-mismatch.rs
new file mode 100644
index 0000000..b54b532
--- /dev/null
+++ b/gcc/testsuite/rust/compile/slicepattern-size-mismatch.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let arr = [0, 1];
+
+ match arr {
+ [0, 1, 2] => {} // { dg-error "pattern requires 3 elements but array has 2 .E0527." }
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/static_var1.rs b/gcc/testsuite/rust/compile/static_var1.rs
index b3b5751..fdd2876 100644
--- a/gcc/testsuite/rust/compile/static_var1.rs
+++ b/gcc/testsuite/rust/compile/static_var1.rs
@@ -1,5 +1,5 @@
static x = 3; // { dg-error "expecting ':' but '=' found" }
-fn main() {// { dg-error "failed to parse item in crate" }
+fn main() {
let y = x +1;
}
diff --git a/gcc/testsuite/rust/compile/stmt_with_block_dot.rs b/gcc/testsuite/rust/compile/stmt_with_block_dot.rs
index c7037af..5a3721e 100644
--- a/gcc/testsuite/rust/compile/stmt_with_block_dot.rs
+++ b/gcc/testsuite/rust/compile/stmt_with_block_dot.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/struct_init1.rs b/gcc/testsuite/rust/compile/struct_init1.rs
index 1875fb4..38f6f38 100644
--- a/gcc/testsuite/rust/compile/struct_init1.rs
+++ b/gcc/testsuite/rust/compile/struct_init1.rs
@@ -4,7 +4,7 @@ struct Foo {
}
fn main() {
- let a = Foo { 0: 10.0, 1: 20.0 }; // { dg-error "failed to resolve type for field" }
- // { dg-error "unknown field" "" { target *-*-* } .-1 }
- // { dg-prune-output "compilation terminated" }
+ let a = Foo { 0: 10.0, 1: 20.0 };
+ // { dg-error "unknown field .0. .E0560." "" { target *-*-* } .-1 }
+ // { dg-error "unknown field .1. .E0560." "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/structural-eq-peq.rs b/gcc/testsuite/rust/compile/structural-eq-peq.rs
new file mode 100644
index 0000000..9bdc98d3d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/structural-eq-peq.rs
@@ -0,0 +1,11 @@
+#![feature(lang_items)]
+
+#[lang = "structural_peq"]
+pub trait StructuralPartialEq {
+ // Empty.
+}
+
+#[lang = "structural_teq"]
+pub trait StructuralEq {
+ // Empty.
+}
diff --git a/gcc/testsuite/rust/compile/torture/associated_types1.rs b/gcc/testsuite/rust/compile/torture/associated_types1.rs
index 2be7037..4fc76af 100644
--- a/gcc/testsuite/rust/compile/torture/associated_types1.rs
+++ b/gcc/testsuite/rust/compile/torture/associated_types1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/builtin_abort.rs b/gcc/testsuite/rust/compile/torture/builtin_abort.rs
index 3112cdc..919caa4 100644
--- a/gcc/testsuite/rust/compile/torture/builtin_abort.rs
+++ b/gcc/testsuite/rust/compile/torture/builtin_abort.rs
@@ -12,7 +12,7 @@ mod intrinsics {
}
}
-pub fn main () -> i32 {
- abort();
+pub fn main() -> i32 {
+ crate::intrinsics::abort();
0
}
diff --git a/gcc/testsuite/rust/compile/torture/extern_mod2.rs b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
index 4984d5d..f3a4f79 100644
--- a/gcc/testsuite/rust/compile/torture/extern_mod2.rs
+++ b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
@@ -12,6 +12,12 @@ mod no_leading_equal;
#[path = "modules/valid_path.rs"]
mod extra_spaces;
+#[path = ""] // { dg-error "path attributes must contain a filename" }
+mod empty_path; // { dg-error "no candidate found" }
+
+#[path = " "] // { dg-error "path attributes must contain a filename" }
+mod path_with_spaces; // { dg-error "no candidate found" }
+
#[path] // { dg-error "path attributes must contain a filename" }
mod error; // { dg-error "no candidate found" }
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_5.rs b/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
index 670ab0a..9d0660c 100644
--- a/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics1.rs b/gcc/testsuite/rust/compile/torture/generics1.rs
index b32eddd..1d4c0f2 100644
--- a/gcc/testsuite/rust/compile/torture/generics1.rs
+++ b/gcc/testsuite/rust/compile/torture/generics1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics10.rs b/gcc/testsuite/rust/compile/torture/generics10.rs
index 1a17e84..af12d7d 100644
--- a/gcc/testsuite/rust/compile/torture/generics10.rs
+++ b/gcc/testsuite/rust/compile/torture/generics10.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics11.rs b/gcc/testsuite/rust/compile/torture/generics11.rs
index 9d5e719..0e2939f 100644
--- a/gcc/testsuite/rust/compile/torture/generics11.rs
+++ b/gcc/testsuite/rust/compile/torture/generics11.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics12.rs b/gcc/testsuite/rust/compile/torture/generics12.rs
index 9347b24..cf841dd 100644
--- a/gcc/testsuite/rust/compile/torture/generics12.rs
+++ b/gcc/testsuite/rust/compile/torture/generics12.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics13.rs b/gcc/testsuite/rust/compile/torture/generics13.rs
index 00b26ec..b83521f 100644
--- a/gcc/testsuite/rust/compile/torture/generics13.rs
+++ b/gcc/testsuite/rust/compile/torture/generics13.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics14.rs b/gcc/testsuite/rust/compile/torture/generics14.rs
index 5be39eb..bf5b2955 100644
--- a/gcc/testsuite/rust/compile/torture/generics14.rs
+++ b/gcc/testsuite/rust/compile/torture/generics14.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics15.rs b/gcc/testsuite/rust/compile/torture/generics15.rs
index 2b1f31c..ab65007 100644
--- a/gcc/testsuite/rust/compile/torture/generics15.rs
+++ b/gcc/testsuite/rust/compile/torture/generics15.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics16.rs b/gcc/testsuite/rust/compile/torture/generics16.rs
index a9fa2eb..0701c94 100644
--- a/gcc/testsuite/rust/compile/torture/generics16.rs
+++ b/gcc/testsuite/rust/compile/torture/generics16.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics17.rs b/gcc/testsuite/rust/compile/torture/generics17.rs
index 9a04158..a52de9b 100644
--- a/gcc/testsuite/rust/compile/torture/generics17.rs
+++ b/gcc/testsuite/rust/compile/torture/generics17.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics18.rs b/gcc/testsuite/rust/compile/torture/generics18.rs
index cb7b1fa..8a239f2 100644
--- a/gcc/testsuite/rust/compile/torture/generics18.rs
+++ b/gcc/testsuite/rust/compile/torture/generics18.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics19.rs b/gcc/testsuite/rust/compile/torture/generics19.rs
index c98599f..4b372b6 100644
--- a/gcc/testsuite/rust/compile/torture/generics19.rs
+++ b/gcc/testsuite/rust/compile/torture/generics19.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics2.rs b/gcc/testsuite/rust/compile/torture/generics2.rs
index e720b422..61fd574 100644
--- a/gcc/testsuite/rust/compile/torture/generics2.rs
+++ b/gcc/testsuite/rust/compile/torture/generics2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics20.rs b/gcc/testsuite/rust/compile/torture/generics20.rs
index 92b022e..985189e 100644
--- a/gcc/testsuite/rust/compile/torture/generics20.rs
+++ b/gcc/testsuite/rust/compile/torture/generics20.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics21.rs b/gcc/testsuite/rust/compile/torture/generics21.rs
index 1c74ea4..2986e69 100644
--- a/gcc/testsuite/rust/compile/torture/generics21.rs
+++ b/gcc/testsuite/rust/compile/torture/generics21.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics22.rs b/gcc/testsuite/rust/compile/torture/generics22.rs
index b838e6e..b5c5f9a 100644
--- a/gcc/testsuite/rust/compile/torture/generics22.rs
+++ b/gcc/testsuite/rust/compile/torture/generics22.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics23.rs b/gcc/testsuite/rust/compile/torture/generics23.rs
index bf4dfb5..d0da16f 100644
--- a/gcc/testsuite/rust/compile/torture/generics23.rs
+++ b/gcc/testsuite/rust/compile/torture/generics23.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics24.rs b/gcc/testsuite/rust/compile/torture/generics24.rs
index ce782c0..8655ca5 100644
--- a/gcc/testsuite/rust/compile/torture/generics24.rs
+++ b/gcc/testsuite/rust/compile/torture/generics24.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics25.rs b/gcc/testsuite/rust/compile/torture/generics25.rs
index 4fe952a..a711e21 100644
--- a/gcc/testsuite/rust/compile/torture/generics25.rs
+++ b/gcc/testsuite/rust/compile/torture/generics25.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics26.rs b/gcc/testsuite/rust/compile/torture/generics26.rs
index 0111add..3a5dcac 100644
--- a/gcc/testsuite/rust/compile/torture/generics26.rs
+++ b/gcc/testsuite/rust/compile/torture/generics26.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics27.rs b/gcc/testsuite/rust/compile/torture/generics27.rs
index c4ca4db..db8fe76 100644
--- a/gcc/testsuite/rust/compile/torture/generics27.rs
+++ b/gcc/testsuite/rust/compile/torture/generics27.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics28.rs b/gcc/testsuite/rust/compile/torture/generics28.rs
index c1ffd9c..f815ef5 100644
--- a/gcc/testsuite/rust/compile/torture/generics28.rs
+++ b/gcc/testsuite/rust/compile/torture/generics28.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics29.rs b/gcc/testsuite/rust/compile/torture/generics29.rs
index e9c693e..4a35b3b 100644
--- a/gcc/testsuite/rust/compile/torture/generics29.rs
+++ b/gcc/testsuite/rust/compile/torture/generics29.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -5,7 +6,6 @@ struct Foo<A, B>(A, B);
impl Foo<i32, f32> {
fn test<X>(self, a: X) -> X {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
a
}
}
diff --git a/gcc/testsuite/rust/compile/torture/generics3.rs b/gcc/testsuite/rust/compile/torture/generics3.rs
index 4c5dabc..ae12d00 100644
--- a/gcc/testsuite/rust/compile/torture/generics3.rs
+++ b/gcc/testsuite/rust/compile/torture/generics3.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics30.rs b/gcc/testsuite/rust/compile/torture/generics30.rs
index 24ae58f..f592e77 100644
--- a/gcc/testsuite/rust/compile/torture/generics30.rs
+++ b/gcc/testsuite/rust/compile/torture/generics30.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -5,7 +6,6 @@ struct Foo<A, B>(A, B);
impl<T> Foo<T, f32> {
fn test<X>(self, a: X) -> X {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
a
}
}
diff --git a/gcc/testsuite/rust/compile/torture/generics31.rs b/gcc/testsuite/rust/compile/torture/generics31.rs
index f8e2f36..a393a4c 100644
--- a/gcc/testsuite/rust/compile/torture/generics31.rs
+++ b/gcc/testsuite/rust/compile/torture/generics31.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics32.rs b/gcc/testsuite/rust/compile/torture/generics32.rs
index 49c4539..f332a77 100644
--- a/gcc/testsuite/rust/compile/torture/generics32.rs
+++ b/gcc/testsuite/rust/compile/torture/generics32.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics4.rs b/gcc/testsuite/rust/compile/torture/generics4.rs
index 54bdf56..3d4875b 100644
--- a/gcc/testsuite/rust/compile/torture/generics4.rs
+++ b/gcc/testsuite/rust/compile/torture/generics4.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics5.rs b/gcc/testsuite/rust/compile/torture/generics5.rs
index df27fdd..3fcf13b 100644
--- a/gcc/testsuite/rust/compile/torture/generics5.rs
+++ b/gcc/testsuite/rust/compile/torture/generics5.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics6.rs b/gcc/testsuite/rust/compile/torture/generics6.rs
index 16b85fb..79d1ab8 100644
--- a/gcc/testsuite/rust/compile/torture/generics6.rs
+++ b/gcc/testsuite/rust/compile/torture/generics6.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics7.rs b/gcc/testsuite/rust/compile/torture/generics7.rs
index 66454d6..0eb1db1 100644
--- a/gcc/testsuite/rust/compile/torture/generics7.rs
+++ b/gcc/testsuite/rust/compile/torture/generics7.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics8.rs b/gcc/testsuite/rust/compile/torture/generics8.rs
index bc6d09b..b46b1a2 100644
--- a/gcc/testsuite/rust/compile/torture/generics8.rs
+++ b/gcc/testsuite/rust/compile/torture/generics8.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/generics9.rs b/gcc/testsuite/rust/compile/torture/generics9.rs
index 3d9d748..fa926ee 100644
--- a/gcc/testsuite/rust/compile/torture/generics9.rs
+++ b/gcc/testsuite/rust/compile/torture/generics9.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/identifier-missing-impl-1.rs b/gcc/testsuite/rust/compile/torture/identifier-missing-impl-1.rs
index 2389fa5..8a9b031 100644
--- a/gcc/testsuite/rust/compile/torture/identifier-missing-impl-1.rs
+++ b/gcc/testsuite/rust/compile/torture/identifier-missing-impl-1.rs
@@ -4,7 +4,6 @@ impl I {
fn () {
// { dg-error {expecting 'identifier' but '\(' found} "" { target *-*-* } .-1 }
// { dg-error {failed to parse inherent impl item in inherent impl} "" { target *-*-* } .-2 }
- // { dg-error {failed to parse item in crate} "" { target *-*-* } .-3 }
}
}
diff --git a/gcc/testsuite/rust/compile/torture/if.rs b/gcc/testsuite/rust/compile/torture/if.rs
index bcd520f..3b753a7 100644
--- a/gcc/testsuite/rust/compile/torture/if.rs
+++ b/gcc/testsuite/rust/compile/torture/if.rs
@@ -4,6 +4,10 @@ fn foo() -> bool {
fn bar() {}
+fn baz(a: i32) {
+ a;
+}
+
struct Foo1 {
one: i32
}
@@ -13,7 +17,7 @@ fn main() {
if foo() {
bar();
let a = Foo1{one: 1};
- a.one
+ baz (a.one);
}
-} \ No newline at end of file
+}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-2.rs b/gcc/testsuite/rust/compile/torture/intrinsics-2.rs
index a6cd8f8..23151b1 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-2.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-2.rs
@@ -2,6 +2,7 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-4.rs b/gcc/testsuite/rust/compile/torture/intrinsics-4.rs
index 3d26e99..51fc3c1 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-4.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-4.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
index 7a62cca..a015c2a 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-6.rs b/gcc/testsuite/rust/compile/torture/intrinsics-6.rs
index 0e26345..12821a0 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-6.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-6.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-7.rs b/gcc/testsuite/rust/compile/torture/intrinsics-7.rs
index 754aacb..6dc9187c 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-7.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-7.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-8.rs b/gcc/testsuite/rust/compile/torture/intrinsics-8.rs
index b9bd83c..22b1012 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-8.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-8.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1024.rs b/gcc/testsuite/rust/compile/torture/issue-1024.rs
index 819e329..c732565 100644
--- a/gcc/testsuite/rust/compile/torture/issue-1024.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-1024.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1075.rs b/gcc/testsuite/rust/compile/torture/issue-1075.rs
index d23774b..5584678 100644
--- a/gcc/testsuite/rust/compile/torture/issue-1075.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-1075.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1432.rs b/gcc/testsuite/rust/compile/torture/issue-1432.rs
index 5b526fd..df1b527 100644
--- a/gcc/testsuite/rust/compile/torture/issue-1432.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-1432.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1555.rs b/gcc/testsuite/rust/compile/torture/issue-1555.rs
index bee8952..b2f675a 100644
--- a/gcc/testsuite/rust/compile/torture/issue-1555.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-1555.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-368.rs b/gcc/testsuite/rust/compile/torture/issue-368.rs
index 775e70d..a657a7c 100644
--- a/gcc/testsuite/rust/compile/torture/issue-368.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-368.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-808.rs b/gcc/testsuite/rust/compile/torture/issue-808.rs
index 4186d54..f739d22 100644
--- a/gcc/testsuite/rust/compile/torture/issue-808.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-808.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-862.rs b/gcc/testsuite/rust/compile/torture/issue-862.rs
index d9ac912..88d6d65 100644
--- a/gcc/testsuite/rust/compile/torture/issue-862.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-862.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-893-2.rs b/gcc/testsuite/rust/compile/torture/issue-893-2.rs
index 3df27b8..2e4ec14 100644
--- a/gcc/testsuite/rust/compile/torture/issue-893-2.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-893-2.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/issue-893.rs b/gcc/testsuite/rust/compile/torture/issue-893.rs
index f96b5c3..bd77c8d 100644
--- a/gcc/testsuite/rust/compile/torture/issue-893.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-893.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/must_use2.rs b/gcc/testsuite/rust/compile/torture/must_use2.rs
index cf6643e..9c9a1a7 100644
--- a/gcc/testsuite/rust/compile/torture/must_use2.rs
+++ b/gcc/testsuite/rust/compile/torture/must_use2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/nested_fn2.rs b/gcc/testsuite/rust/compile/torture/nested_fn2.rs
index ad7a10b..57cee8a 100644
--- a/gcc/testsuite/rust/compile/torture/nested_fn2.rs
+++ b/gcc/testsuite/rust/compile/torture/nested_fn2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/phantom_data.rs b/gcc/testsuite/rust/compile/torture/phantom_data.rs
index d6c5adc..a5b70a5 100644
--- a/gcc/testsuite/rust/compile/torture/phantom_data.rs
+++ b/gcc/testsuite/rust/compile/torture/phantom_data.rs
@@ -1,4 +1,5 @@
// { dg-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/range-lang-item1.rs b/gcc/testsuite/rust/compile/torture/range-lang-item1.rs
index 604fee8..db10f85 100644
--- a/gcc/testsuite/rust/compile/torture/range-lang-item1.rs
+++ b/gcc/testsuite/rust/compile/torture/range-lang-item1.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits1.rs b/gcc/testsuite/rust/compile/torture/traits1.rs
index 8929501..6fe943c 100644
--- a/gcc/testsuite/rust/compile/torture/traits1.rs
+++ b/gcc/testsuite/rust/compile/torture/traits1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits10.rs b/gcc/testsuite/rust/compile/torture/traits10.rs
index 4cf36e3..4710445 100644
--- a/gcc/testsuite/rust/compile/torture/traits10.rs
+++ b/gcc/testsuite/rust/compile/torture/traits10.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits11.rs b/gcc/testsuite/rust/compile/torture/traits11.rs
index 02383a5..1cab51f 100644
--- a/gcc/testsuite/rust/compile/torture/traits11.rs
+++ b/gcc/testsuite/rust/compile/torture/traits11.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits12.rs b/gcc/testsuite/rust/compile/torture/traits12.rs
index 8648022..3e340eb 100644
--- a/gcc/testsuite/rust/compile/torture/traits12.rs
+++ b/gcc/testsuite/rust/compile/torture/traits12.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits13.rs b/gcc/testsuite/rust/compile/torture/traits13.rs
index 5d9c819..ce70a28 100644
--- a/gcc/testsuite/rust/compile/torture/traits13.rs
+++ b/gcc/testsuite/rust/compile/torture/traits13.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits14.rs b/gcc/testsuite/rust/compile/torture/traits14.rs
index ab546a8..2996ecf 100644
--- a/gcc/testsuite/rust/compile/torture/traits14.rs
+++ b/gcc/testsuite/rust/compile/torture/traits14.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits15.rs b/gcc/testsuite/rust/compile/torture/traits15.rs
index c1863a8..c875577 100644
--- a/gcc/testsuite/rust/compile/torture/traits15.rs
+++ b/gcc/testsuite/rust/compile/torture/traits15.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits16.rs b/gcc/testsuite/rust/compile/torture/traits16.rs
index 8c8e682..7dc546c 100644
--- a/gcc/testsuite/rust/compile/torture/traits16.rs
+++ b/gcc/testsuite/rust/compile/torture/traits16.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits17.rs b/gcc/testsuite/rust/compile/torture/traits17.rs
index 268c2bd..9ee267e 100644
--- a/gcc/testsuite/rust/compile/torture/traits17.rs
+++ b/gcc/testsuite/rust/compile/torture/traits17.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits18.rs b/gcc/testsuite/rust/compile/torture/traits18.rs
index 512152e..bd32f70 100644
--- a/gcc/testsuite/rust/compile/torture/traits18.rs
+++ b/gcc/testsuite/rust/compile/torture/traits18.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits19.rs b/gcc/testsuite/rust/compile/torture/traits19.rs
index 4be898d..bd1a6e2 100644
--- a/gcc/testsuite/rust/compile/torture/traits19.rs
+++ b/gcc/testsuite/rust/compile/torture/traits19.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits2.rs b/gcc/testsuite/rust/compile/torture/traits2.rs
index a9dca94..f0a33d9 100644
--- a/gcc/testsuite/rust/compile/torture/traits2.rs
+++ b/gcc/testsuite/rust/compile/torture/traits2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits3.rs b/gcc/testsuite/rust/compile/torture/traits3.rs
index d805da5..d06a68f 100644
--- a/gcc/testsuite/rust/compile/torture/traits3.rs
+++ b/gcc/testsuite/rust/compile/torture/traits3.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -10,7 +11,6 @@ struct Baz;
impl Foo for Baz {
fn Bar(self) -> i32 {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
123
}
}
diff --git a/gcc/testsuite/rust/compile/torture/traits4.rs b/gcc/testsuite/rust/compile/torture/traits4.rs
index 49c4db2..716d657 100644
--- a/gcc/testsuite/rust/compile/torture/traits4.rs
+++ b/gcc/testsuite/rust/compile/torture/traits4.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits5.rs b/gcc/testsuite/rust/compile/torture/traits5.rs
index c60a259..86e83e5 100644
--- a/gcc/testsuite/rust/compile/torture/traits5.rs
+++ b/gcc/testsuite/rust/compile/torture/traits5.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits6.rs b/gcc/testsuite/rust/compile/torture/traits6.rs
index f117353..f1c4e84 100644
--- a/gcc/testsuite/rust/compile/torture/traits6.rs
+++ b/gcc/testsuite/rust/compile/torture/traits6.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits7.rs b/gcc/testsuite/rust/compile/torture/traits7.rs
index 8e4472d..928dd62 100644
--- a/gcc/testsuite/rust/compile/torture/traits7.rs
+++ b/gcc/testsuite/rust/compile/torture/traits7.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -13,7 +14,6 @@ impl Foo for Bar {
// { dg-warning "unused name" "" { target *-*-* } .-1 }
fn test(self) {}
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/traits8.rs b/gcc/testsuite/rust/compile/torture/traits8.rs
index cc0875b..f2515e8 100644
--- a/gcc/testsuite/rust/compile/torture/traits8.rs
+++ b/gcc/testsuite/rust/compile/torture/traits8.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/traits9.rs b/gcc/testsuite/rust/compile/torture/traits9.rs
index 3a7c37f..8015a35 100644
--- a/gcc/testsuite/rust/compile/torture/traits9.rs
+++ b/gcc/testsuite/rust/compile/torture/traits9.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs b/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs
index 7b98779..4de1843 100644
--- a/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs
+++ b/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/transmute1.rs b/gcc/testsuite/rust/compile/torture/transmute1.rs
index be9fb1d..fc1d94a 100644
--- a/gcc/testsuite/rust/compile/torture/transmute1.rs
+++ b/gcc/testsuite/rust/compile/torture/transmute1.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs b/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs
new file mode 100644
index 0000000..91a3c9a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs
@@ -0,0 +1,6 @@
+// { dg-excess-errors "...." }
+fn main() {
+ // { dg-error "unended raw byte string literal" "" { target *-*-* } .+1 }
+ let s = br##"123"#
+}
+
diff --git a/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs b/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs
index fa329c6..50083e5 100644
--- a/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs
+++ b/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -11,7 +12,7 @@ mod intrinsics {
mod mem {
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
@@ -21,6 +22,6 @@ struct Foo(i32, i32);
impl Foo {
pub fn new() -> Self {
- unsafe { mem::uninitialized::<Foo>() }
+ unsafe { crate::mem::uninitialized::<Foo>() }
}
}
diff --git a/gcc/testsuite/rust/compile/torture/utf8_identifiers.rs b/gcc/testsuite/rust/compile/torture/utf8_identifiers.rs
index 696fcc0..f7d6b37 100644
--- a/gcc/testsuite/rust/compile/torture/utf8_identifiers.rs
+++ b/gcc/testsuite/rust/compile/torture/utf8_identifiers.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/track_caller.rs b/gcc/testsuite/rust/compile/track_caller.rs
new file mode 100644
index 0000000..fd1d842
--- /dev/null
+++ b/gcc/testsuite/rust/compile/track_caller.rs
@@ -0,0 +1,6 @@
+#[track_caller]
+fn foo() {}
+
+fn main() {
+ foo();
+}
diff --git a/gcc/testsuite/rust/compile/traits1.rs b/gcc/testsuite/rust/compile/traits1.rs
index 779662c..d67a6cd 100644
--- a/gcc/testsuite/rust/compile/traits1.rs
+++ b/gcc/testsuite/rust/compile/traits1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits10.rs b/gcc/testsuite/rust/compile/traits10.rs
index da6c155..5e6e7e2 100644
--- a/gcc/testsuite/rust/compile/traits10.rs
+++ b/gcc/testsuite/rust/compile/traits10.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits11.rs b/gcc/testsuite/rust/compile/traits11.rs
index ac8ccdf..6aa860b 100644
--- a/gcc/testsuite/rust/compile/traits11.rs
+++ b/gcc/testsuite/rust/compile/traits11.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits12.rs b/gcc/testsuite/rust/compile/traits12.rs
index b194e07..99f10a2 100644
--- a/gcc/testsuite/rust/compile/traits12.rs
+++ b/gcc/testsuite/rust/compile/traits12.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits2.rs b/gcc/testsuite/rust/compile/traits2.rs
index a76f4c0..857ab28 100644
--- a/gcc/testsuite/rust/compile/traits2.rs
+++ b/gcc/testsuite/rust/compile/traits2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits3.rs b/gcc/testsuite/rust/compile/traits3.rs
index 119132f..c4e3185 100644
--- a/gcc/testsuite/rust/compile/traits3.rs
+++ b/gcc/testsuite/rust/compile/traits3.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits4.rs b/gcc/testsuite/rust/compile/traits4.rs
index 4388b5e..11a0c78 100644
--- a/gcc/testsuite/rust/compile/traits4.rs
+++ b/gcc/testsuite/rust/compile/traits4.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits5.rs b/gcc/testsuite/rust/compile/traits5.rs
index 4e9dcc1..5bb6793 100644
--- a/gcc/testsuite/rust/compile/traits5.rs
+++ b/gcc/testsuite/rust/compile/traits5.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits6.rs b/gcc/testsuite/rust/compile/traits6.rs
index d081dd1..b4922cc 100644
--- a/gcc/testsuite/rust/compile/traits6.rs
+++ b/gcc/testsuite/rust/compile/traits6.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits7.rs b/gcc/testsuite/rust/compile/traits7.rs
index 68f3f38..62e197e 100644
--- a/gcc/testsuite/rust/compile/traits7.rs
+++ b/gcc/testsuite/rust/compile/traits7.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits8.rs b/gcc/testsuite/rust/compile/traits8.rs
index ccba9fa..117ba54 100644
--- a/gcc/testsuite/rust/compile/traits8.rs
+++ b/gcc/testsuite/rust/compile/traits8.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/traits9.rs b/gcc/testsuite/rust/compile/traits9.rs
index bb3034d..3341244 100644
--- a/gcc/testsuite/rust/compile/traits9.rs
+++ b/gcc/testsuite/rust/compile/traits9.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -11,6 +12,5 @@ fn main() {
a = Foo(123);
let b: &dyn Bar = &a;
- // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied" "" { target *-*-* } .-1 }
- // { dg-error "expected" "" { target *-*-* } .-2 }
+ // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied .E0277." "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/try-catch-unwind-new.rs b/gcc/testsuite/rust/compile/try-catch-unwind-new.rs
new file mode 100644
index 0000000..b176f7a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/try-catch-unwind-new.rs
@@ -0,0 +1,20 @@
+// { dg-options "-O2 -w -fdump-tree-optimized" }
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+ // { dg-final { scan-tree-dump-times "__builtin_eh_pointer" 1 "optimized" } }
+ fn catch_unwind(try_fn: fn(_: *mut u8), data: *mut u8, catch_fn: fn(_: *mut u8, _: *mut u8));
+}
+
+extern "C" {
+ fn try_fn(data: *mut u8);
+ fn catch_fn(data: *mut u8, ex: *mut u8);
+}
+
+pub fn not_main(d: &mut u8) {
+ unsafe {
+ // { dg-final { scan-tree-dump-times "try_fn" 1 "optimized" } }
+ catch_unwind(try_fn, d, catch_fn);
+ // { dg-final { scan-tree-dump-times "catch_fn" 1 "optimized" } }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/try-catch-unwind-old.rs b/gcc/testsuite/rust/compile/try-catch-unwind-old.rs
new file mode 100644
index 0000000..e97d52c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/try-catch-unwind-old.rs
@@ -0,0 +1,21 @@
+// { dg-options "-O2 -w -fdump-tree-optimized" }
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+ // { dg-final { scan-tree-dump-times "__builtin_eh_pointer" 1 "optimized" } }
+ fn r#try(try_fn: fn(_: *mut u8), data: *mut u8, catch_fn: fn(_: *mut u8, _: *mut u8)) -> i32;
+}
+
+extern "C" {
+ fn try_fn(data: *mut u8);
+ fn catch_fn(data: *mut u8, ex: *mut u8);
+}
+
+pub fn not_main(d: &mut u8) -> i32 {
+ unsafe {
+ // { dg-final { scan-tree-dump-times "try_fn" 1 "optimized" } }
+ let _: i32 = r#try(try_fn, d, catch_fn);
+ // { dg-final { scan-tree-dump-times "catch_fn" 1 "optimized" } }
+ }
+ 42
+}
diff --git a/gcc/testsuite/rust/compile/try-expr1.rs b/gcc/testsuite/rust/compile/try-expr1.rs
new file mode 100644
index 0000000..f6e460e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/try-expr1.rs
@@ -0,0 +1,85 @@
+// { dg-additional-options "-frust-compile-until=typecheck" }
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result {
+ #[lang = "Ok"]
+ Ok(i32),
+ #[lang = "Err"]
+ Err(i32)
+}
+
+pub trait From<T>: Sized {
+ /// Performs the conversion.
+ #[lang = "from"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn from(_: T) -> Self;
+}
+
+impl<T> From<T> for T {
+ fn from(t: T) -> Self { t }
+}
+
+#[lang = "try"]
+pub trait Try {
+ /// The type of this value when viewed as successful.
+ // #[unstable(feature = "try_trait", issue = "42327")]
+ // type Ok;
+ /// The type of this value when viewed as failed.
+ // #[unstable(feature = "try_trait", issue = "42327")]
+ // type Error;
+
+ /// Applies the "?" operator. A return of `Ok(t)` means that the
+ /// execution should continue normally, and the result of `?` is the
+ /// value `t`. A return of `Err(e)` means that execution should branch
+ /// to the innermost enclosing `catch`, or return from the function.
+ ///
+ /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+ /// in the return type of the enclosing scope (which must itself implement
+ /// `Try`). Specifically, the value `X::from_error(From::from(e))`
+ /// is returned, where `X` is the return type of the enclosing function.
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result;
+
+ /// Wrap an error value to construct the composite result. For example,
+ /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: i32) -> Self;
+
+ /// Wrap an OK value to construct the composite result. For example,
+ /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: i32) -> Self;
+}
+
+impl Try for Result {
+ // type Ok = i32;
+ // type Error = i32;
+
+ fn into_result(self) -> Result {
+ self
+ }
+
+ fn from_ok(v: i32) -> Self {
+ Result::Ok(v)
+ }
+
+ fn from_error(v: i32) -> Self {
+ Result::Err(v)
+ }
+}
+
+fn bar() -> Result {
+ Result::Ok(15)
+}
+
+fn foo() -> Result {
+ let a = bar()?;
+
+ Result::Ok(a)
+}
diff --git a/gcc/testsuite/rust/compile/try-trait.rs b/gcc/testsuite/rust/compile/try-trait.rs
new file mode 100644
index 0000000..3c0a88c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/try-trait.rs
@@ -0,0 +1,46 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ #[lang = "Ok"]
+ Ok(T),
+ #[lang = "Err"]
+ Err(E)
+}
+
+#[lang = "try"]
+pub trait Try {
+ /// The type of this value when viewed as successful.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Ok;
+ /// The type of this value when viewed as failed.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Error;
+
+ /// Applies the "?" operator. A return of `Ok(t)` means that the
+ /// execution should continue normally, and the result of `?` is the
+ /// value `t`. A return of `Err(e)` means that execution should branch
+ /// to the innermost enclosing `catch`, or return from the function.
+ ///
+ /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+ /// in the return type of the enclosing scope (which must itself implement
+ /// `Try`). Specifically, the value `X::from_error(From::from(e))`
+ /// is returned, where `X` is the return type of the enclosing function.
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+ /// Wrap an error value to construct the composite result. For example,
+ /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: Self::Error) -> Self;
+
+ /// Wrap an OK value to construct the composite result. For example,
+ /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: Self::Ok) -> Self;
+}
diff --git a/gcc/testsuite/rust/compile/try_block1.rs b/gcc/testsuite/rust/compile/try_block1.rs
new file mode 100644
index 0000000..9ace029
--- /dev/null
+++ b/gcc/testsuite/rust/compile/try_block1.rs
@@ -0,0 +1,90 @@
+// { dg-additional-options "-frust-edition=2018" }
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ Ok(T),
+ Err(E)
+}
+
+pub trait Try {
+ /// The type of this value when viewed as successful.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Ok;
+ /// The type of this value when viewed as failed.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Error;
+
+ /// Applies the "?" operator. A return of `Ok(t)` means that the
+ /// execution should continue normally, and the result of `?` is the
+ /// value `t`. A return of `Err(e)` means that execution should branch
+ /// to the innermost enclosing `catch`, or return from the function.
+ ///
+ /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+ /// in the return type of the enclosing scope (which must itself implement
+ /// `Try`). Specifically, the value `X::from_error(From::from(e))`
+ /// is returned, where `X` is the return type of the enclosing function.
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+ /// Wrap an error value to construct the composite result. For example,
+ /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: Self::Error) -> Self;
+
+ /// Wrap an OK value to construct the composite result. For example,
+ /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: Self::Ok) -> Self;
+}
+
+pub struct NoneError;
+
+
+pub enum Option<T> {
+ /// No value
+ None,
+ /// Some value `T`
+ Some(T),
+}
+
+impl<T> Option<T> {
+ pub fn ok_or<E>(self, err: E) -> Result<T, E> {
+ match self {
+ Some(ok) => Result::Ok(ok),
+ None => Result::Err(err)
+ }
+ }
+}
+
+use Option::*;
+
+#[unstable(feature = "try_trait", issue = "42327")]
+impl<T> Try for Option<T> {
+ type Ok = T;
+ type Error = NoneError;
+
+ #[inline]
+ fn into_result(self) -> Result<T, NoneError> {
+ self.ok_or(NoneError)
+ }
+
+ #[inline]
+ fn from_ok(v: T) -> Self {
+ Some(v)
+ }
+
+ #[inline]
+ fn from_error(_: NoneError) -> Self {
+ None
+ }
+}
+
+fn main() {
+ let _: Option<i32> = try { 15i32 };
+}
diff --git a/gcc/testsuite/rust/compile/tuple_index_on_non_tuple.rs b/gcc/testsuite/rust/compile/tuple_index_on_non_tuple.rs
new file mode 100644
index 0000000..f94b8c3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/tuple_index_on_non_tuple.rs
@@ -0,0 +1,15 @@
+enum E {
+ V(usize),
+}
+
+struct S {
+ field: i32,
+}
+
+fn main() {
+ let e = E::V(0);
+ let _ = e.0; // { dg-error "expected tuple or tuple struct, found 'E'" }
+
+ let s = S { field: 0 };
+ let _ = s.0; // { dg-error "expected tuple or tuple struct, found 'S'" }
+}
diff --git a/gcc/testsuite/rust/compile/tuple_mismatch.rs b/gcc/testsuite/rust/compile/tuple_mismatch.rs
index 828586b..1ff358b 100644
--- a/gcc/testsuite/rust/compile/tuple_mismatch.rs
+++ b/gcc/testsuite/rust/compile/tuple_mismatch.rs
@@ -3,6 +3,7 @@ fn main() {
let (_,) = (1, 2); // { dg-error "expected a tuple with 2 elements, found one with 1 element" }
let (_, _) = (1, 2, 3); // { dg-error "expected a tuple with 3 elements, found one with 2 elements" }
let (_, _) = (1,); // { dg-error "expected a tuple with 1 element, found one with 2 elements" }
+ let (_, .., _) = (1,); // { dg-error "expected a tuple with 1 element, found one with 2 elements" }
}
// The lhs and rhs sizes don't match, but we still resolve 'a' to be bool, we don't
diff --git a/gcc/testsuite/rust/compile/tuplepattern-rest-readonly.rs b/gcc/testsuite/rust/compile/tuplepattern-rest-readonly.rs
new file mode 100644
index 0000000..db165ef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/tuplepattern-rest-readonly.rs
@@ -0,0 +1,5 @@
+fn main() {
+ let (a, .., b) = (1, 1);
+ a = 2; // { dg-error "assignment of read-only variable .a." }
+ b = 2; // { dg-error "assignment of read-only variable .b." }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/tuplepattern-restpattern-typecheck-err.rs b/gcc/testsuite/rust/compile/tuplepattern-restpattern-typecheck-err.rs
new file mode 100644
index 0000000..d9f7c18
--- /dev/null
+++ b/gcc/testsuite/rust/compile/tuplepattern-restpattern-typecheck-err.rs
@@ -0,0 +1,8 @@
+fn main() {
+ match (1, 2.2, "not 3") {
+ // { dg-error "expected a tuple with 3 elements, found one with 5 elements" "" { target *-*-* } .+1 }
+ (a, b, .., c, d, e) => {
+ let _ = b + c; // { dg-error "cannot apply operator .+. to types <float> and & str" }
+ }
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/type-bindings1.rs b/gcc/testsuite/rust/compile/type-bindings1.rs
index 358035b..fabb487 100644
--- a/gcc/testsuite/rust/compile/type-bindings1.rs
+++ b/gcc/testsuite/rust/compile/type-bindings1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -7,5 +8,4 @@ fn main() {
let a;
a = Foo::<A = i32, B = f32>(123f32);
// { dg-error "associated type bindings are not allowed here" "" { target *-*-* } .-1 }
- // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/unconstrained_type_param.rs b/gcc/testsuite/rust/compile/unconstrained_type_param.rs
index 1cef0b9..dccfc9e 100644
--- a/gcc/testsuite/rust/compile/unconstrained_type_param.rs
+++ b/gcc/testsuite/rust/compile/unconstrained_type_param.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -13,5 +14,4 @@ impl<X, Y> Foo<X> {
fn main() {
let a = Foo::test();
// { dg-error "expected" "" { target *-*-* } .-1 }
- // { dg-error "Failed to resolve expression of function call" "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/undeclared_label.rs b/gcc/testsuite/rust/compile/undeclared_label.rs
index 6efa2d9..9aa0553 100644
--- a/gcc/testsuite/rust/compile/undeclared_label.rs
+++ b/gcc/testsuite/rust/compile/undeclared_label.rs
@@ -2,12 +2,12 @@
#![allow(unused)]
fn resolve_label_continue() -> () {
loop {
- continue 'a; // { dg-error "use of undeclared label .a. in .continue." }
+ continue 'a; // { dg-error "use of undeclared label .'a." }
}
}
fn resolve_label_break() -> () {
loop {
- break 'crabby; // { dg-error "use of undeclared label .crabby. in .break." }
+ break 'crabby; // { dg-error "use of undeclared label .'crabby." }
}
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/unify-errors1.rs b/gcc/testsuite/rust/compile/unify-errors1.rs
new file mode 100644
index 0000000..e101059
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unify-errors1.rs
@@ -0,0 +1,50 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+trait MyTrait {}
+
+struct Wrapper<T: MyTrait> {
+ value: T,
+}
+
+struct NotImpl;
+
+trait A {}
+trait B {}
+
+struct Wrapper2<T: A + B> {
+ value: T,
+}
+
+struct NotImpl2;
+
+impl A for NotImpl2 {}
+
+fn takes_tuple(x: (i32, bool)) {}
+
+fn requires_copy<T: Copy>(value: T) {}
+
+pub fn test() {
+ takes_tuple((1, 2));
+ // { dg-error "mismatched types, expected .bool. but got .<integer>. .E0308." "" { target *-*-* } .-1 }
+
+ takes_tuple((1, 2, 3));
+ // { dg-error "mismatched types, expected ..i32, bool.. but got ..<integer>, <integer>, <integer>.. .E0308." "" { target *-*-* } .-1 }
+
+ takes_tuple("hello");
+ // { dg-error "mismatched types, expected ..i32, bool.. but got .& str. .E0308." "" { target *-*-* } .-1 }
+
+ let x = &mut 5;
+ requires_copy(x);
+ // { dg-error "bounds not satisfied for &mut <integer> .Copy. is not satisfied .E0277." "" { target *-*-* } .-1 }
+
+ let _x = Wrapper { value: NotImpl };
+ // { dg-error "bounds not satisfied for NotImpl .MyTrait. is not satisfied .E0277." "" { target *-*-* } .-1 }
+
+ let _x = Wrapper2 { value: NotImpl2 };
+ // { dg-error "bounds not satisfied for NotImpl2 .B. is not satisfied .E0277." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe10.rs b/gcc/testsuite/rust/compile/unsafe10.rs
index 5861c15..12c0483 100644
--- a/gcc/testsuite/rust/compile/unsafe10.rs
+++ b/gcc/testsuite/rust/compile/unsafe10.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/use_1.rs b/gcc/testsuite/rust/compile/use_1.rs
index 94b9632..21ee3e1 100644
--- a/gcc/testsuite/rust/compile/use_1.rs
+++ b/gcc/testsuite/rust/compile/use_1.rs
@@ -1,7 +1,7 @@
mod frob {}
-use foo::bar::baz; // { dg-error "cannot find simple path segment .foo." }
-use frob::ulator; // { dg-error "cannot find simple path segment .ulator." }
+use foo::bar::baz; // { dg-error "unresolved import .foo::bar::baz." }
+use frob::ulator; // { dg-error "unresolved import .frob::ulator." }
mod sain {
mod doux {}
@@ -9,8 +9,8 @@ mod sain {
mod dron {}
}
-use not_sain::*; // { dg-error "cannot find simple path segment .not_sain." }
+use not_sain::*; // { dg-error "unresolved import .not_sain." }
use sain::*;
use sain::{doux, dron};
-use sain::{doux, dron, graal}; // { dg-error "cannot find simple path segment .graal." }
+use sain::{doux, dron, graal}; // { dg-error "unresolved import .sain::graal." }
diff --git a/gcc/testsuite/rust/compile/use_3.rs b/gcc/testsuite/rust/compile/use_3.rs
new file mode 100644
index 0000000..2cfe38f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/use_3.rs
@@ -0,0 +1,10 @@
+mod intrinsic {
+ pub fn foo() {}
+}
+
+pub mod a {
+ pub fn b() {
+ use crate::intrinsic;
+ intrinsic::foo();
+ }
+}
diff --git a/gcc/testsuite/rust/compile/use_self_alone.rs b/gcc/testsuite/rust/compile/use_self_alone.rs
new file mode 100644
index 0000000..1df923c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/use_self_alone.rs
@@ -0,0 +1,2 @@
+use self;
+// { dg-error ".self. imports are only allowed within a { } list" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/use_self_alone_in_list.rs b/gcc/testsuite/rust/compile/use_self_alone_in_list.rs
new file mode 100644
index 0000000..2e87227
--- /dev/null
+++ b/gcc/testsuite/rust/compile/use_self_alone_in_list.rs
@@ -0,0 +1,7 @@
+struct B;
+
+use {B as B2, self};
+// { dg-error ".self. import can only appear in an import list with a non-empty prefix" "" { target *-*-* } .-1 }
+
+use {self};
+// { dg-error ".self. import can only appear in an import list with a non-empty prefix" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/usize1.rs b/gcc/testsuite/rust/compile/usize1.rs
index 36cb99b..08f6c9c 100644
--- a/gcc/testsuite/rust/compile/usize1.rs
+++ b/gcc/testsuite/rust/compile/usize1.rs
@@ -1,5 +1,5 @@
fn main() {
let a = [1, 2, 3];
let b: u32 = 1;
- let c = a[b]; // { dg-error "the type ...integer..CAPACITY.. cannot be indexed by .u32." }
+ let c = a[b]; // { dg-error "the type ...integer.; 3.. cannot be indexed by .u32." }
}
diff --git a/gcc/testsuite/rust/compile/v0-mangle1.rs b/gcc/testsuite/rust/compile/v0-mangle1.rs
index 04c546e..b4a8c13 100644
--- a/gcc/testsuite/rust/compile/v0-mangle1.rs
+++ b/gcc/testsuite/rust/compile/v0-mangle1.rs
@@ -1,4 +1,5 @@
// { dg-additional-options -frust-mangling=v0 }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/v0-mangle2.rs b/gcc/testsuite/rust/compile/v0-mangle2.rs
index d092dcc..4378dd8 100644
--- a/gcc/testsuite/rust/compile/v0-mangle2.rs
+++ b/gcc/testsuite/rust/compile/v0-mangle2.rs
@@ -1,4 +1,5 @@
// { dg-additional-options -frust-mangling=v0 }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/compile/while_let1.rs b/gcc/testsuite/rust/compile/while_let1.rs
new file mode 100644
index 0000000..03d84df
--- /dev/null
+++ b/gcc/testsuite/rust/compile/while_let1.rs
@@ -0,0 +1,111 @@
+#![feature(lang_items)]
+
+// use self::Ordering::*;
+// use Ordering::*;
+
+// enum Ordering {
+// A,
+// B,
+// }
+
+// fn foo(_: Ordering) {}
+
+// fn main() {
+// let a = A;
+
+// foo(a);
+// foo(B);
+// }
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ Ok(T),
+ Err(E),
+}
+
+pub trait Try {
+ /// The type of this value when viewed as successful.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Ok;
+ /// The type of this value when viewed as failed.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Error;
+
+ /// Applies the "?" operator. A return of `Ok(t)` means that the
+ /// execution should continue normally, and the result of `?` is the
+ /// value `t`. A return of `Err(e)` means that execution should branch
+ /// to the innermost enclosing `catch`, or return from the function.
+ ///
+ /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+ /// in the return type of the enclosing scope (which must itself implement
+ /// `Try`). Specifically, the value `X::from_error(From::from(e))`
+ /// is returned, where `X` is the return type of the enclosing function.
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+ /// Wrap an error value to construct the composite result. For example,
+ /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: Self::Error) -> Self;
+
+ /// Wrap an OK value to construct the composite result. For example,
+ /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: Self::Ok) -> Self;
+}
+
+pub struct NoneError;
+
+pub enum Option<T> {
+ /// No value
+ None,
+ /// Some value `T`
+ Some(T),
+}
+
+impl<T> Option<T> {
+ pub fn ok_or<E>(self, err: E) -> Result<T, E> {
+ match self {
+ Some(ok) => Result::Ok(ok),
+ None => Result::Err(err),
+ }
+ }
+}
+
+use Option::*;
+
+#[unstable(feature = "try_trait", issue = "42327")]
+impl<T> Try for Option<T> {
+ type Ok = T;
+ type Error = NoneError;
+
+ #[inline]
+ fn into_result(self) -> Result<T, NoneError> {
+ self.ok_or(NoneError)
+ }
+
+ #[inline]
+ fn from_ok(v: T) -> Self {
+ Some(v)
+ }
+
+ #[inline]
+ fn from_error(_: NoneError) -> Self {
+ None
+ }
+}
+
+fn foo() -> Option<i32> {
+ Option::Some(15)
+}
+
+fn main() {
+ // let _: Option<i32> = try { 15i32 };
+
+ while let Option::Some(15) = foo() {}
+}
diff --git a/gcc/testsuite/rust/compile/while_let_without_label.rs b/gcc/testsuite/rust/compile/while_let_without_label.rs
new file mode 100644
index 0000000..e04e4b5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/while_let_without_label.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-frust-compile-until=lowering" }
+
+enum Foo {
+ A(i32),
+}
+
+fn main() {
+ let b = Foo::A(15);
+
+ while let Foo::A(x) = b {}
+}
diff --git a/gcc/testsuite/rust/compile/xfail/name_resolution21.rs b/gcc/testsuite/rust/compile/xfail/name_resolution21.rs
index df48d00..fc8e94b 100644
--- a/gcc/testsuite/rust/compile/xfail/name_resolution21.rs
+++ b/gcc/testsuite/rust/compile/xfail/name_resolution21.rs
@@ -1,5 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub macro bar() {}
}
diff --git a/gcc/testsuite/rust/core/core.exp b/gcc/testsuite/rust/core/core.exp
new file mode 100644
index 0000000..45bdbb5
--- /dev/null
+++ b/gcc/testsuite/rust/core/core.exp
@@ -0,0 +1,37 @@
+# Copyright (C) 2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Compile test libcore, no torture testing.
+#
+# Skip torture testing for now, as it'd be slow
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "compile"
+set individual_timeout 600
+dg-additional-files [lsort [glob -nocomplain $srcdir/../../libgrust/rustc-lib/*]]
+dg-runtest $srcdir/../../libgrust/rustc-lib/core/src/lib.rs "-frust-edition=2018 -frust-crate=core -frust-compile-until=nameresolution -w" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rust/execute/black_box.rs b/gcc/testsuite/rust/execute/black_box.rs
new file mode 100644
index 0000000..8fa2cce
--- /dev/null
+++ b/gcc/testsuite/rust/execute/black_box.rs
@@ -0,0 +1,31 @@
+/* { dg-output "Value is: 42\r*\n" } */
+#![feature(rustc_attrs, lang_items)]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[rustc_builtin_macro]
+macro_rules! llvm_asm {
+ () => {};
+}
+
+pub fn black_box<T>(mut dummy: T) -> T {
+ unsafe {
+ llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
+ }
+
+ dummy
+}
+
+fn main() -> i32 {
+ let dummy: i32 = 42;
+ let result = black_box(dummy);
+ unsafe {
+ printf("Value is: %i\n\0" as *const str as *const i8, result);
+ }
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/crate-metavar1.rs b/gcc/testsuite/rust/execute/crate-metavar1.rs
new file mode 100644
index 0000000..8418308
--- /dev/null
+++ b/gcc/testsuite/rust/execute/crate-metavar1.rs
@@ -0,0 +1,11 @@
+macro_rules! foo {
+ () => {
+ $crate::bar()
+ }
+}
+
+pub fn bar() -> i32 { 1 }
+
+fn main() -> i32 {
+ foo!() - crate::bar()
+}
diff --git a/gcc/testsuite/rust/execute/execute.exp b/gcc/testsuite/rust/execute/execute.exp
new file mode 100644
index 0000000..3754778
--- /dev/null
+++ b/gcc/testsuite/rust/execute/execute.exp
@@ -0,0 +1,33 @@
+# Copyright (C) 2021-2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Execute tests.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "run"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rust/execute/inline_asm_inout_ident.rs b/gcc/testsuite/rust/execute/inline_asm_inout_ident.rs
new file mode 100644
index 0000000..324b84d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/inline_asm_inout_ident.rs
@@ -0,0 +1,24 @@
+/* { dg-do run { target x86_64*-*-* } } */
+/* { dg-output "Value is: 5\r*\n" } */
+#![feature(rustc_attrs)]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+ () => {};
+}
+
+fn main() -> i32 {
+ let x: i32;
+ // `inout` can also move values to different places
+ unsafe {
+ asm!("inc {}", inout(reg) 4u64=>x);
+ }
+ unsafe {
+ printf("Value is: %i\n\0" as *const str as *const i8, x);
+ }
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/inline_asm_inout_var.rs b/gcc/testsuite/rust/execute/inline_asm_inout_var.rs
new file mode 100644
index 0000000..fff432e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/inline_asm_inout_var.rs
@@ -0,0 +1,25 @@
+/* { dg-do run { target x86_64*-*-* } } */
+/* { dg-output "Value is: 5\r*\n" } */
+#![feature(rustc_attrs)]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+ () => {};
+}
+
+fn main() -> i32 {
+ let y: i32 = 4;
+ let x: i32;
+ // `inout` can also move values to different places
+ unsafe {
+ asm!("inc {}", inout(reg) y=>x);
+ }
+ unsafe {
+ printf("Value is: %i\n\0" as *const str as *const i8, x);
+ }
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/atomic_load.rs b/gcc/testsuite/rust/execute/torture/atomic_load.rs
index 11da848..c272700 100644
--- a/gcc/testsuite/rust/execute/torture/atomic_load.rs
+++ b/gcc/testsuite/rust/execute/torture/atomic_load.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/atomic_store.rs b/gcc/testsuite/rust/execute/torture/atomic_store.rs
index 1b46678..acf7c64c 100644
--- a/gcc/testsuite/rust/execute/torture/atomic_store.rs
+++ b/gcc/testsuite/rust/execute/torture/atomic_store.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs b/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs
new file mode 100644
index 0000000..d51c95d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs
@@ -0,0 +1,191 @@
+/* { dg-output "less\r*" }*/
+#![feature(lang_items)]
+
+mod core {
+ mod option {
+ pub enum Option<T> {
+ None,
+ Some(T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {}
+
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {}
+
+ #[lang = "sized"]
+ pub trait Sized {}
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ pub enum Ordering {
+ Less = -1,
+ Equal = 0,
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ pub trait Eq: PartialEq<Self> {
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) | Option::Some(Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) | Option::Some(Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ pub trait Ord: Eq + PartialOrd<Self> {
+ fn cmp(&self, other: &Self) -> Ordering;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::option::Option;
+
+// Needed impls for primitives
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self < *other {
+ Option::Some(Ordering::Less)
+ } else if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Eq for i32 {}
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self < *other {
+ Ordering::Less
+ } else if *self > *other {
+ Ordering::Greater
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// Manual impl for struct Bar
+struct Bar {
+ a: i32,
+ b: i32,
+}
+
+impl PartialEq for Bar {
+ fn eq(&self, other: &Self) -> bool {
+ self.a.eq(&other.a) && self.b.eq(&other.b)
+ }
+}
+
+impl Eq for Bar {}
+
+impl PartialOrd for Bar {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ match self.a.partial_cmp(&other.a) {
+ Option::Some(Ordering::Equal) => self.b.partial_cmp(&other.b),
+ ord => ord,
+ }
+ }
+}
+
+impl Ord for Bar {
+ fn cmp(&self, other: &Self) -> Ordering {
+ match self.a.cmp(&other.a) {
+ Ordering::Equal => self.b.cmp(&other.b),
+ ord => ord,
+ }
+ }
+}
+
+// External print shim
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let x = Bar { a: 1, b: 2 };
+ let y = Bar { a: 1, b: 3 };
+
+ match x.partial_cmp(&y) {
+ Option::Some(Ordering::Less) => print("less"),
+ Option::Some(Ordering::Greater) => print("greater"),
+ Option::Some(Ordering::Equal) => print("equal"),
+ _ => print("none"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs b/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs
new file mode 100644
index 0000000..86c26df
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs
@@ -0,0 +1,199 @@
+/* { dg-output "<><=>=\r*" } */
+/* { dg-options "-w" } */
+#![feature(lang_items)]
+
+mod core {
+ mod option {
+ pub enum Option<T> {
+ None,
+ Some(T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {}
+
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {}
+
+ #[lang = "sized"]
+ pub trait Sized {}
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ pub enum Ordering {
+ Less = -1,
+ Equal = 0,
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ pub trait Eq: PartialEq<Self> {
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) | Option::Some(Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) | Option::Some(Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ pub trait Ord: Eq + PartialOrd<Self> {
+ fn cmp(&self, other: &Self) -> Ordering;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::option::Option;
+
+// Needed impls for primitives
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self < *other {
+ Option::Some(Ordering::Less)
+ } else if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Eq for i32 {}
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self < *other {
+ Ordering::Less
+ } else if *self > *other {
+ Ordering::Greater
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// Manual impl for struct Bar
+struct Bar {
+ a: i32,
+ b: i32,
+}
+
+impl PartialEq for Bar {
+ fn eq(&self, other: &Self) -> bool {
+ self.a.eq(&other.a) && self.b.eq(&other.b)
+ }
+}
+
+impl Eq for Bar {}
+
+impl PartialOrd for Bar {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ match self.a.partial_cmp(&other.a) {
+ Option::Some(Ordering::Equal) => self.b.partial_cmp(&other.b),
+ ord => ord,
+ }
+ }
+}
+
+impl Ord for Bar {
+ fn cmp(&self, other: &Self) -> Ordering {
+ match self.a.cmp(&other.a) {
+ Ordering::Equal => self.b.cmp(&other.b),
+ ord => ord,
+ }
+ }
+}
+
+// External print shim
+extern "C" {
+ fn printf(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ printf(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Bar { a: 1, b: 2 };
+ let b = Bar { a: 1, b: 3 };
+ let c = Bar { a: 1, b: 2 };
+
+ if a < b {
+ print("<");
+ }
+ if b > a {
+ print(">");
+ }
+ if a <= c {
+ print("<=");
+ }
+ if b >= c {
+ print(">=");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_abort.rs b/gcc/testsuite/rust/execute/torture/builtin_abort.rs
index 9f2d8c2..8c8259a 100644
--- a/gcc/testsuite/rust/execute/torture/builtin_abort.rs
+++ b/gcc/testsuite/rust/execute/torture/builtin_abort.rs
@@ -9,6 +9,6 @@ mod intrinsics {
}
pub fn main () -> i32 {
- abort();
+ intrinsics::abort();
0
}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs
index 6aec417..c8a2dae 100644
--- a/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs
@@ -25,7 +25,7 @@ fn print_int(value: i32) {
fn check_bytes(bytes: &[u8; 16]) {
let the_bytes = b"hello, include!\n";
- let x = true;
+ let mut x = true;
let mut i = 0;
// X is true iff bytes == the_bytes
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_option_env.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_option_env.rs
new file mode 100644
index 0000000..708c2aa
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_option_env.rs
@@ -0,0 +1,65 @@
+// { dg-output "VALUE\r*\nVALUE\r*\n" }
+// { dg-set-compiler-env-var ENV_MACRO_TEST "VALUE" }
+
+#![feature(rustc_attrs, lang_items)]
+
+#[rustc_builtin_macro]
+macro_rules! option_env {
+ () => {{}};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod option {
+ pub enum Option<T> {
+ #[lang = "Some"]
+ Some(T),
+ #[lang = "None"]
+ None,
+ }
+ }
+}
+
+use core::option::Option;
+
+extern "C" {
+ fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: &str) {
+ unsafe {
+ printf(
+ "%s\n" as *const str as *const i8,
+ s as *const str as *const i8,
+ );
+ }
+}
+
+macro_rules! env_macro_test {
+ () => { "ENV_MACRO_TEST" }
+}
+
+fn main() -> i32 {
+ let val0: Option<&'static str> = option_env!("ENV_MACRO_TEST");
+
+
+ match val0 {
+ Option::None => {},
+ Option::Some(s) => {
+ print(s);
+ }
+ }
+
+ //eager expansion test
+ let val1: Option<&'static str> = option_env!(env_macro_test!(),);
+
+ match val1 {
+ Option::None => {},
+ Option::Some(s) => {
+ print(s);
+ }
+ }
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/closure1.rs b/gcc/testsuite/rust/execute/torture/closure1.rs
index e956413..1a5e498 100644
--- a/gcc/testsuite/rust/execute/torture/closure1.rs
+++ b/gcc/testsuite/rust/execute/torture/closure1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/closure2.rs b/gcc/testsuite/rust/execute/torture/closure2.rs
index deca784..06f385f 100644
--- a/gcc/testsuite/rust/execute/torture/closure2.rs
+++ b/gcc/testsuite/rust/execute/torture/closure2.rs
@@ -1,4 +1,6 @@
// { dg-output "3\r*\n" }
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/closure3.rs b/gcc/testsuite/rust/execute/torture/closure3.rs
index 98ec261..e9c6244 100644
--- a/gcc/testsuite/rust/execute/torture/closure3.rs
+++ b/gcc/testsuite/rust/execute/torture/closure3.rs
@@ -1,4 +1,6 @@
// { dg-output "3\r*\n" }
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/closure4.rs b/gcc/testsuite/rust/execute/torture/closure4.rs
index 0701776..3f845dc 100644
--- a/gcc/testsuite/rust/execute/torture/closure4.rs
+++ b/gcc/testsuite/rust/execute/torture/closure4.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/coercion1.rs b/gcc/testsuite/rust/execute/torture/coercion1.rs
index 335f496..e6511b9 100644
--- a/gcc/testsuite/rust/execute/torture/coercion1.rs
+++ b/gcc/testsuite/rust/execute/torture/coercion1.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/coercion2.rs b/gcc/testsuite/rust/execute/torture/coercion2.rs
index 6be8602..cf316e4 100644
--- a/gcc/testsuite/rust/execute/torture/coercion2.rs
+++ b/gcc/testsuite/rust/execute/torture/coercion2.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/coercion3.rs b/gcc/testsuite/rust/execute/torture/coercion3.rs
index 0686056..a870bea 100644
--- a/gcc/testsuite/rust/execute/torture/coercion3.rs
+++ b/gcc/testsuite/rust/execute/torture/coercion3.rs
@@ -1,4 +1,5 @@
// { dg-output "123\r*\n" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/const-generics-1.rs b/gcc/testsuite/rust/execute/torture/const-generics-1.rs
new file mode 100644
index 0000000..3ad1b3b
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const-generics-1.rs
@@ -0,0 +1,26 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<const N: usize>;
+
+impl Foo<1> {
+ fn call(&self) -> i32 {
+ 10
+ }
+}
+
+impl Foo<2> {
+ fn call(&self) -> i32 {
+ 20
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo::<1> {};
+ let b = Foo::<2> {};
+ let aa = a.call();
+ let bb = b.call();
+ bb - aa - 10
+}
diff --git a/gcc/testsuite/rust/execute/torture/const-generics-2.rs b/gcc/testsuite/rust/execute/torture/const-generics-2.rs
new file mode 100644
index 0000000..6ed5535
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const-generics-2.rs
@@ -0,0 +1,22 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Magic {
+ fn magic(&self) -> usize;
+}
+
+struct Foo<const N: usize>;
+
+impl<const N: usize> Magic for Foo<N> {
+ fn magic(&self) -> usize {
+ N
+ }
+}
+
+fn main() -> i32 {
+ let f = Foo::<7> {};
+ let n = f.magic();
+ n as i32 - 7
+}
diff --git a/gcc/testsuite/rust/execute/torture/const-generics-3.rs b/gcc/testsuite/rust/execute/torture/const-generics-3.rs
new file mode 100644
index 0000000..289b865
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const-generics-3.rs
@@ -0,0 +1,14 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+fn simd_shuffle<const N: usize>(idx: [u32; N]) -> [u32; N] {
+ idx
+}
+
+fn main() -> i32 {
+ let a = [1u32, 2, 3, 4];
+ let out = simd_shuffle(a);
+ let _check: [u32; 4] = out;
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/const-generics-4.rs b/gcc/testsuite/rust/execute/torture/const-generics-4.rs
new file mode 100644
index 0000000..9104f24
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const-generics-4.rs
@@ -0,0 +1,44 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+#[allow(unused)]
+macro_rules! simd_shuffle {
+ ($x:expr, $y:expr, $idx:expr $(,)?) => {{
+ simd_shuffle(
+ $x,
+ $y,
+ const {
+ let v: [u32; _] = $idx;
+ v
+ },
+ )
+ }};
+}
+
+const fn simd_shuffle(_a: [u32; 4], _b: [u32; 4], idx: [u32; 4]) -> [u32; 4] {
+ idx
+}
+
+fn main() -> i32 {
+ let a = [1, 2, 3, 4];
+ let b = [5, 6, 7, 8];
+ let indices = [3, 2, 1, 0];
+
+ let result: [u32; 4] = simd_shuffle!(a, b, indices);
+
+ if result[0] != 3 {
+ return 1;
+ }
+ if result[1] != 2 {
+ return 2;
+ }
+ if result[2] != 1 {
+ return 3;
+ }
+ if result[3] != 0 {
+ return 4;
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/const-generics-5.rs b/gcc/testsuite/rust/execute/torture/const-generics-5.rs
new file mode 100644
index 0000000..91006ed
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const-generics-5.rs
@@ -0,0 +1,15 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<const N: usize>;
+
+impl<const N: usize> Foo<N> {
+ const VALUE: usize = N;
+}
+
+fn main() -> i32 {
+ let val = Foo::<7>::VALUE;
+ val as i32 - 7
+}
diff --git a/gcc/testsuite/rust/execute/torture/const-generics-6.rs b/gcc/testsuite/rust/execute/torture/const-generics-6.rs
new file mode 100644
index 0000000..0aa7fae
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const-generics-6.rs
@@ -0,0 +1,17 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<const N: usize>;
+
+impl<const N: usize> Foo<N> {
+ const VALUE: usize = N;
+ const SQUARE: usize = N * N;
+}
+
+fn main() -> i32 {
+ let a = Foo::<5>::VALUE; // 5
+ let b = Foo::<5>::SQUARE; // 25
+ (a + b) as i32 - 30
+}
diff --git a/gcc/testsuite/rust/execute/torture/const-generics-7.rs b/gcc/testsuite/rust/execute/torture/const-generics-7.rs
new file mode 100644
index 0000000..c75d897
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const-generics-7.rs
@@ -0,0 +1,23 @@
+#![feature(intrinsics)]
+
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+mod mem {
+ extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
+ pub fn size_of<T>() -> usize;
+ }
+}
+
+struct Foo<T>;
+
+impl<T> Foo<T> {
+ const MAGIC: usize = mem::size_of::<T>();
+}
+
+fn main() -> i32 {
+ let sz = Foo::<u16>::MAGIC;
+ sz as i32 - 2
+}
diff --git a/gcc/testsuite/rust/execute/torture/const_block1.rs b/gcc/testsuite/rust/execute/torture/const_block1.rs
new file mode 100644
index 0000000..eaf3432
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const_block1.rs
@@ -0,0 +1,9 @@
+const X: i32 = const {
+ let a = 15;
+ let b = 14;
+ a + b
+};
+
+fn main() -> i32 {
+ X - 29
+}
diff --git a/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs b/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs
index 15bb811..662f813 100644
--- a/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs
+++ b/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs
@@ -1,4 +1,5 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/derive-default1.rs b/gcc/testsuite/rust/execute/torture/derive-default1.rs
new file mode 100644
index 0000000..775f5be
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/derive-default1.rs
@@ -0,0 +1,28 @@
+#![feature(lang_items)]
+
+#[derive(Default)]
+struct Foo { a: i32 }
+#[derive(Default)]
+struct Bar(i32);
+
+#[lang = "sized"]
+trait Sized {}
+
+mod core {
+ mod default {
+ trait Default: Sized {
+ fn default() -> Self;
+ }
+
+ impl Default for i32 {
+ fn default() -> Self { 1 }
+ }
+ }
+}
+
+fn main() -> i32 {
+ let foo = Foo::default();
+ let bar = Bar::default();
+
+ foo.a + bar.0 - 2
+}
diff --git a/gcc/testsuite/rust/execute/torture/derive-partialeq1.rs b/gcc/testsuite/rust/execute/torture/derive-partialeq1.rs
new file mode 100644
index 0000000..442ee67
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/derive-partialeq1.rs
@@ -0,0 +1,64 @@
+// { dg-output "true\r*\nfalse\r*\nfalse\r*\n" }
+
+#![feature(intrinsics, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ /// This method tests for `!=`.
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
+#[derive(PartialEq, Copy)] // { dg-warning "unused name" }
+struct Foo;
+
+#[derive(PartialEq)]
+struct Bar(Foo);
+
+#[derive(PartialEq)]
+struct Baz { _inner: Foo }
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(b: bool) {
+ if b {
+ unsafe { puts("true" as *const str as *const i8) }
+ } else {
+ unsafe { puts("false" as *const str as *const i8) }
+ }
+}
+
+fn main() -> i32 {
+ let x = Foo;
+
+ let b1 = x == Foo;
+ let b2 = Bar(x) != Bar(Foo);
+ let b3 = Baz { _inner: Foo } != Baz { _inner: x };
+
+ print(b1);
+ print(b2);
+ print(b3);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs b/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs
new file mode 100644
index 0000000..1f4c374
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs
@@ -0,0 +1,80 @@
+// { dg-output "true\r*\nfalse\r*\nfalse\r*\nfalse\r*\nfalse\r*\n" }
+
+#![feature(intrinsics, lang_items)]
+
+pub mod core {
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ /// This method tests for `!=`.
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+#[derive(PartialEq)]
+enum Foo {
+ A { a: i32, b: i32 },
+ B(i32, i32),
+ C,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(b: bool) {
+ if b {
+ unsafe { puts("true\0" as *const str as *const i8) }
+ } else {
+ unsafe { puts("false\0" as *const str as *const i8) }
+ }
+}
+
+fn main() -> i32 {
+ let x = Foo::A { a: 15, b: 14 };
+
+ let b1 = x == Foo::A { a: 15, b: 14 };
+ let b12 = x == Foo::A { a: 15, b: 19 };
+ let b13 = x == Foo::A { a: 19, b: 14 };
+ let b2 = x == Foo::B(15, 14);
+ let b3 = x == Foo::C;
+
+ print(b1);
+ print(b12);
+ print(b13);
+ print(b2);
+ print(b3);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/derive_clone_enum1.rs b/gcc/testsuite/rust/execute/torture/derive_clone_enum1.rs
new file mode 100644
index 0000000..28a120f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/derive_clone_enum1.rs
@@ -0,0 +1,53 @@
+#![feature(lang_items)]
+
+#[lang = "clone"]
+trait Clone {
+ pub fn clone(&self) -> Self;
+}
+
+impl Clone for i32 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+#[derive(Clone)]
+enum MixAndMatch {
+ A,
+ B(i32),
+ C { inner: i32 }
+}
+
+fn main() -> i32 {
+ let a = MixAndMatch::A;
+ let a_copy = a.clone();
+
+ // we want res to stay at zero - when we don't match on the right thing, increase it
+
+ let mut res = match a_copy {
+ MixAndMatch::A => 0,
+ _ => 1,
+ };
+
+ let a = MixAndMatch::B(15);
+ let a_copy = a.clone();
+
+ match a_copy {
+ MixAndMatch::B(15) => {},
+ _ => res += 1,
+ };
+
+ let a = MixAndMatch::C { inner: 15 };
+ let a_copy = a.clone();
+
+ match a_copy {
+ MixAndMatch::C { inner } => {
+ if inner != 15 {
+ res += 1;
+ }
+ },
+ _ => res += 1,
+ };
+
+ res
+}
diff --git a/gcc/testsuite/rust/execute/torture/derive_macro1.rs b/gcc/testsuite/rust/execute/torture/derive_macro1.rs
index 22cfaaa..780a30f 100644
--- a/gcc/testsuite/rust/execute/torture/derive_macro1.rs
+++ b/gcc/testsuite/rust/execute/torture/derive_macro1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/derive_macro3.rs b/gcc/testsuite/rust/execute/torture/derive_macro3.rs
index 7b3a089..e8fe94c 100644
--- a/gcc/testsuite/rust/execute/torture/derive_macro3.rs
+++ b/gcc/testsuite/rust/execute/torture/derive_macro3.rs
@@ -1,6 +1,8 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
+#[lang = "clone"]
pub trait Clone {
fn clone(&self) -> Self;
}
diff --git a/gcc/testsuite/rust/execute/torture/derive_macro4.rs b/gcc/testsuite/rust/execute/torture/derive_macro4.rs
index c355ac7..adeeb8d 100644
--- a/gcc/testsuite/rust/execute/torture/derive_macro4.rs
+++ b/gcc/testsuite/rust/execute/torture/derive_macro4.rs
@@ -1,6 +1,8 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
+#[lang = "clone"]
pub trait Clone {
fn clone(&self) -> Self;
}
diff --git a/gcc/testsuite/rust/execute/torture/enum_intrinsics1.rs b/gcc/testsuite/rust/execute/torture/enum_intrinsics1.rs
new file mode 100644
index 0000000..66011b5
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/enum_intrinsics1.rs
@@ -0,0 +1,49 @@
+/* { dg-output "0\r*\n2\r*\n" } */
+#![feature(intrinsics)]
+
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+enum BookFormat {
+ Paperback,
+ Hardback,
+ Ebook,
+}
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+mod core {
+ mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+pub fn main() -> i32 {
+ let a = BookFormat::Paperback;
+ let b = BookFormat::Ebook;
+
+ unsafe {
+ let val1: isize = core::intrinsics::discriminant_value(&a);
+ let val2 = core::intrinsics::discriminant_value(&b);
+
+ let a = "%i\n";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, val1 as i32);
+ printf(c, val2 as i32);
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/enum_intrinsics2.rs b/gcc/testsuite/rust/execute/torture/enum_intrinsics2.rs
new file mode 100644
index 0000000..5f7d5ff
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/enum_intrinsics2.rs
@@ -0,0 +1,26 @@
+#![feature(intrinsics)]
+
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+enum BookFormat {
+ Paperback,
+ Hardback,
+ Ebook,
+}
+
+mod core {
+ mod intrinsics {
+ extern "rust-intrinsic" {
+ #[rustc_const_unstable(feature = "variant_count", issue = "73662")]
+ pub fn variant_count<T>() -> usize;
+ }
+ }
+}
+
+pub fn main() -> i32 {
+ let count = core::intrinsics::variant_count::<BookFormat>();
+
+ (count as i32) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/for-loop1.rs b/gcc/testsuite/rust/execute/torture/for-loop1.rs
new file mode 100644
index 0000000..e48a4b1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/for-loop1.rs
@@ -0,0 +1,545 @@
+// { dg-output "loop\r*\nloop\r*\n" }
+#![feature(intrinsics, lang_items)]
+
+pub use option::Option::{self, None, Some};
+pub use result::Result::{self, Err, Ok};
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+ fn puts(s: *const i8);
+}
+
+mod option {
+ pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+ }
+}
+
+mod result {
+ enum Result<T, E> {
+ Ok(T),
+ Err(E),
+ }
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+ fn clone(&self) -> Self;
+
+ fn clone_from(&mut self, source: &Self) {
+ *self = source.clone()
+ }
+}
+
+mod impls {
+ use super::Clone;
+
+ macro_rules! impl_clone {
+ ($($t:ty)*) => {
+ $(
+ impl Clone for $t {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ )*
+ }
+ }
+
+ impl_clone! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[lang = "copy"]
+pub trait Copy: Clone {
+ // Empty.
+}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ pub fn wrapping_sub<T>(a: T, b: T) -> T;
+ pub fn rotate_left<T>(a: T, b: T) -> T;
+ pub fn rotate_right<T>(a: T, b: T) -> T;
+ pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+ pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+ pub fn move_val_init<T>(dst: *mut T, src: T);
+ pub fn uninit<T>() -> T;
+ }
+}
+
+mod ptr {
+ #[lang = "const_ptr"]
+ impl<T> *const T {
+ pub unsafe fn offset(self, count: isize) -> *const T {
+ crate::intrinsics::offset(self, count)
+ }
+ }
+
+ #[lang = "mut_ptr"]
+ impl<T> *mut T {
+ pub unsafe fn offset(self, count: isize) -> *mut T {
+ crate::intrinsics::offset(self, count) as *mut T
+ }
+ }
+
+ pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
+ let x = x as *mut u8;
+ let y = y as *mut u8;
+ let len = crate::mem::size_of::<T>() * count;
+ swap_nonoverlapping_bytes(x, y, len)
+ }
+
+ pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
+ // For types smaller than the block optimization below,
+ // just swap directly to avoid pessimizing codegen.
+ if crate::mem::size_of::<T>() < 32 {
+ let z = read(x);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
+ write(y, z);
+ } else {
+ swap_nonoverlapping(x, y, 1);
+ }
+ }
+
+ pub unsafe fn write<T>(dst: *mut T, src: T) {
+ crate::intrinsics::move_val_init(&mut *dst, src)
+ }
+
+ pub unsafe fn read<T>(src: *const T) -> T {
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ tmp
+ }
+
+ pub unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
+ struct Block(u64, u64, u64, u64);
+ struct UnalignedBlock(u64, u64, u64, u64);
+
+ let block_size = crate::mem::size_of::<Block>();
+
+ // Loop through x & y, copying them `Block` at a time
+ // The optimizer should unroll the loop fully for most types
+ // N.B. We can't use a for loop as the `range` impl calls `mem::swap` recursively
+ let mut i: usize = 0;
+ while i + block_size <= len {
+ // Create some uninitialized memory as scratch space
+ // Declaring `t` here avoids aligning the stack when this loop is unused
+ let mut t: Block = crate::mem::uninitialized();
+ let t = &mut t as *mut _ as *mut u8;
+ let x = x.offset(i as isize);
+ let y = y.offset(i as isize);
+
+ // Swap a block of bytes of x & y, using t as a temporary buffer
+ // This should be optimized into efficient SIMD operations where available
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
+ i += block_size;
+ }
+
+ if i < len {
+ // Swap any remaining bytes
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
+ let rem = len - i;
+
+ let t = &mut t as *mut _ as *mut u8;
+ let x = x.offset(i as isize);
+ let y = y.offset(i as isize);
+
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
+ }
+ }
+}
+
+mod mem {
+ extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+ pub fn transmute<T, U>(_: T) -> U;
+ #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
+ pub fn size_of<T>() -> usize;
+ }
+
+ pub fn swap<T>(x: &mut T, y: &mut T) {
+ unsafe {
+ crate::ptr::swap_nonoverlapping_one(x, y);
+ }
+ }
+
+ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
+ swap(dest, &mut src);
+ src
+ }
+
+ pub unsafe fn uninitialized<T>() -> T {
+ crate::intrinsics::uninit()
+ }
+}
+
+macro_rules! impl_uint {
+ ($($ty:ident = $lang:literal),*) => {
+ $(
+ impl $ty {
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::wrapping_add(self, rhs)
+ }
+ }
+
+ pub fn wrapping_sub(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::wrapping_sub(self, rhs)
+ }
+ }
+
+ pub fn rotate_left(self, n: u32) -> Self {
+ unsafe {
+ intrinsics::rotate_left(self, n as Self)
+ }
+ }
+
+ pub fn rotate_right(self, n: u32) -> Self {
+ unsafe {
+ intrinsics::rotate_right(self, n as Self)
+ }
+ }
+
+ pub fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ }
+
+ pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ Self::from_le(Self::from_ne_bytes(bytes))
+ }
+
+ pub const fn from_le(x: Self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ x
+ }
+ }
+
+ pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ unsafe { mem::transmute(bytes) }
+ }
+
+ pub fn checked_add(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_add(rhs);
+ if b {
+ Option::None
+ } else {
+ Option::Some(a)
+ }
+ }
+
+ pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe { intrinsics::add_with_overflow(self as $ty, rhs as $ty) };
+ (a as Self, b)
+ }
+ }
+ )*
+ }
+}
+
+impl_uint!(
+ u8 = "u8",
+ u16 = "u16",
+ u32 = "u32",
+ u64 = "u64",
+ usize = "usize"
+);
+
+#[lang = "add"]
+pub trait Add<RHS = Self> {
+ type Output;
+
+ fn add(self, rhs: RHS) -> Self::Output;
+}
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ impl Add for $t {
+ type Output = $t;
+
+ fn add(self, other: $t) -> $t { self + other }
+ }
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 }
+
+#[lang = "sub"]
+pub trait Sub<RHS = Self> {
+ type Output;
+
+ fn sub(self, rhs: RHS) -> Self::Output;
+}
+macro_rules! sub_impl {
+ ($($t:ty)*) => ($(
+ impl Sub for $t {
+ type Output = $t;
+
+ fn sub(self, other: $t) -> $t { self - other }
+ }
+ )*)
+}
+
+sub_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 }
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+ pub start: Idx,
+ pub end: Idx,
+}
+
+pub trait TryFrom<T>: Sized {
+ /// The type returned in the event of a conversion error.
+ type Error;
+
+ /// Performs the conversion.
+ fn try_from(value: T) -> Result<Self, Self::Error>;
+}
+
+pub trait From<T>: Sized {
+ fn from(_: T) -> Self;
+}
+
+impl<T> From<T> for T {
+ fn from(t: T) -> T {
+ t
+ }
+}
+
+impl<T, U> TryFrom<U> for T
+where
+ T: From<U>,
+{
+ type Error = !;
+
+ fn try_from(value: U) -> Result<Self, Self::Error> {
+ Ok(T::from(value))
+ }
+}
+
+trait Step {
+ /// Returns the number of steps between two step objects. The count is
+ /// inclusive of `start` and exclusive of `end`.
+ ///
+ /// Returns `None` if it is not possible to calculate `steps_between`
+ /// without overflow.
+ fn steps_between(start: &Self, end: &Self) -> Option<usize>;
+
+ /// Replaces this step with `1`, returning itself
+ fn replace_one(&mut self) -> Self;
+
+ /// Replaces this step with `0`, returning itself
+ fn replace_zero(&mut self) -> Self;
+
+ /// Adds one to this step, returning the result
+ fn add_one(&self) -> Self;
+
+ /// Subtracts one to this step, returning the result
+ fn sub_one(&self) -> Self;
+
+ /// Add an usize, returning None on overflow
+ fn add_usize(&self, n: usize) -> Option<Self>;
+}
+
+// These are still macro-generated because the integer literals resolve to different types.
+macro_rules! step_identical_methods {
+ () => {
+ #[inline]
+ fn replace_one(&mut self) -> Self {
+ mem::replace(self, 1)
+ }
+
+ #[inline]
+ fn replace_zero(&mut self) -> Self {
+ mem::replace(self, 0)
+ }
+
+ #[inline]
+ fn add_one(&self) -> Self {
+ Add::add(*self, 1)
+ }
+
+ #[inline]
+ fn sub_one(&self) -> Self {
+ Sub::sub(*self, 1)
+ }
+ };
+}
+
+macro_rules! step_impl_unsigned {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
+ if *start < *end {
+ // Note: We assume $t <= usize here
+ Option::Some((*end - *start) as usize)
+ } else {
+ Option::Some(0)
+ }
+ }
+
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ match <$t>::try_from(n) {
+ Result::Ok(n_as_t) => self.checked_add(n_as_t),
+ Result::Err(_) => Option::None,
+ }
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+macro_rules! step_impl_signed {
+ ($( [$t:ty : $unsigned:ty] )*) => ($(
+ impl Step for $t {
+ #[inline]
+ #[allow(trivial_numeric_casts)]
+ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
+ if *start < *end {
+ // Note: We assume $t <= isize here
+ // Use .wrapping_sub and cast to usize to compute the
+ // difference that may not fit inside the range of isize.
+ Option::Some((*end as isize).wrapping_sub(*start as isize) as usize)
+ } else {
+ Option::Some(0)
+ }
+ }
+
+ #[inline]
+ #[allow(unreachable_patterns)]
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ match <$unsigned>::try_from(n) {
+ Result::Ok(n_as_unsigned) => {
+ // Wrapping in unsigned space handles cases like
+ // `-120_i8.add_usize(200) == Option::Some(80_i8)`,
+ // even though 200_usize is out of range for i8.
+ let wrapped = (*self as $unsigned).wrapping_add(n_as_unsigned) as $t;
+ if wrapped >= *self {
+ Option::Some(wrapped)
+ } else {
+ Option::None // Addition overflowed
+ }
+ }
+ Result::Err(_) => Option::None,
+ }
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+
+macro_rules! step_impl_no_between {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ #[inline]
+ fn steps_between(_start: &Self, _end: &Self) -> Option<usize> {
+ Option::None
+ }
+
+ #[inline]
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ self.checked_add(n as $t)
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+
+step_impl_unsigned!(usize);
+
+pub trait Iterator {
+ type Item;
+
+ #[lang = "next"]
+ fn next(&mut self) -> Option<Self::Item>;
+}
+
+impl<A: Step> Iterator for Range<A> {
+ type Item = A;
+
+ fn next(&mut self) -> Option<A> {
+ if self.start < self.end {
+ // We check for overflow here, even though it can't actually
+ // happen. Adding this check does however help llvm vectorize loops
+ // for some ranges that don't get vectorized otherwise,
+ // and this won't actually result in an extra check in an optimized build.
+ match self.start.add_usize(1) {
+ Option::Some(mut n) => {
+ mem::swap(&mut n, &mut self.start);
+ Option::Some(n)
+ }
+ Option::None => Option::None,
+ }
+ } else {
+ Option::None
+ }
+ }
+}
+
+pub trait IntoIterator {
+ type Item;
+
+ type IntoIter: Iterator<Item = Self::Item>;
+
+ #[lang = "into_iter"]
+ fn into_iter(self) -> Self::IntoIter;
+}
+
+impl<I: Iterator> IntoIterator for I {
+ type Item = I::Item;
+ type IntoIter = I;
+
+ fn into_iter(self) -> I {
+ self
+ }
+}
+
+pub fn main() -> i32 {
+ let a = 1usize..3usize;
+
+ for i in a { // { dg-warning "unused name" }
+ unsafe { puts("loop\0" as *const str as *const i8); }
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/for-loop2.rs b/gcc/testsuite/rust/execute/torture/for-loop2.rs
new file mode 100644
index 0000000..022e951
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/for-loop2.rs
@@ -0,0 +1,544 @@
+// { dg-output "loop1\r*\nloop2\r*\n" }
+#![feature(intrinsics, lang_items)]
+
+pub use option::Option::{self, None, Some};
+pub use result::Result::{self, Err, Ok};
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+mod option {
+ pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+ }
+}
+
+mod result {
+ enum Result<T, E> {
+ Ok(T),
+ Err(E),
+ }
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+ fn clone(&self) -> Self;
+
+ fn clone_from(&mut self, source: &Self) {
+ *self = source.clone()
+ }
+}
+
+mod impls {
+ use super::Clone;
+
+ macro_rules! impl_clone {
+ ($($t:ty)*) => {
+ $(
+ impl Clone for $t {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ )*
+ }
+ }
+
+ impl_clone! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[lang = "copy"]
+pub trait Copy: Clone {
+ // Empty.
+}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ pub fn wrapping_sub<T>(a: T, b: T) -> T;
+ pub fn rotate_left<T>(a: T, b: T) -> T;
+ pub fn rotate_right<T>(a: T, b: T) -> T;
+ pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+ pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+ pub fn move_val_init<T>(dst: *mut T, src: T);
+ pub fn uninit<T>() -> T;
+ }
+}
+
+mod ptr {
+ #[lang = "const_ptr"]
+ impl<T> *const T {
+ pub unsafe fn offset(self, count: isize) -> *const T {
+ crate::intrinsics::offset(self, count)
+ }
+ }
+
+ #[lang = "mut_ptr"]
+ impl<T> *mut T {
+ pub unsafe fn offset(self, count: isize) -> *mut T {
+ crate::intrinsics::offset(self, count) as *mut T
+ }
+ }
+
+ pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
+ let x = x as *mut u8;
+ let y = y as *mut u8;
+ let len = crate::mem::size_of::<T>() * count;
+ swap_nonoverlapping_bytes(x, y, len)
+ }
+
+ pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
+ // For types smaller than the block optimization below,
+ // just swap directly to avoid pessimizing codegen.
+ if crate::mem::size_of::<T>() < 32 {
+ let z = read(x);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
+ write(y, z);
+ } else {
+ swap_nonoverlapping(x, y, 1);
+ }
+ }
+
+ pub unsafe fn write<T>(dst: *mut T, src: T) {
+ crate::intrinsics::move_val_init(&mut *dst, src)
+ }
+
+ pub unsafe fn read<T>(src: *const T) -> T {
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ tmp
+ }
+
+ pub unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
+ struct Block(u64, u64, u64, u64);
+ struct UnalignedBlock(u64, u64, u64, u64);
+
+ let block_size = crate::mem::size_of::<Block>();
+
+ // Loop through x & y, copying them `Block` at a time
+ // The optimizer should unroll the loop fully for most types
+ // N.B. We can't use a for loop as the `range` impl calls `mem::swap` recursively
+ let mut i: usize = 0;
+ while i + block_size <= len {
+ // Create some uninitialized memory as scratch space
+ // Declaring `t` here avoids aligning the stack when this loop is unused
+ let mut t: Block = crate::mem::uninitialized();
+ let t = &mut t as *mut _ as *mut u8;
+ let x = x.offset(i as isize);
+ let y = y.offset(i as isize);
+
+ // Swap a block of bytes of x & y, using t as a temporary buffer
+ // This should be optimized into efficient SIMD operations where available
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
+ i += block_size;
+ }
+
+ if i < len {
+ // Swap any remaining bytes
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
+ let rem = len - i;
+
+ let t = &mut t as *mut _ as *mut u8;
+ let x = x.offset(i as isize);
+ let y = y.offset(i as isize);
+
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
+ }
+ }
+}
+
+mod mem {
+ extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+ pub fn transmute<T, U>(_: T) -> U;
+ #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
+ pub fn size_of<T>() -> usize;
+ }
+
+ pub fn swap<T>(x: &mut T, y: &mut T) {
+ unsafe {
+ crate::ptr::swap_nonoverlapping_one(x, y);
+ }
+ }
+
+ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
+ swap(dest, &mut src);
+ src
+ }
+
+ pub unsafe fn uninitialized<T>() -> T {
+ crate::intrinsics::uninit()
+ }
+}
+
+macro_rules! impl_uint {
+ ($($ty:ident = $lang:literal),*) => {
+ $(
+ impl $ty {
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::wrapping_add(self, rhs)
+ }
+ }
+
+ pub fn wrapping_sub(self, rhs: Self) -> Self {
+ unsafe {
+ intrinsics::wrapping_sub(self, rhs)
+ }
+ }
+
+ pub fn rotate_left(self, n: u32) -> Self {
+ unsafe {
+ intrinsics::rotate_left(self, n as Self)
+ }
+ }
+
+ pub fn rotate_right(self, n: u32) -> Self {
+ unsafe {
+ intrinsics::rotate_right(self, n as Self)
+ }
+ }
+
+ pub fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ }
+
+ pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ Self::from_le(Self::from_ne_bytes(bytes))
+ }
+
+ pub const fn from_le(x: Self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ x
+ }
+ }
+
+ pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ unsafe { mem::transmute(bytes) }
+ }
+
+ pub fn checked_add(self, rhs: Self) -> Option<Self> {
+ let (a, b) = self.overflowing_add(rhs);
+ if b {
+ Option::None
+ } else {
+ Option::Some(a)
+ }
+ }
+
+ pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (a, b) = unsafe { intrinsics::add_with_overflow(self as $ty, rhs as $ty) };
+ (a as Self, b)
+ }
+ }
+ )*
+ }
+}
+
+impl_uint!(
+ u8 = "u8",
+ u16 = "u16",
+ u32 = "u32",
+ u64 = "u64",
+ usize = "usize"
+);
+
+#[lang = "add"]
+pub trait Add<RHS = Self> {
+ type Output;
+
+ fn add(self, rhs: RHS) -> Self::Output;
+}
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ impl Add for $t {
+ type Output = $t;
+
+ fn add(self, other: $t) -> $t { self + other }
+ }
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 }
+
+#[lang = "sub"]
+pub trait Sub<RHS = Self> {
+ type Output;
+
+ fn sub(self, rhs: RHS) -> Self::Output;
+}
+macro_rules! sub_impl {
+ ($($t:ty)*) => ($(
+ impl Sub for $t {
+ type Output = $t;
+
+ fn sub(self, other: $t) -> $t { self - other }
+ }
+ )*)
+}
+
+sub_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 }
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+ pub start: Idx,
+ pub end: Idx,
+}
+
+pub trait TryFrom<T>: Sized {
+ /// The type returned in the event of a conversion error.
+ type Error;
+
+ /// Performs the conversion.
+ fn try_from(value: T) -> Result<Self, Self::Error>;
+}
+
+pub trait From<T>: Sized {
+ fn from(_: T) -> Self;
+}
+
+impl<T> From<T> for T {
+ fn from(t: T) -> T {
+ t
+ }
+}
+
+impl<T, U> TryFrom<U> for T
+where
+ T: From<U>,
+{
+ type Error = !;
+
+ fn try_from(value: U) -> Result<Self, Self::Error> {
+ Ok(T::from(value))
+ }
+}
+
+trait Step {
+ /// Returns the number of steps between two step objects. The count is
+ /// inclusive of `start` and exclusive of `end`.
+ ///
+ /// Returns `None` if it is not possible to calculate `steps_between`
+ /// without overflow.
+ fn steps_between(start: &Self, end: &Self) -> Option<usize>;
+
+ /// Replaces this step with `1`, returning itself
+ fn replace_one(&mut self) -> Self;
+
+ /// Replaces this step with `0`, returning itself
+ fn replace_zero(&mut self) -> Self;
+
+ /// Adds one to this step, returning the result
+ fn add_one(&self) -> Self;
+
+ /// Subtracts one to this step, returning the result
+ fn sub_one(&self) -> Self;
+
+ /// Add an usize, returning None on overflow
+ fn add_usize(&self, n: usize) -> Option<Self>;
+}
+
+// These are still macro-generated because the integer literals resolve to different types.
+macro_rules! step_identical_methods {
+ () => {
+ #[inline]
+ fn replace_one(&mut self) -> Self {
+ mem::replace(self, 1)
+ }
+
+ #[inline]
+ fn replace_zero(&mut self) -> Self {
+ mem::replace(self, 0)
+ }
+
+ #[inline]
+ fn add_one(&self) -> Self {
+ Add::add(*self, 1)
+ }
+
+ #[inline]
+ fn sub_one(&self) -> Self {
+ Sub::sub(*self, 1)
+ }
+ };
+}
+
+macro_rules! step_impl_unsigned {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
+ if *start < *end {
+ // Note: We assume $t <= usize here
+ Option::Some((*end - *start) as usize)
+ } else {
+ Option::Some(0)
+ }
+ }
+
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ match <$t>::try_from(n) {
+ Result::Ok(n_as_t) => self.checked_add(n_as_t),
+ Result::Err(_) => Option::None,
+ }
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+macro_rules! step_impl_signed {
+ ($( [$t:ty : $unsigned:ty] )*) => ($(
+ impl Step for $t {
+ #[inline]
+ #[allow(trivial_numeric_casts)]
+ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
+ if *start < *end {
+ // Note: We assume $t <= isize here
+ // Use .wrapping_sub and cast to usize to compute the
+ // difference that may not fit inside the range of isize.
+ Option::Some((*end as isize).wrapping_sub(*start as isize) as usize)
+ } else {
+ Option::Some(0)
+ }
+ }
+
+ #[inline]
+ #[allow(unreachable_patterns)]
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ match <$unsigned>::try_from(n) {
+ Result::Ok(n_as_unsigned) => {
+ // Wrapping in unsigned space handles cases like
+ // `-120_i8.add_usize(200) == Option::Some(80_i8)`,
+ // even though 200_usize is out of range for i8.
+ let wrapped = (*self as $unsigned).wrapping_add(n_as_unsigned) as $t;
+ if wrapped >= *self {
+ Option::Some(wrapped)
+ } else {
+ Option::None // Addition overflowed
+ }
+ }
+ Result::Err(_) => Option::None,
+ }
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+
+macro_rules! step_impl_no_between {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ #[inline]
+ fn steps_between(_start: &Self, _end: &Self) -> Option<usize> {
+ Option::None
+ }
+
+ #[inline]
+ fn add_usize(&self, n: usize) -> Option<Self> {
+ self.checked_add(n as $t)
+ }
+
+ step_identical_methods!();
+ }
+ )*)
+}
+
+step_impl_unsigned!(usize);
+
+pub trait Iterator {
+ type Item;
+
+ #[lang = "next"]
+ fn next(&mut self) -> Option<Self::Item>;
+}
+
+impl<A: Step> Iterator for Range<A> {
+ type Item = A;
+
+ fn next(&mut self) -> Option<A> {
+ if self.start < self.end {
+ // We check for overflow here, even though it can't actually
+ // happen. Adding this check does however help llvm vectorize loops
+ // for some ranges that don't get vectorized otherwise,
+ // and this won't actually result in an extra check in an optimized build.
+ match self.start.add_usize(1) {
+ Option::Some(mut n) => {
+ mem::swap(&mut n, &mut self.start);
+ Option::Some(n)
+ }
+ Option::None => Option::None,
+ }
+ } else {
+ Option::None
+ }
+ }
+}
+
+pub trait IntoIterator {
+ type Item;
+
+ type IntoIter: Iterator<Item = Self::Item>;
+
+ #[lang = "into_iter"]
+ fn into_iter(self) -> Self::IntoIter;
+}
+
+impl<I: Iterator> IntoIterator for I {
+ type Item = I::Item;
+ type IntoIter = I;
+
+ fn into_iter(self) -> I {
+ self
+ }
+}
+
+pub fn main() -> i32 {
+ let a = 1usize..3usize;
+
+ for i in a {
+ unsafe { printf("loop%d\n\0" as *const str as *const i8, i); }
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/gat1.rs b/gcc/testsuite/rust/execute/torture/gat1.rs
new file mode 100644
index 0000000..9a60986
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/gat1.rs
@@ -0,0 +1,20 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub struct MyBuf;
+
+trait Foo {
+ type Bar<T>: Sized;
+}
+
+impl Foo for MyBuf {
+ type Bar<T> = T;
+}
+
+type A = <MyBuf as Foo>::Bar<u32>;
+fn main() -> i32 {
+ let a: A = 1;
+ a as i32 - 1
+}
diff --git a/gcc/testsuite/rust/execute/torture/iflet.rs b/gcc/testsuite/rust/execute/torture/iflet.rs
new file mode 100644
index 0000000..da4e93a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/iflet.rs
@@ -0,0 +1,84 @@
+enum Res {
+ OK,
+ BAD,
+}
+
+enum LOption {
+ Some(i32),
+ None,
+}
+
+// Expect a Some(_)
+//
+// Check we can match a Some.
+fn test_can_destructure_Some(v: LOption) -> Res {
+ if let LOption::Some(v) = v {
+ return Res::OK;
+ }
+ return Res::BAD;
+}
+
+// Expect Some(100).
+//
+// Check we can destructure and the inner value is correct.
+fn test_inner_value_is_100(v: LOption) -> Res {
+ if let LOption::Some(v) = v {
+ return match v {
+ 100 => Res::OK,
+ _ => Res::BAD,
+ }
+ }
+ return Res::BAD;
+}
+
+// Expect a None as actual parameter.
+//
+// Only when we FAIL to match a Some do we take the else and return OK.
+fn test_if_else(v: LOption) -> Res {
+ if let LOption::Some(v) = v {
+ return Res::BAD;
+ } else {
+ return Res::OK;
+ }
+}
+
+fn main() -> i32 {
+
+ // Passing a None, so the function should return BAD
+ match test_can_destructure_Some(LOption::None) {
+ Res::OK => return 1,
+ Res::BAD => (),
+ }
+
+ // Same, but with a Some, should return OK
+ match test_can_destructure_Some(LOption::Some(1)) {
+ Res::OK => (),
+ Res::BAD => return 1,
+ }
+
+ // Check the destructuring is correct by looking for Some(100)
+ match test_inner_value_is_100(LOption::Some(100)) {
+ Res::OK => (),
+ Res::BAD => return 1,
+ }
+
+ // ... passing Some(1) should return BAD
+ match test_inner_value_is_100(LOption::Some(1)) {
+ Res::OK => return 1,
+ Res::BAD => (),
+ }
+
+ // ... and so does passing None
+ match test_inner_value_is_100(LOption::None) {
+ Res::OK => return 1,
+ Res::BAD => (),
+ }
+
+ // Check if let... else ...
+ match test_if_else(LOption::None) {
+ Res::OK => (),
+ Res::BAD => return 1,
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs b/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs
new file mode 100644
index 0000000..d1d63ce
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs
@@ -0,0 +1,34 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+macro_rules! impl_foo {
+ () => { impl Foo }
+}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+struct MyBaz; // { dg-warning "struct is never constructed" }
+impl Foo for MyBaz {}
+
+struct MyBar;
+
+impl Bar for MyBar {
+ type Baz = MyBaz;
+}
+
+pub fn foo(_value: impl Bar<Baz = impl_foo!()>) -> i32 {
+ 15
+}
+
+fn main() -> i32 {
+ let bar = MyBar;
+ let result: i32 = foo(bar);
+
+ result - 15
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_desugar.rs b/gcc/testsuite/rust/execute/torture/impl_desugar.rs
new file mode 100644
index 0000000..77309de
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_desugar.rs
@@ -0,0 +1,34 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+struct MyBaz; // { dg-warning "struct is never constructed" }
+impl Foo for MyBaz {}
+
+struct MyBar;
+
+impl Bar for MyBar {
+ type Baz = MyBaz;
+}
+
+pub fn foo<T, U>(_value: T) -> i32
+where
+ T: Bar<Baz = U>,
+ U: Foo,
+{
+ 15
+}
+
+fn main() -> i32 {
+ let bar = MyBar;
+ let result: i32 = foo::<MyBar, MyBaz>(bar);
+
+ result - 15
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit1.rs b/gcc/testsuite/rust/execute/torture/impl_rpit1.rs
new file mode 100644
index 0000000..9de4dff
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit1.rs
@@ -0,0 +1,30 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing(a: i32) -> impl Foo {
+ Thing(a)
+}
+
+fn use_foo(f: impl Foo) -> i32 {
+ f.id()
+}
+
+fn main() -> i32 {
+ let value = make_thing(42);
+ let val = use_foo(value);
+ val - 42
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit2.rs b/gcc/testsuite/rust/execute/torture/impl_rpit2.rs
new file mode 100644
index 0000000..0f2e7e0
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit2.rs
@@ -0,0 +1,38 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Thing {
+ fn double(&self) -> i32 {
+ // { dg-warning "associated function is never used: .double." "" { target *-*-* } .-1 }
+ self.0 * 2
+ }
+}
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing(a: i32) -> impl Foo {
+ Thing(a)
+}
+
+fn use_foo(f: impl Foo) -> i32 {
+ f.id()
+}
+
+fn main() -> i32 {
+ let value = make_thing(21);
+ let id = use_foo(value);
+
+ id - 21
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit3.rs b/gcc/testsuite/rust/execute/torture/impl_rpit3.rs
new file mode 100644
index 0000000..ec55f6a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit3.rs
@@ -0,0 +1,27 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing() -> impl Foo {
+ Thing(99)
+}
+
+fn main() -> i32 {
+ let v = make_thing();
+ let r = &v;
+ let val = r.id();
+ val - 99
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait1.rs b/gcc/testsuite/rust/execute/torture/impl_trait1.rs
new file mode 100644
index 0000000..e578ed8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait1.rs
@@ -0,0 +1,33 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Value {
+ fn get(&self) -> i32;
+}
+
+struct Foo(i32);
+struct Bar(i32);
+
+impl Value for Foo {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+impl Value for Bar {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+
+pub fn foo(a: impl Value, b: impl Value) -> i32 {
+ a.get() + b.get()
+}
+
+fn main() -> i32 {
+ let a = Foo(1);
+ let b = Bar(2);
+
+ foo(a, b) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait2.rs b/gcc/testsuite/rust/execute/torture/impl_trait2.rs
new file mode 100644
index 0000000..d13765e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait2.rs
@@ -0,0 +1,33 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Value {
+ fn get(&self) -> i32;
+}
+
+struct Foo(i32);
+struct Bar(i32);
+
+impl Value for Foo {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+impl Value for Bar {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+
+pub fn foo(a: &impl Value, b: &impl Value) -> i32 {
+ a.get() + b.get()
+}
+
+fn main() -> i32 {
+ let a = Foo(1);
+ let b = Bar(2);
+
+ foo(&a, &b) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait3.rs b/gcc/testsuite/rust/execute/torture/impl_trait3.rs
new file mode 100644
index 0000000..588b11d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait3.rs
@@ -0,0 +1,46 @@
+/* { dg-output "Hello from Message\r*\n" } */
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+trait Speak {
+ fn speak(&self) -> &'static str;
+}
+
+trait Printer {
+ fn print(&self, input: impl Speak);
+}
+
+struct Console;
+
+impl Printer for Console {
+ fn print(&self, input: impl Speak) {
+ unsafe {
+ let a = input.speak();
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+ }
+}
+
+struct Message(&'static str);
+
+impl Speak for Message {
+ fn speak(&self) -> &'static str {
+ self.0
+ }
+}
+
+fn main() -> i32 {
+ let c = Console;
+ let msg = Message("Hello from Message\n");
+ c.print(msg);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait4.rs b/gcc/testsuite/rust/execute/torture/impl_trait4.rs
new file mode 100644
index 0000000..e054949
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait4.rs
@@ -0,0 +1,33 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct A(i32);
+struct B(i32);
+
+impl Foo for A {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+impl Foo for B {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn takes_tuple(pair: (impl Foo, impl Foo)) -> i32 {
+ pair.0.id() + pair.1.id()
+}
+
+fn main() -> i32 {
+ let a = A(1);
+ let b = B(2);
+ takes_tuple((a, b)) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/index1.rs b/gcc/testsuite/rust/execute/torture/index1.rs
index 19e58e3..1071b35 100644
--- a/gcc/testsuite/rust/execute/torture/index1.rs
+++ b/gcc/testsuite/rust/execute/torture/index1.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1120.rs b/gcc/testsuite/rust/execute/torture/issue-1120.rs
index 7dfa26f..d7ef483 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1120.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1120.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1133.rs b/gcc/testsuite/rust/execute/torture/issue-1133.rs
index 29f532e..788b0ea 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1133.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1133.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1198.rs b/gcc/testsuite/rust/execute/torture/issue-1198.rs
index d5c3d89..d50faba 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1198.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1198.rs
@@ -1,4 +1,6 @@
/* { dg-output "foo_deref\r*\nimm_deref\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1232.rs b/gcc/testsuite/rust/execute/torture/issue-1232.rs
index 6fb42b3..d0db0ee 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1232.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1232.rs
@@ -2,6 +2,7 @@
// { dg-output "slice_access=3\r*\n" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1249.rs b/gcc/testsuite/rust/execute/torture/issue-1249.rs
index e7a261c..548600a 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1249.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1249.rs
@@ -1,6 +1,7 @@
// { dg-options "-w" }
// { dg-output "1\r*\n2\r*\n" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1436.rs b/gcc/testsuite/rust/execute/torture/issue-1436.rs
index 5d90907..23620ab 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1436.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1436.rs
@@ -2,6 +2,7 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1481.rs b/gcc/testsuite/rust/execute/torture/issue-1481.rs
new file mode 100644
index 0000000..e63e2bd
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1481.rs
@@ -0,0 +1,36 @@
+/* { dg-output "called Foo::print\\(\\)\r*" } */
+/* { dg-options "-w" } */
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Printable {
+ fn print(&self);
+}
+
+struct Foo;
+
+impl Printable for Foo {
+ fn print(&self) {
+ // Simulate output
+ unsafe {
+ puts("called Foo::print()\0" as *const _ as *const i8);
+ }
+ }
+}
+
+fn get_printable() -> impl Printable {
+ Foo
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let p = get_printable();
+ p.print();
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1482.rs b/gcc/testsuite/rust/execute/torture/issue-1482.rs
new file mode 100644
index 0000000..3b1b398
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1482.rs
@@ -0,0 +1,25 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn takes_fn(a: i32, f: impl FnOnce(i32) -> i32) -> i32 {
+ f(a)
+}
+
+pub fn main() -> i32 {
+ let capture = 2;
+ let a = |i: i32| {
+ let b = i + capture;
+ b
+ };
+ takes_fn(1, a) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1496.rs b/gcc/testsuite/rust/execute/torture/issue-1496.rs
index 36291a7..26dd1ef 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1496.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1496.rs
@@ -1,4 +1,6 @@
/* { dg-output "foo_deref\r*\nimm_deref\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1720-2.rs b/gcc/testsuite/rust/execute/torture/issue-1720-2.rs
index 9c5356e..d90072f 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1720-2.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1720-2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1720.rs b/gcc/testsuite/rust/execute/torture/issue-1720.rs
index 2218282..5da45ee 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1720.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1720.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-2005.rs b/gcc/testsuite/rust/execute/torture/issue-2005.rs
new file mode 100644
index 0000000..29d4454
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-2005.rs
@@ -0,0 +1,465 @@
+// { dg-additional-options "-w" }
+/* { dg-output "WORKS\r?\n" } */
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// --------------
+
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Eq for isize {}
+
+impl Ord for isize {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// ----------------------------------
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+impl Eq for i32 {}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+enum Foo {
+ A,
+ B(i32),
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo::A;
+ let b = Foo::B(15);
+
+ if (a != b) {
+ print("WORKS");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-2052.rs b/gcc/testsuite/rust/execute/torture/issue-2052.rs
index bf5d6a7..a30ddc4 100644
--- a/gcc/testsuite/rust/execute/torture/issue-2052.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-2052.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-2179.rs b/gcc/testsuite/rust/execute/torture/issue-2179.rs
index 8a5ec1b..c5da7ee 100644
--- a/gcc/testsuite/rust/execute/torture/issue-2179.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-2179.rs
@@ -1,4 +1,5 @@
// { dg-output "123\r*\n" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-2180.rs b/gcc/testsuite/rust/execute/torture/issue-2180.rs
index 6bd7172..ee18c8b 100644
--- a/gcc/testsuite/rust/execute/torture/issue-2180.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-2180.rs
@@ -1,4 +1,5 @@
// { dg-output "123\r*\n" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-2236.rs b/gcc/testsuite/rust/execute/torture/issue-2236.rs
index 850b997..b7f2888 100644
--- a/gcc/testsuite/rust/execute/torture/issue-2236.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-2236.rs
@@ -1,4 +1,5 @@
// { dg-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-2583.rs b/gcc/testsuite/rust/execute/torture/issue-2583.rs
index 4ff12fc..c45d61d 100644
--- a/gcc/testsuite/rust/execute/torture/issue-2583.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-2583.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/issue-3126.rs b/gcc/testsuite/rust/execute/torture/issue-3126.rs
new file mode 100644
index 0000000..65bc07d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-3126.rs
@@ -0,0 +1,54 @@
+/* { dg-output "child\r*\n" }*/
+#![feature(lang_items)]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Foo {
+ my_int: u32,
+ // { dg-warning "field is never read: .my_int." "" { target *-*-* } .-1 }
+}
+
+trait Parent<T> {
+ fn parent(&self) -> T;
+}
+
+trait Child: Parent<u32> {
+ fn child(&self);
+}
+
+impl Parent<u32> for Foo {
+ fn parent(&self) -> u32 {
+ unsafe {
+ let parent = "parent %i\n\0";
+ let msg = parent as *const str;
+ printf(msg as *const i8, self.my_int);
+ return self.my_int;
+ }
+ }
+}
+
+impl Child for Foo {
+ fn child(&self) {
+ let _ = self;
+ unsafe {
+ let child = "child\n\0";
+ let msg = child as *const str;
+ printf(msg as *const i8);
+ }
+ }
+}
+
+pub fn main() -> i32 {
+ let a = Foo { my_int: 0xf00dfeed };
+ let b: &dyn Child = &a;
+
+ // b.parent();
+ b.child();
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-3381.rs b/gcc/testsuite/rust/execute/torture/issue-3381.rs
new file mode 100644
index 0000000..02d96d7
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-3381.rs
@@ -0,0 +1,92 @@
+/* { dg-output "Err: 15\r*\n" } */
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ #[lang = "Ok"]
+ Ok(T),
+ #[lang = "Err"]
+ Err(E),
+}
+
+#[lang = "try"]
+pub trait Try {
+ type Ok;
+ type Error;
+
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: Self::Ok) -> Self;
+
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: Self::Error) -> Self;
+}
+
+impl<T, E> Try for Result<T, E> {
+ type Ok = T;
+ type Error = E;
+
+ fn into_result(self) -> Result<T, E> {
+ self
+ }
+
+ fn from_ok(v: T) -> Self {
+ Result::Ok(v)
+ }
+
+ fn from_error(v: E) -> Self {
+ Result::Err(v)
+ }
+}
+
+pub trait From<T>: Sized {
+ fn from(_: T) -> Self;
+}
+
+impl<T> From<T> for T {
+ fn from(t: T) -> Self {
+ t
+ }
+}
+
+fn print(s: &str, value: i32) {
+ extern "C" {
+ fn printf(s: *const i8, ...);
+ }
+
+ unsafe {
+ printf(s as *const str as *const i8, value);
+ }
+}
+
+fn baz() -> Result<i32, i32> {
+ Result::Err(15)
+}
+
+fn foo() -> Result<i32, i32> {
+ let b = match baz() {
+ Result::Ok(value) => value,
+ Result::Err(err) => {
+ return Try::from_error(From::from(err));
+ }
+ };
+
+ Result::Ok(15 + b)
+}
+
+fn main() -> i32 {
+ let a = foo();
+ match a {
+ Result::Ok(value) => print("Ok: %i\n", value),
+ Result::Err(err) => print("Err: %i\n", err),
+ };
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-3502.rs b/gcc/testsuite/rust/execute/torture/issue-3502.rs
new file mode 100644
index 0000000..aa38858
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-3502.rs
@@ -0,0 +1,54 @@
+/* { dg-output "parent 123\r*\nchild\r*\n" } */
+#![feature(lang_items)]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Foo {
+ my_int: u32,
+ // { dg-warning "field is never read: .my_int." "" { target *-*-* } .-1 }
+}
+
+trait Parent<T> {
+ fn parent(&self) -> T;
+}
+
+trait Child: Parent<u32> {
+ fn child(&self);
+}
+
+impl Parent<u32> for Foo {
+ fn parent(&self) -> u32 {
+ unsafe {
+ let parent = "parent %u\n\0";
+ let msg = parent as *const str;
+ printf(msg as *const i8, self.my_int);
+ return self.my_int;
+ }
+ }
+}
+
+impl Child for Foo {
+ fn child(&self) {
+ let _ = self;
+ unsafe {
+ let child = "child\n\0";
+ let msg = child as *const str;
+ printf(msg as *const i8);
+ }
+ }
+}
+
+pub fn main() -> i32 {
+ let a = Foo { my_int: 123 };
+ let b: &dyn Child = &a;
+
+ b.parent();
+ b.child();
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-3836.rs b/gcc/testsuite/rust/execute/torture/issue-3836.rs
new file mode 100644
index 0000000..5c93736
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-3836.rs
@@ -0,0 +1,454 @@
+// { dg-options "-w" }
+// { dg-output "less\r*\n" }
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// ------------
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct Bar {
+ a: i32,
+ b: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let x = Bar { a: 1, b: 2 };
+ let y = Bar { a: 1, b: 3 };
+
+ match x.partial_cmp(&y) {
+ Option::Some(Ordering::Less) => print("less"),
+ Option::Some(Ordering::Greater) => print("greater"),
+ Option::Some(Ordering::Equal) => print("equal"),
+ _ => print("none"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-4242.rs b/gcc/testsuite/rust/execute/torture/issue-4242.rs
new file mode 100644
index 0000000..867adc9
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-4242.rs
@@ -0,0 +1,11 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() -> i32 {
+ let x = -77;
+
+ match x {
+ -55..99 => 1,
+ -99..-55 => 0, // the correct case
+ _ => 1,
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/execute/torture/issue-647.rs b/gcc/testsuite/rust/execute/torture/issue-647.rs
index 6a35655..fbf4a1e 100644
--- a/gcc/testsuite/rust/execute/torture/issue-647.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-647.rs
@@ -1,4 +1,6 @@
/* { dg-output "Hello World 123\r*\n" }*/
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-845.rs b/gcc/testsuite/rust/execute/torture/issue-845.rs
index b11ccd5..060cf0b 100644
--- a/gcc/testsuite/rust/execute/torture/issue-845.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-845.rs
@@ -1,5 +1,7 @@
// { dg-output "Foo::bar\r*\n" }
// { dg-additional-options "-w" }
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-851.rs b/gcc/testsuite/rust/execute/torture/issue-851.rs
index 1361235..093143f 100644
--- a/gcc/testsuite/rust/execute/torture/issue-851.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-851.rs
@@ -1,4 +1,6 @@
/* { dg-output "Result: 123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-858.rs b/gcc/testsuite/rust/execute/torture/issue-858.rs
index 0b1118b..63518ce 100644
--- a/gcc/testsuite/rust/execute/torture/issue-858.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-858.rs
@@ -1,4 +1,6 @@
/* { dg-output "Result: 123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/iter1.rs b/gcc/testsuite/rust/execute/torture/iter1.rs
index c3b6c7b..84b5033 100644
--- a/gcc/testsuite/rust/execute/torture/iter1.rs
+++ b/gcc/testsuite/rust/execute/torture/iter1.rs
@@ -1,5 +1,5 @@
// { dg-output "1\r*\n2\r*\n" }
-#![feature(intrinsics)]
+#![feature(intrinsics, lang_items)]
pub use option::Option::{self, None, Some};
pub use result::Result::{self, Err, Ok};
@@ -99,30 +99,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -130,12 +130,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -143,7 +143,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -152,31 +152,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -191,7 +191,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -201,7 +201,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
diff --git a/gcc/testsuite/rust/execute/torture/let-identifierpattern-subpattern.rs b/gcc/testsuite/rust/execute/torture/let-identifierpattern-subpattern.rs
new file mode 100644
index 0000000..fa1f56e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/let-identifierpattern-subpattern.rs
@@ -0,0 +1,11 @@
+fn main() -> i32 {
+ let foo @ (bar, _, _) = (0, 2, 3);
+ let mut ret = 1;
+
+ match foo {
+ (0, 2, 3) => { ret = bar },
+ _ => {}
+ }
+
+ ret
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/execute/torture/link-name.rs b/gcc/testsuite/rust/execute/torture/link-name.rs
new file mode 100644
index 0000000..1ab1ac1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/link-name.rs
@@ -0,0 +1,16 @@
+// { dg-additional-options "-fdump-rtl-final" }
+// { dg-final { scan-rtl-dump "printf" "final" } }
+// { dg-output "gcc\r*\n" }
+
+extern "C" {
+ #[link_name = "printf"]
+ fn druckt(fmt: *const i8, ...);
+}
+
+fn main() -> i32 {
+ let a = "gcc\0";
+
+ unsafe { druckt("%s\n\0" as *const str as *const i8, a as *const str as *const i8); }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs b/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs
new file mode 100644
index 0000000..3553c4a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs
@@ -0,0 +1,9 @@
+fn main() -> i32 {
+ let x = -55;
+
+ match x {
+ 55 => 1,
+ -55 => 0, // correct case
+ _ => 1
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/execute/torture/macros23.rs b/gcc/testsuite/rust/execute/torture/macros23.rs
index b27985d..ef958af 100644
--- a/gcc/testsuite/rust/execute/torture/macros23.rs
+++ b/gcc/testsuite/rust/execute/torture/macros23.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/macros28.rs b/gcc/testsuite/rust/execute/torture/macros28.rs
index 46d9cfc..db1d9f2 100644
--- a/gcc/testsuite/rust/execute/torture/macros28.rs
+++ b/gcc/testsuite/rust/execute/torture/macros28.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs b/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs
new file mode 100644
index 0000000..b102ad1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs
@@ -0,0 +1,10 @@
+fn main() -> i32 {
+ let mut x = 2;
+
+ match x {
+ a @ 2 => { x = a + 1 },
+ _ => {}
+ }
+
+ x - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs b/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs
new file mode 100644
index 0000000..2c1418c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs
@@ -0,0 +1,27 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let x = (1, 2, 3, 4);
+ let mut ret = 1;
+
+ match x {
+ (1, .., 2, 4) => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ (2, ..) => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ (b, .., 4) => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/execute/torture/match-slicepattern-array-1.rs b/gcc/testsuite/rust/execute/torture/match-slicepattern-array-1.rs
new file mode 100644
index 0000000..95c55d8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-slicepattern-array-1.rs
@@ -0,0 +1,23 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let a = [0, 1];
+ let mut ret = 1;
+
+ match a {
+ [0, 0] => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ [0, b] => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-slicepattern-array-2.rs b/gcc/testsuite/rust/execute/torture/match-slicepattern-array-2.rs
new file mode 100644
index 0000000..c6e7762
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-slicepattern-array-2.rs
@@ -0,0 +1,27 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let a = [0, 4, 5, 6, 1];
+ let mut ret = 1;
+
+ match a {
+ [1, .., b] => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ }
+ [0, .., 0] => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ [0, .., b] => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-1.rs b/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-1.rs
new file mode 100644
index 0000000..3ed0b644
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-1.rs
@@ -0,0 +1,24 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let arr = [0, 1];
+ let a: &[i32] = &arr;
+ let mut ret = 1;
+
+ match a {
+ [0, 0] => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ [0, b] => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-2.rs b/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-2.rs
new file mode 100644
index 0000000..2fdffbb
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-2.rs
@@ -0,0 +1,28 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let arr = [0, 4, 5, 6, 1];
+ let a: &[i32] = &arr;
+ let mut ret = 1;
+
+ match a {
+ [1, .., b] => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ }
+ [0, .., 0] => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ [0, .., b] => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-tuplestructpattern-rest-1.rs b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern-rest-1.rs
new file mode 100644
index 0000000..8d7446d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern-rest-1.rs
@@ -0,0 +1,24 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ struct A (i32, i32, i32);
+ let a = A (0, 1, 2);
+ let mut ret = 1;
+
+ match a {
+ A (1, ..) => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ }
+ A (0, b, ..) => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-tuplestructpattern-rest-2.rs b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern-rest-2.rs
new file mode 100644
index 0000000..f433be9
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern-rest-2.rs
@@ -0,0 +1,28 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ struct A (i32, i32, i32);
+ let a = A (0, 3, 1);
+ let mut ret = 1;
+
+ match a {
+ A (1, ..) => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ }
+ A (.., 3) => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ }
+ A (.., b) => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs
new file mode 100644
index 0000000..323109c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs
@@ -0,0 +1,12 @@
+fn main() -> i32 {
+ struct A (i32, i32);
+ let a = A (0, 1);
+ let mut ret = 1;
+
+ match a {
+ A (0, b) => { ret -= b },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/method2.rs b/gcc/testsuite/rust/execute/torture/method2.rs
index e5f630a..0355a750 100644
--- a/gcc/testsuite/rust/execute/torture/method2.rs
+++ b/gcc/testsuite/rust/execute/torture/method2.rs
@@ -1,5 +1,7 @@
// { dg-additional-options "-w" }
// { dg-output "foo_deref\r*\nimm_deref\r*\n" }
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/method3.rs b/gcc/testsuite/rust/execute/torture/method3.rs
index 9a7865c..70b7792 100644
--- a/gcc/testsuite/rust/execute/torture/method3.rs
+++ b/gcc/testsuite/rust/execute/torture/method3.rs
@@ -1,5 +1,7 @@
// { dg-additional-options "-w" }
// { dg-output "mut_deref\r*\nfoobar: 123\r*\n" }
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/method4.rs b/gcc/testsuite/rust/execute/torture/method4.rs
index e20618f..f4b3a33 100644
--- a/gcc/testsuite/rust/execute/torture/method4.rs
+++ b/gcc/testsuite/rust/execute/torture/method4.rs
@@ -1,5 +1,7 @@
// { dg-additional-options "-w" }
// { dg-output "mut_deref\r*\nfoobar: 123\r*\n" }
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/min_specialization2.rs b/gcc/testsuite/rust/execute/torture/min_specialization2.rs
new file mode 100644
index 0000000..b3eac27
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/min_specialization2.rs
@@ -0,0 +1,31 @@
+#![feature(min_specialization, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn foo(&self) -> i32;
+}
+
+impl<T> Foo for T {
+ default fn foo(&self) -> i32 {
+ 15
+ }
+}
+
+impl Foo for bool {
+ fn foo(&self) -> i32 {
+ if *self {
+ 1
+ } else {
+ 0
+ }
+ }
+}
+
+fn main() -> i32 {
+ let a = 1.foo() - 15;
+ let b = true.foo() - 1;
+
+ a + b
+}
diff --git a/gcc/testsuite/rust/execute/torture/min_specialization3.rs b/gcc/testsuite/rust/execute/torture/min_specialization3.rs
new file mode 100644
index 0000000..b73a8ac
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/min_specialization3.rs
@@ -0,0 +1,36 @@
+#![feature(min_specialization, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn foo(&self) -> i32;
+}
+
+struct Wrap<T>(T);
+
+impl<T> Foo for T {
+ default fn foo(&self) -> i32 {
+ 15
+ }
+}
+
+impl<T> Foo for Wrap<T> {
+ default fn foo(&self) -> i32 {
+ 16
+ }
+}
+
+impl Foo for Wrap<bool> {
+ fn foo(&self) -> i32 {
+ if self.0 {
+ 1
+ } else {
+ 0
+ }
+ }
+}
+
+fn main() -> i32 {
+ Wrap(true).foo() - 1
+}
diff --git a/gcc/testsuite/rust/execute/torture/multiline-string.rs b/gcc/testsuite/rust/execute/torture/multiline-string.rs
new file mode 100644
index 0000000..4d22f99
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/multiline-string.rs
@@ -0,0 +1,15 @@
+// { dg-output "gcc\n\nrs\n" }
+
+extern "C" {
+ fn printf(fmt: *const i8, ...);
+}
+
+fn main() -> i32 {
+ let a = "gcc
+
+rs\0";
+
+ unsafe { printf("%s\n\0" as *const str as *const i8, a as *const str as *const i8); }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/name_resolution.rs b/gcc/testsuite/rust/execute/torture/name_resolution.rs
index 7492183..a2eaf48 100644
--- a/gcc/testsuite/rust/execute/torture/name_resolution.rs
+++ b/gcc/testsuite/rust/execute/torture/name_resolution.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
// { dg-output "Value is 10\r*\n" }
const BAZ: i32 = 10;
diff --git a/gcc/testsuite/rust/execute/torture/offset_of1.rs b/gcc/testsuite/rust/execute/torture/offset_of1.rs
new file mode 100644
index 0000000..7d39483
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/offset_of1.rs
@@ -0,0 +1,16 @@
+// { dg-do run { target x86_64*-*-* } }
+// { dg-additional-options "-frust-assume-builtin-offset-of" }
+
+pub struct Foo {
+ pub a: i32,
+ pub b: i32,
+}
+
+fn main() -> i32 {
+ let a = offset_of!(Foo, a); // valid
+ let b = offset_of!(Foo, b); // valid
+
+ let res = a + b - 4;
+
+ res as i32
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_1.rs b/gcc/testsuite/rust/execute/torture/operator_overload_1.rs
index 9aed393..0fc6372 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_1.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_1.rs
@@ -1,4 +1,6 @@
/* { dg-output "3\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_10.rs b/gcc/testsuite/rust/execute/torture/operator_overload_10.rs
index 921ec5f..6989347 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_10.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_10.rs
@@ -1,4 +1,6 @@
/* { dg-output "foo_deref\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_11.rs b/gcc/testsuite/rust/execute/torture/operator_overload_11.rs
index f0359fb..d0b45a7 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_11.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_11.rs
@@ -1,5 +1,7 @@
// { dg-output "1\r*\n" }
// { dg-additional-options "-w" }
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_12.rs b/gcc/testsuite/rust/execute/torture/operator_overload_12.rs
index 2cd5c69..a0e1bc8 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_12.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_12.rs
@@ -1,5 +1,7 @@
// { dg-output "1\r*\n" }
// { dg-additional-options "-w" }
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_2.rs b/gcc/testsuite/rust/execute/torture/operator_overload_2.rs
index 6862415..dfc2530 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_2.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_2.rs
@@ -1,4 +1,6 @@
/* { dg-output "3\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_3.rs b/gcc/testsuite/rust/execute/torture/operator_overload_3.rs
index 6c1a8b8..6807143 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_3.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_3.rs
@@ -1,4 +1,6 @@
/* { dg-output "3\r*\n3\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_4.rs b/gcc/testsuite/rust/execute/torture/operator_overload_4.rs
index c8235c6..3f68bf1 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_4.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_4.rs
@@ -1,4 +1,6 @@
/* { dg-output "neg\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_5.rs b/gcc/testsuite/rust/execute/torture/operator_overload_5.rs
index eeef5bc..b5c1fd6 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_5.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_5.rs
@@ -1,4 +1,6 @@
/* { dg-output "not\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_6.rs b/gcc/testsuite/rust/execute/torture/operator_overload_6.rs
index d5ffae5..0a69758 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_6.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_6.rs
@@ -1,4 +1,6 @@
/* { dg-output "add_assign\r*\n3\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_7.rs b/gcc/testsuite/rust/execute/torture/operator_overload_7.rs
index 7226b26..e1bd7c4 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_7.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_7.rs
@@ -1,4 +1,6 @@
/* { dg-output "imm_deref\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_8.rs b/gcc/testsuite/rust/execute/torture/operator_overload_8.rs
index 4b589a8..8324768 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_8.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_8.rs
@@ -1,4 +1,6 @@
/* { dg-output "imm_deref\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs
index 5fc0428..4d10f78 100644
--- a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs
@@ -1,4 +1,6 @@
/* { dg-output "mut_deref\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/partial-eq-1.rs b/gcc/testsuite/rust/execute/torture/partial-eq-1.rs
new file mode 100644
index 0000000..fa918f3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-eq-1.rs
@@ -0,0 +1,104 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+#![feature(lang_items)]
+
+mod core {
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[lang = "sized"]
+ pub trait Sized {}
+ }
+
+ pub mod cmp {
+ use super::marker::Sized;
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ pub trait Eq: PartialEq<Self> {
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+ }
+}
+
+use core::cmp::{Eq, PartialEq};
+
+// PartialEq for i32 and u32 so we can compare across types
+impl PartialEq<u32> for i32 {
+ fn eq(&self, other: &u32) -> bool {
+ *self >= 0 && (*self as u32) == *other
+ }
+}
+impl PartialEq<i32> for u32 {
+ fn eq(&self, other: &i32) -> bool {
+ *other >= 0 && *self == *other as u32
+ }
+}
+
+// Our generic struct
+struct Foo<T> {
+ value: T,
+}
+
+// Manual impl of PartialEq for different generic params
+impl<T, U> PartialEq<Foo<U>> for Foo<T>
+where
+ T: PartialEq<U>,
+{
+ fn eq(&self, other: &Foo<U>) -> bool {
+ self.value.eq(&other.value)
+ }
+}
+
+impl<T: PartialEq> Eq for Foo<T> {}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { value: 42i32 };
+ let b = Foo { value: 42u32 };
+ let c = Foo { value: 7u32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-eq-2.rs b/gcc/testsuite/rust/execute/torture/partial-eq-2.rs
new file mode 100644
index 0000000..e132ef0
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-eq-2.rs
@@ -0,0 +1,61 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+struct Foo<T> {
+ value: T,
+}
+
+impl<T: PartialEq> PartialEq for Foo<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.value.eq(&other.value)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { value: 42i32 };
+ let b = Foo { value: 42i32 };
+ let c = Foo { value: 99i32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-eq-3.rs b/gcc/testsuite/rust/execute/torture/partial-eq-3.rs
new file mode 100644
index 0000000..4ace3d9
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-eq-3.rs
@@ -0,0 +1,457 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+#[derive(PartialEq)]
+struct Foo {
+ a: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { a: 42i32 };
+ let b = Foo { a: 42i32 };
+ let c = Foo { a: 7i32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-eq-4.rs b/gcc/testsuite/rust/execute/torture/partial-eq-4.rs
new file mode 100644
index 0000000..d1835db
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-eq-4.rs
@@ -0,0 +1,457 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+#[derive(PartialEq, Eq)]
+struct Foo {
+ a: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { a: 42i32 };
+ let b = Foo { a: 42i32 };
+ let c = Foo { a: 7i32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-1.rs b/gcc/testsuite/rust/execute/torture/partial-ord-1.rs
new file mode 100644
index 0000000..b1546a3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-1.rs
@@ -0,0 +1,102 @@
+/* { dg-output "x == y\r*\nx > z\r*\n" }*/
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+}
+
+use Option::{None, Some};
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+pub enum Ordering {
+ Less = -1,
+ Equal = 0,
+ Greater = 1,
+}
+
+#[lang = "partial_ord"]
+pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+}
+
+// Implement for i32
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// Implement PartialOrd for i32
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self < *other {
+ Some(Ordering::Less)
+ } else if *self > *other {
+ Some(Ordering::Greater)
+ } else {
+ Some(Ordering::Equal)
+ }
+ }
+}
+
+// Struct with manual PartialEq
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &Self) -> bool {
+ self.a.eq(&other.a)
+ }
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.a.partial_cmp(&other.a)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let x = Foo { a: 42 };
+ let y = Foo { a: 42 };
+ let z = Foo { a: 7 };
+
+ match x.partial_cmp(&y) {
+ Some(Ordering::Equal) => print("x == y"),
+ Some(Ordering::Less) => print("x < y"),
+ Some(Ordering::Greater) => print("x > y"),
+ None => print("x ? y"),
+ }
+
+ match x.partial_cmp(&z) {
+ Some(Ordering::Equal) => print("x == z"),
+ Some(Ordering::Less) => print("x < z"),
+ Some(Ordering::Greater) => print("x > z"),
+ None => print("x ? z"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-2.rs b/gcc/testsuite/rust/execute/torture/partial-ord-2.rs
new file mode 100644
index 0000000..76cdc2a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-2.rs
@@ -0,0 +1,469 @@
+/* { dg-output "x == y\r*\nx > z\r*\n" }*/
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &'_ Self) -> bool {
+ self.a == other.a
+ }
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &'_ Foo) -> Option<::core::cmp::Ordering> {
+ self.a.partial_cmp(&other.a)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let x = Foo { a: 42 };
+ let y = Foo { a: 42 };
+ let z = Foo { a: 7 };
+
+ match x.partial_cmp(&y) {
+ Option::Some(Ordering::Equal) => print("x == y"),
+ Option::Some(Ordering::Less) => print("x < y"),
+ Option::Some(Ordering::Greater) => print("x > y"),
+ Option::None => print("x ? y"),
+ }
+
+ match x.partial_cmp(&z) {
+ Option::Some(Ordering::Equal) => print("x == z"),
+ Option::Some(Ordering::Less) => print("x < z"),
+ Option::Some(Ordering::Greater) => print("x > z"),
+ Option::None => print("x ? z"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-3.rs b/gcc/testsuite/rust/execute/torture/partial-ord-3.rs
new file mode 100644
index 0000000..dd8072f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-3.rs
@@ -0,0 +1,489 @@
+/* { dg-output "x == y\r*\nx > z\r*\nx < z\r*\nx >= y\r*\nx <= y\r*\n" } */
+/* { dg-options "-w" } */
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &Self) -> bool {
+ self.a == other.a
+ }
+}
+impl Eq for Foo {}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.a.partial_cmp(&other.a)
+ }
+}
+
+impl Ord for Foo {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.a.cmp(&other.a)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let x = Foo { a: 42 };
+ let y = Foo { a: 42 };
+ let z = Foo { a: 7 };
+
+ // test direct equality
+ if x == y {
+ print("x == y");
+ }
+
+ // test PartialOrd via match
+ match x.partial_cmp(&z) {
+ Option::Some(Ordering::Greater) => print("x > z"),
+ _ => print("x ? z"),
+ }
+
+ // test `<` directly
+ if z < x {
+ print("x < z");
+ }
+
+ // test `>=`
+ if x >= y {
+ print("x >= y");
+ }
+
+ // test `<=`
+ if x <= y {
+ print("x <= y");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-4.rs b/gcc/testsuite/rust/execute/torture/partial-ord-4.rs
new file mode 100644
index 0000000..de13074
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-4.rs
@@ -0,0 +1,115 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+ }
+ }
+
+ mod marker {
+ #[lang = "sized"]
+ pub trait Sized {}
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ pub enum Ordering {
+ Less = -1,
+ Equal = 0,
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[lang = "partial_ord"]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ }
+ }
+}
+
+use core::cmp::{Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+}
+
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &'_ Self) -> bool {
+ self.a == other.a
+ }
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &'_ Foo) -> Option<::core::cmp::Ordering> {
+ ::core::cmp::PartialOrd::partial_cmp(&self.a, &other.a)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { a: 42i32 };
+ let b = Foo { a: 42i32 };
+ let c = Foo { a: 7i32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-5.rs b/gcc/testsuite/rust/execute/torture/partial-ord-5.rs
new file mode 100644
index 0000000..b87a08e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-5.rs
@@ -0,0 +1,487 @@
+/* { dg-output "a == b\r*\na != c\r*\na >= c\r*\na <= b\r*\na > c\r*\nc < b\r*\n" } */
+/* { dg-options "-w" } */
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+#[derive(PartialEq, Eq, Ord)]
+struct Foo {
+ a: i32,
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &'_ Foo) -> Option<::core::cmp::Ordering> {
+ self.a.partial_cmp(&other.a)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { a: 42 };
+ let b = Foo { a: 42 };
+ let c = Foo { a: 7 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a != c {
+ print("a != c");
+ } else {
+ print("a == c");
+ }
+
+ if a < c {
+ print("a < c");
+ } else {
+ print("a >= c");
+ }
+
+ if a <= b {
+ print("a <= b");
+ } else {
+ print("a > b");
+ }
+
+ if a > c {
+ print("a > c");
+ } else {
+ print("a <= c");
+ }
+
+ if c >= b {
+ print("c >= b");
+ } else {
+ print("c < b");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-6.rs b/gcc/testsuite/rust/execute/torture/partial-ord-6.rs
new file mode 100644
index 0000000..04f13cd
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-6.rs
@@ -0,0 +1,518 @@
+// { dg-additional-options "-w" }
+/* { dg-output "Foo A < B\r?\nFoo B < C\r?\nFoo C == C\r?\nBar x < y\r?\nBarFull s1 < s2\r?\n" } */
+
+#![feature(intrinsics, lang_items)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+impl Eq for i32 {}
+
+#[derive(PartialEq, PartialOrd)]
+enum Foo {
+ A,
+ B(i32, i32, i32),
+ C { inner: i32, outer: i32 },
+}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct Bar {
+ a: i32,
+}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct BarFull {
+ a: i32,
+ b: i32,
+ c: i32,
+ d: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ // Enum comparison
+ let a = Foo::A;
+ let b = Foo::B(15, 14, 13);
+ let c = Foo::C {
+ inner: 10,
+ outer: 20,
+ };
+
+ match a.partial_cmp(&b) {
+ Option::Some(Ordering::Less) => print("Foo A < B"),
+ Option::Some(Ordering::Greater) => print("Foo A > B"),
+ Option::Some(Ordering::Equal) => print("Foo A == B"),
+ _ => print("Foo A ? B"),
+ }
+
+ match b.partial_cmp(&c) {
+ Option::Some(Ordering::Less) => print("Foo B < C"),
+ Option::Some(Ordering::Greater) => print("Foo B > C"),
+ Option::Some(Ordering::Equal) => print("Foo B == C"),
+ _ => print("Foo B ? C"),
+ }
+
+ match c.partial_cmp(&c) {
+ Option::Some(Ordering::Less) => print("Foo C < C ???"),
+ Option::Some(Ordering::Greater) => print("Foo C > C ???"),
+ Option::Some(Ordering::Equal) => print("Foo C == C"),
+ _ => print("Foo C ? C"),
+ }
+
+ // Struct comparison: Bar
+ let x = Bar { a: 10 };
+ let y = Bar { a: 20 };
+
+ if x < y {
+ print("Bar x < y");
+ } else if x > y {
+ print("Bar x > y");
+ } else {
+ print("Bar x == y");
+ }
+
+ // Struct comparison: BarFull
+ let s1 = BarFull {
+ a: 1,
+ b: 2,
+ c: 3,
+ d: 4,
+ };
+ let s2 = BarFull {
+ a: 1,
+ b: 2,
+ c: 3,
+ d: 5,
+ };
+
+ match s1.cmp(&s2) {
+ Ordering::Less => print("BarFull s1 < s2"),
+ Ordering::Greater => print("BarFull s1 > s2"),
+ Ordering::Equal => print("BarFull s1 == s2"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/prefetch_data.rs b/gcc/testsuite/rust/execute/torture/prefetch_data.rs
index 2a847fb..a155e67 100644
--- a/gcc/testsuite/rust/execute/torture/prefetch_data.rs
+++ b/gcc/testsuite/rust/execute/torture/prefetch_data.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/ref-pattern2.rs b/gcc/testsuite/rust/execute/torture/ref-pattern2.rs
index 8e71724..cde7ea5 100644
--- a/gcc/testsuite/rust/execute/torture/ref-pattern2.rs
+++ b/gcc/testsuite/rust/execute/torture/ref-pattern2.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/sip-hasher.rs b/gcc/testsuite/rust/execute/torture/sip-hasher.rs
new file mode 100644
index 0000000..32cdc22
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/sip-hasher.rs
@@ -0,0 +1,437 @@
+// { dg-skip-if "" { *-*-* } { "-m32" } { "" } }
+// { dg-options "-w" }
+// { dg-output "Hash: 0x63d53fd2170bbb8c\r*\n" }
+#![feature(intrinsics, lang_items, rustc_attrs)]
+
+#[lang = "sized"]
+trait Sized {}
+
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ pub fn rotate_left<T>(a: T, b: T) -> T;
+ pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+ }
+}
+
+#[lang = "add"]
+trait Add<Rhs = Self> {
+ type Output;
+
+ fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ impl Add for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn add(self, other: $t) -> $t { self + other }
+ }
+
+
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+impl<T> *const T {
+ pub unsafe fn add(self, count: usize) -> Self {
+ // SAFETY: the caller must uphold the safety contract for `offset`.
+ unsafe { self.offset(count as isize) }
+ }
+
+ pub unsafe fn offset(self, count: isize) -> *const T {
+ // SAFETY: the caller must uphold the safety contract for `offset`.
+ unsafe { intrinsics::offset(self, count) }
+ }
+}
+
+macro_rules! impl_uint {
+ ($($ty:ident = $lang:literal),*) => {
+ $(
+ #[lang = $lang]
+ impl $ty {
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ intrinsics::wrapping_add(self, rhs)
+ }
+
+ pub fn rotate_left(self, n: u32) -> Self {
+ intrinsics::rotate_left(self, n as Self)
+ }
+
+ pub fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ #[cfg(not(target_endian = "little"))]
+ {
+ self.swap_bytes()
+ }
+ }
+ }
+ )*
+ }
+}
+
+impl_uint!(
+ u8 = "u8",
+ u16 = "u16",
+ u32 = "u32",
+ u64 = "u64",
+ u128 = "u128",
+ usize = "usize"
+);
+
+#[repr(C)]
+pub(crate) struct SliceComponents {
+ pub(crate) data_address: *const (),
+ pub(crate) metadata: usize,
+}
+
+#[repr(C)]
+pub(crate) union SliceRepr<T> {
+ pub(crate) const_ptr: *const [T],
+ pub(crate) mut_ptr: *mut [T],
+ pub(crate) components: SliceComponents,
+}
+
+impl<T> [T] {
+ pub const fn as_ptr(&self) -> *const T {
+ self as *const [T] as *const T
+ }
+
+ pub unsafe fn get_unchecked(&self, index: usize) -> &T {
+ unsafe { &*self.as_ptr().add(index) }
+ }
+
+ pub fn len(&self) -> usize {
+ unsafe {
+ SliceRepr {
+ const_ptr: self as *const _,
+ }
+ .components
+ .metadata
+ }
+ }
+}
+
+trait HasherTrait {
+ fn write(&mut self, msg: &[u8]);
+ fn finish(&self) -> u64;
+}
+
+mod cmp {
+ pub fn min(a: usize, b: usize) -> usize {
+ if a < b {
+ a
+ } else {
+ b
+ }
+ }
+}
+
+struct PhantomData<T>;
+
+mod mem {
+ extern "rust-intrinsic" {
+ fn transmute<T, U>(_: T) -> U;
+ fn size_of<T>() -> usize;
+ }
+}
+
+mod ptr {
+ extern "rust-intrinsic" {
+ fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+ }
+}
+
+#[repr(C)]
+struct State {
+ v0: u64,
+ v2: u64,
+ v1: u64,
+ v3: u64,
+}
+
+struct Hasher<S: Sip> {
+ k0: u64,
+ k1: u64,
+ length: usize, // how many bytes we've processed
+ state: State, // hash State
+ tail: u64, // unprocessed bytes le
+ ntail: usize, // how many bytes in tail are valid
+ _marker: PhantomData<S>,
+}
+
+macro_rules! compress {
+ ($state:expr) => {{
+ compress!($state.v0, $state.v1, $state.v2, $state.v3)
+ }};
+ ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{
+ $v0 = $v0.wrapping_add($v1);
+ $v1 = $v1.rotate_left(13);
+ $v1 ^= $v0;
+ $v0 = $v0.rotate_left(32);
+ $v2 = $v2.wrapping_add($v3);
+ $v3 = $v3.rotate_left(16);
+ $v3 ^= $v2;
+ $v0 = $v0.wrapping_add($v3);
+ $v3 = $v3.rotate_left(21);
+ $v3 ^= $v0;
+ $v2 = $v2.wrapping_add($v1);
+ $v1 = $v1.rotate_left(17);
+ $v1 ^= $v2;
+ $v2 = $v2.rotate_left(32);
+ }};
+}
+
+#[doc(hidden)]
+trait Sip {
+ fn c_rounds(_: &mut State);
+ fn d_rounds(_: &mut State);
+}
+
+struct Sip13Rounds;
+
+impl Sip for Sip13Rounds {
+ #[inline]
+ fn c_rounds(state: &mut State) {
+ compress!(state);
+ }
+
+ #[inline]
+ fn d_rounds(state: &mut State) {
+ compress!(state);
+ compress!(state);
+ compress!(state);
+ }
+}
+
+struct Sip24Rounds;
+
+impl Sip for Sip24Rounds {
+ #[inline]
+ fn c_rounds(state: &mut State) {
+ compress!(state);
+ compress!(state);
+ }
+
+ #[inline]
+ fn d_rounds(state: &mut State) {
+ compress!(state);
+ compress!(state);
+ compress!(state);
+ compress!(state);
+ }
+}
+
+pub struct SipHasher13 {
+ hasher: Hasher<Sip13Rounds>,
+}
+
+struct SipHasher24 {
+ hasher: Hasher<Sip24Rounds>,
+}
+
+pub struct SipHasher(SipHasher24);
+
+macro_rules! load_int_le {
+ ($buf:expr, $i:expr, $int_ty:ident) => {{
+ let mut data = 0 as $int_ty;
+ ptr::copy_nonoverlapping(
+ $buf.as_ptr().add($i),
+ &mut data as *mut _ as *mut u8,
+ mem::size_of::<$int_ty>(),
+ );
+ data.to_le()
+ }};
+}
+
+#[inline]
+unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
+ let mut i = 0; // current byte index (from LSB) in the output u64
+ let mut out = 0;
+ if i + 3 < len {
+ // SAFETY: `i` cannot be greater than `len`, and the caller must guarantee
+ // that the index start..start+len is in bounds.
+ out = unsafe { load_int_le!(buf, start + i, u32) } as u64;
+ i += 4;
+ }
+ if i + 1 < len {
+ // SAFETY: same as above.
+ out |= (unsafe { load_int_le!(buf, start + i, u16) } as u64) << ((i * 8) as u64);
+ i += 2
+ }
+ if i < len {
+ // SAFETY: same as above.
+ out |= (unsafe { *buf.get_unchecked(start + i) } as u64) << ((i * 8) as u64);
+ i += 1;
+ }
+ out
+}
+
+impl SipHasher {
+ #[inline]
+ #[must_use]
+ pub fn new() -> SipHasher {
+ SipHasher::new_with_keys(0, 0)
+ }
+
+ #[inline]
+ #[must_use]
+ pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
+ SipHasher(SipHasher24 {
+ hasher: Hasher::new_with_keys(key0, key1),
+ })
+ }
+}
+
+impl SipHasher13 {
+ #[inline]
+ pub fn new() -> SipHasher13 {
+ SipHasher13::new_with_keys(0, 0)
+ }
+
+ #[inline]
+ pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
+ SipHasher13 {
+ hasher: Hasher::new_with_keys(key0, key1),
+ }
+ }
+}
+
+impl<S: Sip> Hasher<S> {
+ #[inline]
+ fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
+ let mut state = Hasher {
+ k0: key0,
+ k1: key1,
+ length: 0,
+ state: State {
+ v0: 0,
+ v1: 0,
+ v2: 0,
+ v3: 0,
+ },
+ tail: 0,
+ ntail: 0,
+ _marker: PhantomData,
+ };
+ state.reset();
+ state
+ }
+
+ #[inline]
+ fn reset(&mut self) {
+ self.length = 0;
+ self.state.v0 = self.k0 ^ 0x736f6d6570736575;
+ self.state.v1 = self.k1 ^ 0x646f72616e646f6d;
+ self.state.v2 = self.k0 ^ 0x6c7967656e657261;
+ self.state.v3 = self.k1 ^ 0x7465646279746573;
+ self.ntail = 0;
+ }
+}
+
+impl HasherTrait for SipHasher {
+ #[inline]
+ fn write(&mut self, msg: &[u8]) {
+ self.0.hasher.write(msg)
+ }
+
+ #[inline]
+ fn finish(&self) -> u64 {
+ self.0.hasher.finish()
+ }
+}
+
+impl HasherTrait for SipHasher13 {
+ #[inline]
+ fn write(&mut self, msg: &[u8]) {
+ self.hasher.write(msg)
+ }
+
+ #[inline]
+ fn finish(&self) -> u64 {
+ self.hasher.finish()
+ }
+}
+
+impl<S: Sip> HasherTrait for Hasher<S> {
+ #[inline]
+ fn write(&mut self, msg: &[u8]) {
+ let length = msg.len();
+ self.length += length;
+
+ let mut needed = 0;
+
+ if self.ntail != 0 {
+ needed = 8 - self.ntail;
+ // SAFETY: `cmp::min(length, needed)` is guaranteed to not be over `length`
+ self.tail |=
+ unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << ((8 * self.ntail) as u64);
+ if length < needed {
+ self.ntail += length;
+ return;
+ } else {
+ self.state.v3 ^= self.tail;
+ S::c_rounds(&mut self.state);
+ self.state.v0 ^= self.tail;
+ self.ntail = 0;
+ }
+ }
+
+ // Buffered tail is now flushed, process new input.
+ let len = length - needed;
+ let left = len & 0x7; // len % 8
+
+ let mut i = needed;
+ while i < len - left {
+ let mi = unsafe { load_int_le!(msg, i, u64) };
+
+ self.state.v3 ^= mi;
+ S::c_rounds(&mut self.state);
+ self.state.v0 ^= mi;
+
+ i += 8;
+ }
+
+ self.tail = unsafe { u8to64_le(msg, i, left) };
+ self.ntail = left;
+ }
+
+ #[inline]
+ fn finish(&self) -> u64 {
+ let mut state = self.state;
+
+ let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;
+
+ state.v3 ^= b;
+ S::c_rounds(&mut state);
+ state.v0 ^= b;
+
+ state.v2 ^= 0xff;
+ S::d_rounds(&mut state);
+
+ state.v0 ^ state.v1 ^ state.v2 ^ state.v3
+ }
+}
+
+extern "C" {
+ fn printf(fmt: *const u8, ...) -> i32;
+}
+
+fn main() -> i32 {
+ let mut hasher = SipHasher::new_with_keys(0x0706050403020100, 0x0f0e0d0c0b0a0908);
+ hasher.write(b"Hello");
+ let result = hasher.finish();
+
+ unsafe {
+ printf("Hash: 0x%016llx\n\0" as *const str as *const u8, result);
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/slice-magic.rs b/gcc/testsuite/rust/execute/torture/slice-magic.rs
index 1f56187..521a251 100644
--- a/gcc/testsuite/rust/execute/torture/slice-magic.rs
+++ b/gcc/testsuite/rust/execute/torture/slice-magic.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/slice-magic2.rs b/gcc/testsuite/rust/execute/torture/slice-magic2.rs
index 20f113e..75c04f3 100644
--- a/gcc/testsuite/rust/execute/torture/slice-magic2.rs
+++ b/gcc/testsuite/rust/execute/torture/slice-magic2.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/slice1.rs b/gcc/testsuite/rust/execute/torture/slice1.rs
index 2683179..317ff7a 100644
--- a/gcc/testsuite/rust/execute/torture/slice1.rs
+++ b/gcc/testsuite/rust/execute/torture/slice1.rs
@@ -1,4 +1,5 @@
// { dg-additional-options "-w" }
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/str-layout1.rs b/gcc/testsuite/rust/execute/torture/str-layout1.rs
index fb3b4e3..a28d265 100644
--- a/gcc/testsuite/rust/execute/torture/str-layout1.rs
+++ b/gcc/testsuite/rust/execute/torture/str-layout1.rs
@@ -2,6 +2,7 @@
// { dg-output "t1sz=5 t2sz=10\r*" }
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs b/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs
new file mode 100644
index 0000000..6aec51f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs
@@ -0,0 +1,13 @@
+enum Foo {
+ A { x: i32 },
+ B { y: i32 }
+}
+
+fn main() -> i32 {
+ let x = Foo::A { x: 12 };
+ match x {
+ Foo::A { x: 10 } => 1,
+ Foo::B { y: 11 } => 2,
+ Foo::A { x: abc } => { abc - 12 }
+ }
+}
diff --git a/gcc/testsuite/rust/execute/torture/struct_pattern1.rs b/gcc/testsuite/rust/execute/torture/struct_pattern1.rs
new file mode 100644
index 0000000..7a74092
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/struct_pattern1.rs
@@ -0,0 +1,19 @@
+struct A {
+ // the two warnings are invalid but this should be fixed by our lint rework
+ // with this year's GSoC so ok for now
+ a: i32, // { dg-warning "never read" }
+ b: i32, // { dg-warning "never read" }
+}
+
+fn main() -> i32 {
+ let a = A { a: 15, b: 14 };
+
+ let result = match a {
+ A {
+ a: self_a,
+ b: self_b,
+ } => self_a + self_b,
+ };
+
+ result - 29
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait1.rs b/gcc/testsuite/rust/execute/torture/trait1.rs
index f8a5959..db5b6e2 100644
--- a/gcc/testsuite/rust/execute/torture/trait1.rs
+++ b/gcc/testsuite/rust/execute/torture/trait1.rs
@@ -1,4 +1,6 @@
/* { dg-output "S::f\r*\nT1::f\r*\nT2::f\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait10.rs b/gcc/testsuite/rust/execute/torture/trait10.rs
index a595122..4eb9546 100644
--- a/gcc/testsuite/rust/execute/torture/trait10.rs
+++ b/gcc/testsuite/rust/execute/torture/trait10.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
@@ -26,7 +28,6 @@ impl Bar for Foo {
struct S;
impl S {
fn dynamic_dispatch(self, t: &dyn Bar) {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
t.baz();
}
}
diff --git a/gcc/testsuite/rust/execute/torture/trait11.rs b/gcc/testsuite/rust/execute/torture/trait11.rs
index 093343c..84add74 100644
--- a/gcc/testsuite/rust/execute/torture/trait11.rs
+++ b/gcc/testsuite/rust/execute/torture/trait11.rs
@@ -1,4 +1,5 @@
/* { dg-output "3\r*\n" } */
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
@@ -13,7 +14,6 @@ trait FnLike<A, R> {
struct S;
impl<'a, T> FnLike<&'a T, &'a T> for S {
fn call(&self, arg: &'a T) -> &'a T {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
arg
}
}
diff --git a/gcc/testsuite/rust/execute/torture/trait12.rs b/gcc/testsuite/rust/execute/torture/trait12.rs
index 83cf107..dd7a644 100644
--- a/gcc/testsuite/rust/execute/torture/trait12.rs
+++ b/gcc/testsuite/rust/execute/torture/trait12.rs
@@ -1,4 +1,6 @@
/* { dg-output "3\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
@@ -16,7 +18,6 @@ struct Identity;
impl<'a, T> FnLike<&'a T, &'a T> for Identity {
fn call(&self, arg: &'a T) -> &'a T {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
arg
}
}
diff --git a/gcc/testsuite/rust/execute/torture/trait13.rs b/gcc/testsuite/rust/execute/torture/trait13.rs
index 928a37c..25912bd 100644
--- a/gcc/testsuite/rust/execute/torture/trait13.rs
+++ b/gcc/testsuite/rust/execute/torture/trait13.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n456\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
@@ -11,7 +13,6 @@ trait Bar {
fn baz(&self);
fn qux(&self) {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
unsafe {
let a = "%i\n\0";
let b = a as *const str;
diff --git a/gcc/testsuite/rust/execute/torture/trait14.rs b/gcc/testsuite/rust/execute/torture/trait14.rs
index 759950e..ebc0c5c 100644
--- a/gcc/testsuite/rust/execute/torture/trait14.rs
+++ b/gcc/testsuite/rust/execute/torture/trait14.rs
@@ -1,4 +1,5 @@
/* { dg-output "parent123\r*\nchild\r*\n" } */
+#![feature(lang_items)]
extern "C" {
fn printf(s: *const i8, ...);
diff --git a/gcc/testsuite/rust/execute/torture/trait15.rs b/gcc/testsuite/rust/execute/torture/trait15.rs
index 53469d7..59f8dc3 100644
--- a/gcc/testsuite/rust/execute/torture/trait15.rs
+++ b/gcc/testsuite/rust/execute/torture/trait15.rs
@@ -1,6 +1,8 @@
/* { dg-output "parent123\r*\nchild\r*\n" } */
// Testing generics passing with supertraits
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait2.rs b/gcc/testsuite/rust/execute/torture/trait2.rs
index d5fd546..db69c1e 100644
--- a/gcc/testsuite/rust/execute/torture/trait2.rs
+++ b/gcc/testsuite/rust/execute/torture/trait2.rs
@@ -1,4 +1,6 @@
/* { dg-output "Bar::A = 456\r*\n<Foo as Bar>::A = 456\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait3.rs b/gcc/testsuite/rust/execute/torture/trait3.rs
index 668b437..d39d324 100644
--- a/gcc/testsuite/rust/execute/torture/trait3.rs
+++ b/gcc/testsuite/rust/execute/torture/trait3.rs
@@ -1,4 +1,6 @@
/* { dg-output "123, 777\r*" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait4.rs b/gcc/testsuite/rust/execute/torture/trait4.rs
index 61c2d15..fb1eaae 100644
--- a/gcc/testsuite/rust/execute/torture/trait4.rs
+++ b/gcc/testsuite/rust/execute/torture/trait4.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n" }*/
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait5.rs b/gcc/testsuite/rust/execute/torture/trait5.rs
index 7cd7d1a..67b5dd4 100644
--- a/gcc/testsuite/rust/execute/torture/trait5.rs
+++ b/gcc/testsuite/rust/execute/torture/trait5.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait6.rs b/gcc/testsuite/rust/execute/torture/trait6.rs
index de5ddc1..baa075b 100644
--- a/gcc/testsuite/rust/execute/torture/trait6.rs
+++ b/gcc/testsuite/rust/execute/torture/trait6.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait7.rs b/gcc/testsuite/rust/execute/torture/trait7.rs
index 21f1575..47d40ae 100644
--- a/gcc/testsuite/rust/execute/torture/trait7.rs
+++ b/gcc/testsuite/rust/execute/torture/trait7.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait8.rs b/gcc/testsuite/rust/execute/torture/trait8.rs
index 69e784e..cbce3c1 100644
--- a/gcc/testsuite/rust/execute/torture/trait8.rs
+++ b/gcc/testsuite/rust/execute/torture/trait8.rs
@@ -1,4 +1,6 @@
/* { dg-output "123\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
diff --git a/gcc/testsuite/rust/execute/torture/trait9.rs b/gcc/testsuite/rust/execute/torture/trait9.rs
index a1642f6..3448eb8 100644
--- a/gcc/testsuite/rust/execute/torture/trait9.rs
+++ b/gcc/testsuite/rust/execute/torture/trait9.rs
@@ -1,4 +1,6 @@
/* { dg-output "3\r*\n" } */
+#![feature(lang_items)]
+
extern "C" {
fn printf(s: *const i8, ...);
}
@@ -13,7 +15,6 @@ trait FnLike<A, R> {
struct S;
impl<T> FnLike<&T, &T> for S {
fn call(&self, arg: &T) -> &T {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
arg
}
}
diff --git a/gcc/testsuite/rust/execute/torture/transmute1.rs b/gcc/testsuite/rust/execute/torture/transmute1.rs
index d89affd..8da1ae7 100644
--- a/gcc/testsuite/rust/execute/torture/transmute1.rs
+++ b/gcc/testsuite/rust/execute/torture/transmute1.rs
@@ -1,5 +1,5 @@
// { dg-additional-options "-w" }
-#![feature(intrinsics)]
+#![feature(intrinsics, lang_items)]
extern "rust-intrinsic" {
fn transmute<T, U>(value: T) -> U;
diff --git a/gcc/testsuite/rust/execute/torture/wrapping_op1.rs b/gcc/testsuite/rust/execute/torture/wrapping_op1.rs
index e0c100c..ba9b168 100644
--- a/gcc/testsuite/rust/execute/torture/wrapping_op1.rs
+++ b/gcc/testsuite/rust/execute/torture/wrapping_op1.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/torture/wrapping_op2.rs b/gcc/testsuite/rust/execute/torture/wrapping_op2.rs
index 6928992..5e6a37d 100644
--- a/gcc/testsuite/rust/execute/torture/wrapping_op2.rs
+++ b/gcc/testsuite/rust/execute/torture/wrapping_op2.rs
@@ -1,5 +1,6 @@
#![feature(intrinsics)]
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/execute/xfail/match-identifierpattern-enum.rs b/gcc/testsuite/rust/execute/xfail/match-identifierpattern-enum.rs
new file mode 100644
index 0000000..c3a0f65
--- /dev/null
+++ b/gcc/testsuite/rust/execute/xfail/match-identifierpattern-enum.rs
@@ -0,0 +1,15 @@
+enum Foo {
+ I(i32),
+}
+
+fn main() -> i32 {
+ let x = Foo::I(0);
+ let ret = 1;
+
+ match x {
+ _ @ Foo::I(b) => { ret = b },
+ _ => {},
+ };
+
+ ret
+}
diff --git a/gcc/testsuite/rust/link/generic_function_0.rs b/gcc/testsuite/rust/link/generic_function_0.rs
index 179c822..58b8eb1 100644
--- a/gcc/testsuite/rust/link/generic_function_0.rs
+++ b/gcc/testsuite/rust/link/generic_function_0.rs
@@ -1,6 +1,3 @@
-// { dg-xfail-if "https://github.com/Rust-GCC/gccrs/issues/2349" { *-*-* } }
-// { dg-excess-errors "" { xfail *-*-* } }
-
extern crate generic_function_1;
use generic_function_1::generic_function;
diff --git a/gcc/testsuite/rust/link/generic_function_1.rs b/gcc/testsuite/rust/link/generic_function_1.rs
index 46d0e82..dab62f0 100644
--- a/gcc/testsuite/rust/link/generic_function_1.rs
+++ b/gcc/testsuite/rust/link/generic_function_1.rs
@@ -1,3 +1,4 @@
+#![feature(lang_items)]
#[lang = "sized"]
pub trait Sized {}
diff --git a/gcc/testsuite/rust/link/trait_import_0.rs b/gcc/testsuite/rust/link/trait_import_0.rs
index 1b8c90a..ac8c581 100644
--- a/gcc/testsuite/rust/link/trait_import_0.rs
+++ b/gcc/testsuite/rust/link/trait_import_0.rs
@@ -1,6 +1,3 @@
-// { dg-xfail-if "https://github.com/Rust-GCC/gccrs/issues/2349" { *-*-* } }
-// { dg-excess-errors "" { xfail *-*-* } }
-
extern crate trait_import_1;
use trait_import_1::Add;
diff --git a/gcc/testsuite/rust/link/trait_import_1.rs b/gcc/testsuite/rust/link/trait_import_1.rs
index fc7f516..589871d 100644
--- a/gcc/testsuite/rust/link/trait_import_1.rs
+++ b/gcc/testsuite/rust/link/trait_import_1.rs
@@ -1,3 +1,7 @@
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
#[lang = "add"]
pub trait Add<Rhs = Self> {
type Output;