mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Handle InlineAsm in clippy
This commit is contained in:
parent
f1d3086492
commit
d25b25610b
@ -16,8 +16,8 @@ use rustc_errors::Applicability;
|
|||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
def_id, BinOpKind, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, GenericArg, HirId, LoopSource,
|
def_id, BinOpKind, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, GenericArg, HirId, InlineAsmOperand,
|
||||||
MatchSource, Mutability, Node, Pat, PatKind, QPath, Stmt, StmtKind,
|
LoopSource, MatchSource, Mutability, Node, Pat, PatKind, QPath, Stmt, StmtKind,
|
||||||
};
|
};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
@ -693,6 +693,20 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
|
|||||||
NeverLoopResult::AlwaysBreak
|
NeverLoopResult::AlwaysBreak
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ExprKind::InlineAsm(ref asm) => asm
|
||||||
|
.operands
|
||||||
|
.iter()
|
||||||
|
.map(|o| match o {
|
||||||
|
InlineAsmOperand::In { expr, .. }
|
||||||
|
| InlineAsmOperand::InOut { expr, .. }
|
||||||
|
| InlineAsmOperand::Const { expr }
|
||||||
|
| InlineAsmOperand::Sym { expr } => never_loop_expr(expr, main_loop_id),
|
||||||
|
InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter(), main_loop_id),
|
||||||
|
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
|
||||||
|
never_loop_expr_all(&mut once(in_expr).chain(out_expr.iter()), main_loop_id)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.fold(NeverLoopResult::Otherwise, combine_both),
|
||||||
ExprKind::Struct(_, _, None)
|
ExprKind::Struct(_, _, None)
|
||||||
| ExprKind::Yield(_, _)
|
| ExprKind::Yield(_, _)
|
||||||
| ExprKind::Closure(_, _, _, _, _)
|
| ExprKind::Closure(_, _, _, _, _)
|
||||||
|
@ -469,6 +469,10 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||||||
println!("Ret(None) = {};", current);
|
println!("Ret(None) = {};", current);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ExprKind::InlineAsm(_) => {
|
||||||
|
println!("InlineAsm(_) = {};", current);
|
||||||
|
println!(" // unimplemented: `ExprKind::InlineAsm` is not further destructured at the moment");
|
||||||
|
},
|
||||||
ExprKind::LlvmInlineAsm(_) => {
|
ExprKind::LlvmInlineAsm(_) => {
|
||||||
println!("LlvmInlineAsm(_) = {};", current);
|
println!("LlvmInlineAsm(_) = {};", current);
|
||||||
println!(" // unimplemented: `ExprKind::LlvmInlineAsm` is not further destructured at the moment");
|
println!(" // unimplemented: `ExprKind::LlvmInlineAsm` is not further destructured at the moment");
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use crate::consts::{constant_context, constant_simple};
|
use crate::consts::{constant_context, constant_simple};
|
||||||
use crate::utils::differing_macro_contexts;
|
use crate::utils::differing_macro_contexts;
|
||||||
|
use rustc_ast::ast::InlineAsmTemplatePiece;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprKind, Field, FnRetTy, GenericArg,
|
BinOpKind, Block, BlockCheckMode, BodyId, BorrowKind, CaptureBy, Expr, ExprKind, Field, FnRetTy, GenericArg,
|
||||||
GenericArgs, Guard, Lifetime, LifetimeName, ParamName, Pat, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, Ty,
|
GenericArgs, Guard, InlineAsmOperand, Lifetime, LifetimeName, ParamName, Pat, PatKind, Path, PathSegment, QPath,
|
||||||
TyKind, TypeBinding,
|
Stmt, StmtKind, Ty, TyKind, TypeBinding,
|
||||||
};
|
};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ich::StableHashingContextProvider;
|
use rustc_middle::ich::StableHashingContextProvider;
|
||||||
@ -474,6 +475,56 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||||||
self.hash_expr(a);
|
self.hash_expr(a);
|
||||||
self.hash_expr(i);
|
self.hash_expr(i);
|
||||||
},
|
},
|
||||||
|
ExprKind::InlineAsm(ref asm) => {
|
||||||
|
for piece in asm.template {
|
||||||
|
match piece {
|
||||||
|
InlineAsmTemplatePiece::String(s) => s.hash(&mut self.s),
|
||||||
|
InlineAsmTemplatePiece::Placeholder {
|
||||||
|
operand_idx,
|
||||||
|
modifier,
|
||||||
|
span: _,
|
||||||
|
} => {
|
||||||
|
operand_idx.hash(&mut self.s);
|
||||||
|
modifier.hash(&mut self.s);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asm.options.hash(&mut self.s);
|
||||||
|
for op in asm.operands {
|
||||||
|
match op {
|
||||||
|
InlineAsmOperand::In { reg, expr } => {
|
||||||
|
reg.hash(&mut self.s);
|
||||||
|
self.hash_expr(expr);
|
||||||
|
},
|
||||||
|
InlineAsmOperand::Out { reg, late, expr } => {
|
||||||
|
reg.hash(&mut self.s);
|
||||||
|
late.hash(&mut self.s);
|
||||||
|
if let Some(expr) = expr {
|
||||||
|
self.hash_expr(expr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InlineAsmOperand::InOut { reg, late, expr } => {
|
||||||
|
reg.hash(&mut self.s);
|
||||||
|
late.hash(&mut self.s);
|
||||||
|
self.hash_expr(expr);
|
||||||
|
},
|
||||||
|
InlineAsmOperand::SplitInOut {
|
||||||
|
reg,
|
||||||
|
late,
|
||||||
|
in_expr,
|
||||||
|
out_expr,
|
||||||
|
} => {
|
||||||
|
reg.hash(&mut self.s);
|
||||||
|
late.hash(&mut self.s);
|
||||||
|
self.hash_expr(in_expr);
|
||||||
|
if let Some(out_expr) = out_expr {
|
||||||
|
self.hash_expr(out_expr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
InlineAsmOperand::Const { expr } | InlineAsmOperand::Sym { expr } => self.hash_expr(expr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
ExprKind::LlvmInlineAsm(..) | ExprKind::Err => {},
|
ExprKind::LlvmInlineAsm(..) | ExprKind::Err => {},
|
||||||
ExprKind::Lit(ref l) => {
|
ExprKind::Lit(ref l) => {
|
||||||
l.node.hash(&mut self.s);
|
l.node.hash(&mut self.s);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! checks for attributes
|
//! checks for attributes
|
||||||
|
|
||||||
use crate::utils::get_attr;
|
use crate::utils::get_attr;
|
||||||
use rustc_ast::ast::Attribute;
|
use rustc_ast::ast::{Attribute, InlineAsmTemplatePiece};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
@ -282,6 +282,31 @@ fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, indent: usize) {
|
|||||||
print_expr(cx, e, indent + 1);
|
print_expr(cx, e, indent + 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
hir::ExprKind::InlineAsm(ref asm) => {
|
||||||
|
println!("{}InlineAsm", ind);
|
||||||
|
println!("{}template: {}", ind, InlineAsmTemplatePiece::to_string(asm.template));
|
||||||
|
println!("{}options: {:?}", ind, asm.options);
|
||||||
|
println!("{}operands:", ind);
|
||||||
|
for op in asm.operands {
|
||||||
|
match op {
|
||||||
|
hir::InlineAsmOperand::In { expr, .. } => print_expr(cx, expr, indent + 1),
|
||||||
|
hir::InlineAsmOperand::Out { expr, .. } => {
|
||||||
|
if let Some(expr) = expr {
|
||||||
|
print_expr(cx, expr, indent + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hir::InlineAsmOperand::InOut { expr, .. } => print_expr(cx, expr, indent + 1),
|
||||||
|
hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
|
||||||
|
print_expr(cx, in_expr, indent + 1);
|
||||||
|
if let Some(out_expr) = out_expr {
|
||||||
|
print_expr(cx, out_expr, indent + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hir::InlineAsmOperand::Const { expr } => print_expr(cx, expr, indent + 1),
|
||||||
|
hir::InlineAsmOperand::Sym { expr } => print_expr(cx, expr, indent + 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
hir::ExprKind::LlvmInlineAsm(ref asm) => {
|
hir::ExprKind::LlvmInlineAsm(ref asm) => {
|
||||||
let inputs = &asm.inputs_exprs;
|
let inputs = &asm.inputs_exprs;
|
||||||
let outputs = &asm.outputs_exprs;
|
let outputs = &asm.outputs_exprs;
|
||||||
|
@ -108,6 +108,7 @@ impl<'a> Sugg<'a> {
|
|||||||
| hir::ExprKind::Call(..)
|
| hir::ExprKind::Call(..)
|
||||||
| hir::ExprKind::Field(..)
|
| hir::ExprKind::Field(..)
|
||||||
| hir::ExprKind::Index(..)
|
| hir::ExprKind::Index(..)
|
||||||
|
| hir::ExprKind::InlineAsm(..)
|
||||||
| hir::ExprKind::LlvmInlineAsm(..)
|
| hir::ExprKind::LlvmInlineAsm(..)
|
||||||
| hir::ExprKind::Lit(..)
|
| hir::ExprKind::Lit(..)
|
||||||
| hir::ExprKind::Loop(..)
|
| hir::ExprKind::Loop(..)
|
||||||
@ -150,6 +151,7 @@ impl<'a> Sugg<'a> {
|
|||||||
| ast::ExprKind::Field(..)
|
| ast::ExprKind::Field(..)
|
||||||
| ast::ExprKind::ForLoop(..)
|
| ast::ExprKind::ForLoop(..)
|
||||||
| ast::ExprKind::Index(..)
|
| ast::ExprKind::Index(..)
|
||||||
|
| ast::ExprKind::InlineAsm(..)
|
||||||
| ast::ExprKind::LlvmInlineAsm(..)
|
| ast::ExprKind::LlvmInlineAsm(..)
|
||||||
| ast::ExprKind::Lit(..)
|
| ast::ExprKind::Lit(..)
|
||||||
| ast::ExprKind::Loop(..)
|
| ast::ExprKind::Loop(..)
|
||||||
|
@ -353,7 +353,8 @@ impl Write {
|
|||||||
is_write: bool,
|
is_write: bool,
|
||||||
) -> (Option<StrLit>, Option<Expr>) {
|
) -> (Option<StrLit>, Option<Expr>) {
|
||||||
use fmt_macros::{
|
use fmt_macros::{
|
||||||
AlignUnknown, ArgumentImplicitlyIs, ArgumentIs, ArgumentNamed, CountImplied, FormatSpec, Parser, Piece,
|
AlignUnknown, ArgumentImplicitlyIs, ArgumentIs, ArgumentNamed, CountImplied, FormatSpec, ParseMode, Parser,
|
||||||
|
Piece,
|
||||||
};
|
};
|
||||||
let tts = tts.clone();
|
let tts = tts.clone();
|
||||||
|
|
||||||
@ -376,7 +377,7 @@ impl Write {
|
|||||||
};
|
};
|
||||||
let tmp = fmtstr.symbol.as_str();
|
let tmp = fmtstr.symbol.as_str();
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
let mut fmt_parser = Parser::new(&tmp, None, Vec::new(), false);
|
let mut fmt_parser = Parser::new(&tmp, None, None, false, ParseMode::Format);
|
||||||
while let Some(piece) = fmt_parser.next() {
|
while let Some(piece) = fmt_parser.next() {
|
||||||
if !fmt_parser.errors.is_empty() {
|
if !fmt_parser.errors.is_empty() {
|
||||||
return (None, expr);
|
return (None, expr);
|
||||||
|
Loading…
Reference in New Issue
Block a user