@@ -78,8 +78,42 @@ 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 error already unless this feature is enabled.
92+ if !tcx. features ( ) . unsized_fn_params ( ) {
93+ return ;
94+ }
95+
96+ // Unsized parameters are allowed with the (unstable) "Rust" (and similar) ABIs.
97+ if fn_abi. conv . is_rustic_abi ( ) {
98+ return ;
99+ }
100+
101+ for arg_abi in fn_abi. args . iter ( ) {
102+ if !arg_abi. layout . layout . is_sized ( ) {
103+ let ( span, _hir_id) = loc ( ) ;
104+ tcx. dcx ( ) . emit_err ( errors:: AbiErrorUnsupportedUnsizedParameter {
105+ span,
106+ ty : arg_abi. layout . ty ,
107+ is_call,
108+ } ) ;
109+ }
110+ }
111+ }
112+
113+ /// Checks the ABI of an Instance, emitting an error when:
114+ ///
115+ /// - a non-rustic ABI uses unsized parameters
116+ /// - the signature requires target features that are not enabled
83117fn check_instance_abi < ' tcx > ( tcx : TyCtxt < ' tcx > , instance : Instance < ' tcx > ) {
84118 let typing_env = ty:: TypingEnv :: fully_monomorphized ( ) ;
85119 let Ok ( abi) = tcx. fn_abi_of_instance ( typing_env. as_query_input ( ( instance, ty:: List :: empty ( ) ) ) )
@@ -102,11 +136,14 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
102136 def_id. as_local ( ) . map ( |did| tcx. local_def_id_to_hir_id ( did) ) . unwrap_or ( CRATE_HIR_ID ) ,
103137 )
104138 } ;
139+ do_check_unsized_params ( tcx, abi, /*is_call*/ false , loc) ;
105140 do_check_simd_vector_abi ( tcx, abi, instance. def_id ( ) , /*is_call*/ false , loc) ;
106141}
107142
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.
143+ /// Check the ABI at a call site, emitting an error when:
144+ ///
145+ /// - a non-rustic ABI uses unsized parameters
146+ /// - the signature requires target features that are not enabled
110147fn check_call_site_abi < ' tcx > (
111148 tcx : TyCtxt < ' tcx > ,
112149 callee : Ty < ' tcx > ,
@@ -140,6 +177,7 @@ fn check_call_site_abi<'tcx>(
140177 // ABI failed to compute; this will not get through codegen.
141178 return ;
142179 } ;
180+ do_check_unsized_params ( tcx, callee_abi, /*is_call*/ true , loc) ;
143181 do_check_simd_vector_abi ( tcx, callee_abi, caller. def_id ( ) , /*is_call*/ true , loc) ;
144182}
145183
0 commit comments