@@ -1331,84 +1331,83 @@ impl<'hir> LoweringContext<'_, 'hir> {
13311331 }
13321332
13331333 fn lower_expr_asm ( & mut self , sp : Span , asm : & InlineAsm ) -> hir:: ExprKind < ' hir > {
1334- if self . sess . asm_arch . is_none ( ) {
1334+ // Rustdoc needs to support asm! from foriegn architectures: don't try
1335+ // lowering the register contraints in this case.
1336+ let asm_arch = if self . sess . opts . actually_rustdoc { None } else { self . sess . asm_arch } ;
1337+ if asm_arch. is_none ( ) && !self . sess . opts . actually_rustdoc {
13351338 struct_span_err ! ( self . sess, sp, E0472 , "asm! is unsupported on this target" ) . emit ( ) ;
13361339 }
13371340 if asm. options . contains ( InlineAsmOptions :: ATT_SYNTAX )
1338- && !matches ! (
1339- self . sess. asm_arch,
1340- Some ( asm:: InlineAsmArch :: X86 | asm:: InlineAsmArch :: X86_64 )
1341- )
1341+ && !matches ! ( asm_arch, Some ( asm:: InlineAsmArch :: X86 | asm:: InlineAsmArch :: X86_64 ) )
1342+ && !self . sess . opts . actually_rustdoc
13421343 {
13431344 self . sess
13441345 . struct_span_err ( sp, "the `att_syntax` option is only supported on x86" )
13451346 . emit ( ) ;
13461347 }
13471348
1348- // Lower operands to HIR, filter_map skips any operands with invalid
1349- // register classes.
1349+ // Lower operands to HIR. We use dummy register classes if an error
1350+ // occurs during lowering because we still need to be able to produce a
1351+ // valid HIR.
13501352 let sess = self . sess ;
13511353 let operands: Vec < _ > = asm
13521354 . operands
13531355 . iter ( )
1354- . filter_map ( |( op, op_sp) | {
1355- let lower_reg = |reg| {
1356- Some ( match reg {
1357- InlineAsmRegOrRegClass :: Reg ( s ) => asm :: InlineAsmRegOrRegClass :: Reg (
1356+ . map ( |( op, op_sp) | {
1357+ let lower_reg = |reg| match reg {
1358+ InlineAsmRegOrRegClass :: Reg ( s ) => {
1359+ asm :: InlineAsmRegOrRegClass :: Reg ( if let Some ( asm_arch ) = asm_arch {
13581360 asm:: InlineAsmReg :: parse (
1359- sess . asm_arch ? ,
1361+ asm_arch,
13601362 |feature| sess. target_features . contains ( & Symbol :: intern ( feature) ) ,
13611363 & sess. target ,
13621364 s,
13631365 )
1364- . map_err ( |e| {
1366+ . unwrap_or_else ( |e| {
13651367 let msg = format ! ( "invalid register `{}`: {}" , s. as_str( ) , e) ;
13661368 sess. struct_span_err ( * op_sp, & msg) . emit ( ) ;
1369+ asm:: InlineAsmReg :: Err
13671370 } )
1368- . ok ( ) ?,
1369- ) ,
1370- InlineAsmRegOrRegClass :: RegClass ( s) => {
1371- asm:: InlineAsmRegOrRegClass :: RegClass (
1372- asm:: InlineAsmRegClass :: parse ( sess. asm_arch ?, s)
1373- . map_err ( |e| {
1374- let msg = format ! (
1375- "invalid register class `{}`: {}" ,
1376- s. as_str( ) ,
1377- e
1378- ) ;
1379- sess. struct_span_err ( * op_sp, & msg) . emit ( ) ;
1380- } )
1381- . ok ( ) ?,
1382- )
1383- }
1384- } )
1371+ } else {
1372+ asm:: InlineAsmReg :: Err
1373+ } )
1374+ }
1375+ InlineAsmRegOrRegClass :: RegClass ( s) => {
1376+ asm:: InlineAsmRegOrRegClass :: RegClass ( if let Some ( asm_arch) = asm_arch {
1377+ asm:: InlineAsmRegClass :: parse ( asm_arch, s) . unwrap_or_else ( |e| {
1378+ let msg = format ! ( "invalid register class `{}`: {}" , s. as_str( ) , e) ;
1379+ sess. struct_span_err ( * op_sp, & msg) . emit ( ) ;
1380+ asm:: InlineAsmRegClass :: Err
1381+ } )
1382+ } else {
1383+ asm:: InlineAsmRegClass :: Err
1384+ } )
1385+ }
13851386 } ;
13861387
1387- // lower_reg is executed last because we need to lower all
1388- // sub-expressions even if we throw them away later.
13891388 let op = match * op {
13901389 InlineAsmOperand :: In { reg, ref expr } => hir:: InlineAsmOperand :: In {
1390+ reg : lower_reg ( reg) ,
13911391 expr : self . lower_expr_mut ( expr) ,
1392- reg : lower_reg ( reg) ?,
13931392 } ,
13941393 InlineAsmOperand :: Out { reg, late, ref expr } => hir:: InlineAsmOperand :: Out {
1394+ reg : lower_reg ( reg) ,
13951395 late,
13961396 expr : expr. as_ref ( ) . map ( |expr| self . lower_expr_mut ( expr) ) ,
1397- reg : lower_reg ( reg) ?,
13981397 } ,
13991398 InlineAsmOperand :: InOut { reg, late, ref expr } => {
14001399 hir:: InlineAsmOperand :: InOut {
1400+ reg : lower_reg ( reg) ,
14011401 late,
14021402 expr : self . lower_expr_mut ( expr) ,
1403- reg : lower_reg ( reg) ?,
14041403 }
14051404 }
14061405 InlineAsmOperand :: SplitInOut { reg, late, ref in_expr, ref out_expr } => {
14071406 hir:: InlineAsmOperand :: SplitInOut {
1407+ reg : lower_reg ( reg) ,
14081408 late,
14091409 in_expr : self . lower_expr_mut ( in_expr) ,
14101410 out_expr : out_expr. as_ref ( ) . map ( |expr| self . lower_expr_mut ( expr) ) ,
1411- reg : lower_reg ( reg) ?,
14121411 }
14131412 }
14141413 InlineAsmOperand :: Const { ref expr } => {
@@ -1418,17 +1417,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
14181417 hir:: InlineAsmOperand :: Sym { expr : self . lower_expr_mut ( expr) }
14191418 }
14201419 } ;
1421- Some ( ( op, * op_sp) )
1420+ ( op, * op_sp)
14221421 } )
14231422 . collect ( ) ;
14241423
1425- // Stop if there were any errors when lowering the register classes
1426- if operands. len ( ) != asm. operands . len ( ) || sess. asm_arch . is_none ( ) {
1427- return hir:: ExprKind :: Err ;
1428- }
1429-
14301424 // Validate template modifiers against the register classes for the operands
1431- let asm_arch = sess. asm_arch . unwrap ( ) ;
14321425 for p in & asm. template {
14331426 if let InlineAsmTemplatePiece :: Placeholder {
14341427 operand_idx,
@@ -1443,7 +1436,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
14431436 | hir:: InlineAsmOperand :: InOut { reg, .. }
14441437 | hir:: InlineAsmOperand :: SplitInOut { reg, .. } => {
14451438 let class = reg. reg_class ( ) ;
1446- let valid_modifiers = class. valid_modifiers ( asm_arch) ;
1439+ if class == asm:: InlineAsmRegClass :: Err {
1440+ continue ;
1441+ }
1442+ let valid_modifiers = class. valid_modifiers ( asm_arch. unwrap ( ) ) ;
14471443 if !valid_modifiers. contains ( & modifier) {
14481444 let mut err = sess. struct_span_err (
14491445 placeholder_span,
@@ -1506,7 +1502,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
15061502 // features. We check that at least one type is available for
15071503 // the current target.
15081504 let reg_class = reg. reg_class ( ) ;
1509- for & ( _, feature) in reg_class. supported_types ( asm_arch) {
1505+ if reg_class == asm:: InlineAsmRegClass :: Err {
1506+ continue ;
1507+ }
1508+ for & ( _, feature) in reg_class. supported_types ( asm_arch. unwrap ( ) ) {
15101509 if let Some ( feature) = feature {
15111510 if self . sess . target_features . contains ( & Symbol :: intern ( feature) ) {
15121511 required_features. clear ( ) ;
0 commit comments