@@ -78,8 +78,37 @@ fn do_check_simd_vector_abi<'tcx>(
7878 }
7979}
8080
81- /// Checks that the ABI of a given instance of a function does not contain vector-passed arguments
82- /// or return values for which the corresponding target feature is not enabled.
81+ /// Emit an error when a non-rustic ABI has unsized parameters.
82+ /// Unsized types do not have a stable layout, so should not be used with stable ABIs.
83+ /// `is_call` indicates whether this is a call-site check or a definition-site check;
84+ /// this is only relevant for the wording in the emitted error.
85+ fn do_check_unsized_params < ' tcx > (
86+ tcx : TyCtxt < ' tcx > ,
87+ fn_abi : & FnAbi < ' tcx , Ty < ' tcx > > ,
88+ is_call : bool ,
89+ loc : impl Fn ( ) -> ( Span , HirId ) ,
90+ ) {
91+ // Unsized parameters are allowed with the (unstable) "Rust" (and similar) ABIs.
92+ if fn_abi. conv . is_rustic_abi ( ) {
93+ return ;
94+ }
95+
96+ for arg_abi in fn_abi. args . iter ( ) {
97+ if !arg_abi. layout . layout . is_sized ( ) {
98+ let ( span, _hir_id) = loc ( ) ;
99+ tcx. dcx ( ) . emit_err ( errors:: AbiErrorUnsupportedUnsizedParameter {
100+ span,
101+ ty : arg_abi. layout . ty ,
102+ is_call,
103+ } ) ;
104+ }
105+ }
106+ }
107+
108+ /// Checks the ABI of an Instance, emitting an error when:
109+ ///
110+ /// - a non-rustic ABI uses unsized parameters
111+ /// - the signature requires target features that are not enabled
83112fn check_instance_abi < ' tcx > ( tcx : TyCtxt < ' tcx > , instance : Instance < ' tcx > ) {
84113 let typing_env = ty:: TypingEnv :: fully_monomorphized ( ) ;
85114 let Ok ( abi) = tcx. fn_abi_of_instance ( typing_env. as_query_input ( ( instance, ty:: List :: empty ( ) ) ) )
@@ -102,11 +131,14 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
102131 def_id. as_local ( ) . map ( |did| tcx. local_def_id_to_hir_id ( did) ) . unwrap_or ( CRATE_HIR_ID ) ,
103132 )
104133 } ;
134+ do_check_unsized_params ( tcx, abi, /*is_call*/ false , loc) ;
105135 do_check_simd_vector_abi ( tcx, abi, instance. def_id ( ) , /*is_call*/ false , loc) ;
106136}
107137
108- /// Checks that a call expression does not try to pass a vector-passed argument which requires a
109- /// target feature that the caller does not have, as doing so causes UB because of ABI mismatch.
138+ /// Check the ABI at a call site, emitting an error when:
139+ ///
140+ /// - a non-rustic ABI uses unsized parameters
141+ /// - the signature requires target features that are not enabled
110142fn check_call_site_abi < ' tcx > (
111143 tcx : TyCtxt < ' tcx > ,
112144 callee : Ty < ' tcx > ,
@@ -140,6 +172,7 @@ fn check_call_site_abi<'tcx>(
140172 // ABI failed to compute; this will not get through codegen.
141173 return ;
142174 } ;
175+ do_check_unsized_params ( tcx, callee_abi, /*is_call*/ true , loc) ;
143176 do_check_simd_vector_abi ( tcx, callee_abi, caller. def_id ( ) , /*is_call*/ true , loc) ;
144177}
145178
0 commit comments