Refactor #82270 as lint instead of an error
This commit is contained in:
parent
2bd94f4aa9
commit
5dabc80796
6 changed files with 179 additions and 118 deletions
|
@ -7,11 +7,10 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
|
|||
use rustc_expand::base::{self, *};
|
||||
use rustc_parse::parser::Parser;
|
||||
use rustc_parse_format as parse;
|
||||
use rustc_span::{
|
||||
symbol::{kw, sym, Symbol},
|
||||
BytePos,
|
||||
};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::{InnerSpan, Span};
|
||||
use rustc_target::asm::InlineAsmArch;
|
||||
|
||||
struct AsmArgs {
|
||||
templates: Vec<P<ast::Expr>>,
|
||||
|
@ -402,8 +401,6 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
|
|||
let mut line_spans = Vec::with_capacity(args.templates.len());
|
||||
let mut curarg = 0;
|
||||
|
||||
let default_dialect = ecx.sess.inline_asm_dialect();
|
||||
|
||||
for template_expr in args.templates.into_iter() {
|
||||
if !template.is_empty() {
|
||||
template.push(ast::InlineAsmTemplatePiece::String("\n".to_string()));
|
||||
|
@ -430,56 +427,36 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
|
|||
let template_str = &template_str.as_str();
|
||||
let template_snippet = ecx.source_map().span_to_snippet(template_sp).ok();
|
||||
|
||||
if let Some(snippet) = &template_snippet {
|
||||
let snippet = snippet.trim_matches('"');
|
||||
match default_dialect {
|
||||
ast::LlvmAsmDialect::Intel => {
|
||||
if let Some(span) = check_syntax_directive(snippet, ".intel_syntax") {
|
||||
let span = template_span.from_inner(span);
|
||||
let mut err = ecx.struct_span_err(span, "intel syntax is the default syntax on this target, and trying to use this directive may cause issues");
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"remove this assembler directive",
|
||||
"".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
|
||||
let span = template_span.from_inner(span);
|
||||
let mut err = ecx.struct_span_err(span, "using the .att_syntax directive may cause issues, use the att_syntax option instead");
|
||||
let asm_end = sp.hi() - BytePos(2);
|
||||
let suggestions = vec![
|
||||
(span, "".to_string()),
|
||||
(
|
||||
Span::new(asm_end, asm_end, sp.ctxt()),
|
||||
", options(att_syntax)".to_string(),
|
||||
),
|
||||
];
|
||||
err.multipart_suggestion(
|
||||
"remove the assembler directive and replace it with options(att_syntax)",
|
||||
suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
if let Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) = ecx.sess.asm_arch {
|
||||
let find_span = |needle: &str| -> Span {
|
||||
if let Some(snippet) = &template_snippet {
|
||||
if let Some(pos) = snippet.find(needle) {
|
||||
let end = pos
|
||||
+ &snippet[pos..]
|
||||
.find(|c| matches!(c, '\n' | ';' | '\\' | '"'))
|
||||
.unwrap_or(snippet[pos..].len() - 1);
|
||||
let inner = InnerSpan::new(pos, end);
|
||||
return template_sp.from_inner(inner);
|
||||
}
|
||||
}
|
||||
ast::LlvmAsmDialect::Att => {
|
||||
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
|
||||
let span = template_span.from_inner(span);
|
||||
let mut err = ecx.struct_span_err(span, "att syntax is the default syntax on this target, and trying to use this directive may cause issues");
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"remove this assembler directive",
|
||||
"".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
template_sp
|
||||
};
|
||||
|
||||
// Use of .intel_syntax is ignored
|
||||
}
|
||||
if template_str.contains(".intel_syntax") {
|
||||
ecx.parse_sess().buffer_lint(
|
||||
lint::builtin::BAD_ASM_STYLE,
|
||||
find_span(".intel_syntax"),
|
||||
ecx.resolver.lint_node_id(ecx.current_expansion.id),
|
||||
"avoid using `.intel_syntax`, Intel syntax is the default",
|
||||
);
|
||||
}
|
||||
if template_str.contains(".att_syntax") {
|
||||
ecx.parse_sess().buffer_lint(
|
||||
lint::builtin::BAD_ASM_STYLE,
|
||||
find_span(".att_syntax"),
|
||||
ecx.resolver.lint_node_id(ecx.current_expansion.id),
|
||||
"avoid using `.att_syntax`, prefer using `options(att_syntax)` instead",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -690,15 +667,3 @@ pub fn expand_asm<'cx>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_syntax_directive<S: AsRef<str>>(piece: S, syntax: &str) -> Option<InnerSpan> {
|
||||
let piece = piece.as_ref();
|
||||
if let Some(idx) = piece.find(syntax) {
|
||||
let end =
|
||||
idx + &piece[idx..].find(|c| matches!(c, '\n' | ';')).unwrap_or(piece[idx..].len());
|
||||
// Offset by one because these represent the span with the " removed
|
||||
Some(InnerSpan::new(idx + 1, end + 1))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue