@@ -7,12 +7,14 @@ use rustc_hir::{self as hir, LangItem};
77use rustc_middle:: bug;
88use rustc_middle:: ty:: { self , FloatTy , IntTy , Ty , TyCtxt , TypeVisitableExt , UintTy } ;
99use rustc_session:: lint;
10- use rustc_span:: Symbol ;
1110use rustc_span:: def_id:: LocalDefId ;
11+ use rustc_span:: { Symbol , sym} ;
1212use rustc_target:: asm:: {
1313 InlineAsmReg , InlineAsmRegClass , InlineAsmRegOrRegClass , InlineAsmType , ModifierInfo ,
1414} ;
1515
16+ use crate :: errors:: RegisterTypeUnstable ;
17+
1618pub struct InlineAsmCtxt < ' a , ' tcx > {
1719 tcx : TyCtxt < ' tcx > ,
1820 typing_env : ty:: TypingEnv < ' tcx > ,
@@ -218,17 +220,29 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
218220 // Check the type against the list of types supported by the selected
219221 // register class.
220222 let asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ;
223+ let allow_experimental_reg = self . tcx . features ( ) . asm_experimental_reg ( ) ;
221224 let reg_class = reg. reg_class ( ) ;
222- let supported_tys = reg_class. supported_types ( asm_arch) ;
225+ let supported_tys = reg_class. supported_types ( asm_arch, allow_experimental_reg ) ;
223226 let Some ( ( _, feature) ) = supported_tys. iter ( ) . find ( |& & ( t, _) | t == asm_ty) else {
224- let msg = format ! ( "type `{ty}` cannot be used with this register class" ) ;
225- let mut err = self . tcx . dcx ( ) . struct_span_err ( expr. span , msg) ;
226- let supported_tys: Vec < _ > = supported_tys. iter ( ) . map ( |( t, _) | t. to_string ( ) ) . collect ( ) ;
227- err. note ( format ! (
228- "register class `{}` supports these types: {}" ,
229- reg_class. name( ) ,
230- supported_tys. join( ", " ) ,
231- ) ) ;
227+ let mut err = if !allow_experimental_reg
228+ && reg_class. supported_types ( asm_arch, true ) . iter ( ) . any ( |& ( t, _) | t == asm_ty)
229+ {
230+ self . tcx . sess . create_feature_err (
231+ RegisterTypeUnstable { span : expr. span , ty } ,
232+ sym:: asm_experimental_reg,
233+ )
234+ } else {
235+ let msg = format ! ( "type `{ty}` cannot be used with this register class" ) ;
236+ let mut err = self . tcx . dcx ( ) . struct_span_err ( expr. span , msg) ;
237+ let supported_tys: Vec < _ > =
238+ supported_tys. iter ( ) . map ( |( t, _) | t. to_string ( ) ) . collect ( ) ;
239+ err. note ( format ! (
240+ "register class `{}` supports these types: {}" ,
241+ reg_class. name( ) ,
242+ supported_tys. join( ", " ) ,
243+ ) ) ;
244+ err
245+ } ;
232246 if let Some ( suggest) = reg_class. suggest_class ( asm_arch, asm_ty) {
233247 err. help ( format ! ( "consider using the `{}` register class instead" , suggest. name( ) ) ) ;
234248 }
@@ -313,6 +327,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
313327 self . tcx . dcx ( ) . delayed_bug ( "target architecture does not support asm" ) ;
314328 return ;
315329 } ;
330+ let allow_experimental_reg = self . tcx . features ( ) . asm_experimental_reg ( ) ;
316331 for ( idx, ( op, op_sp) ) in asm. operands . iter ( ) . enumerate ( ) {
317332 // Validate register classes against currently enabled target
318333 // features. We check that at least one type is available for
@@ -352,7 +367,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
352367 if let InlineAsmRegClass :: Err = reg_class {
353368 continue ;
354369 }
355- for & ( _, feature) in reg_class. supported_types ( asm_arch) {
370+ for & ( _, feature) in reg_class. supported_types ( asm_arch, allow_experimental_reg)
371+ {
356372 match feature {
357373 Some ( feature) => {
358374 if target_features. contains ( & feature) {
0 commit comments