Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 6f318e3

Browse files
committed
propagate errors about failing to rewrite a macro
1 parent 6ada5b5 commit 6f318e3

File tree

10 files changed

+228
-4
lines changed

10 files changed

+228
-4
lines changed

src/expr.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,9 @@ pub fn rewrite_block_with_visitor(
522522
let inner_attrs = attrs.map(inner_attributes);
523523
let label_str = rewrite_label(label);
524524
visitor.visit_block(block, inner_attrs.as_ref().map(|a| &**a), has_braces);
525+
if visitor.macro_rewrite_failure {
526+
context.macro_rewrite_failure.replace(true);
527+
}
525528
Some(format!("{}{}{}", prefix, label_str, visitor.buffer))
526529
}
527530

src/items.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,10 @@ pub fn format_impl(
747747

748748
visitor.format_missing(item.span.hi() - BytePos(1));
749749

750+
if visitor.macro_rewrite_failure {
751+
context.macro_rewrite_failure.replace(true);
752+
}
753+
750754
let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config);
751755
let outer_indent_str = offset.block_only().to_string_with_newline(context.config);
752756

@@ -1106,6 +1110,10 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
11061110

11071111
visitor.format_missing(item.span.hi() - BytePos(1));
11081112

1113+
if visitor.macro_rewrite_failure {
1114+
context.macro_rewrite_failure.replace(true);
1115+
}
1116+
11091117
let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config);
11101118
let outer_indent_str = offset.block_only().to_string_with_newline(context.config);
11111119

src/macros.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ impl Rewrite for ast::Item {
6969
visitor.block_indent = shape.indent;
7070
visitor.last_pos = self.span().lo();
7171
visitor.visit_item(self);
72+
if visitor.macro_rewrite_failure {
73+
context.macro_rewrite_failure.replace(true);
74+
}
7275
Some(visitor.buffer)
7376
}
7477
}
@@ -406,7 +409,15 @@ pub fn rewrite_macro_def(
406409
";",
407410
|branch| branch.span.lo(),
408411
|branch| branch.span.hi(),
409-
|branch| branch.rewrite(context, arm_shape, multi_branch_style),
412+
|branch| match branch.rewrite(context, arm_shape, multi_branch_style) {
413+
Some(v) => Some(v),
414+
// if the rewrite returned None because a macro could not be rewritten, then return the
415+
// original body
416+
None if *context.macro_rewrite_failure.borrow() == true => {
417+
Some(context.snippet(branch.body).trim().to_string())
418+
}
419+
None => None,
420+
},
410421
context.snippet_provider.span_after(span, "{"),
411422
span.hi(),
412423
false,

src/visitor.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
9797
if contains_skip(get_attrs_from_stmt(stmt)) {
9898
self.push_skipped_with_span(stmt.span());
9999
} else {
100-
let rewrite = stmt.rewrite(&self.get_context(), self.shape());
100+
let shape = self.shape().clone();
101+
let rewrite = self.with_context(|ctx| stmt.rewrite(&ctx, shape));
101102
self.push_rewrite(stmt.span(), rewrite)
102103
}
103104
}
@@ -350,11 +351,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
350351
let where_span_end = snippet
351352
.find_uncommented("{")
352353
.map(|x| BytePos(x as u32) + source!(self, item.span).lo());
353-
let rw = format_impl(&self.get_context(), item, self.block_indent, where_span_end);
354+
let block_indent = self.block_indent.clone();
355+
let rw =
356+
self.with_context(|ctx| format_impl(&ctx, item, block_indent, where_span_end));
354357
self.push_rewrite(item.span, rw);
355358
}
356359
ast::ItemKind::Trait(..) => {
357-
let rw = format_trait(&self.get_context(), item, self.block_indent);
360+
let block_indent = self.block_indent.clone();
361+
let rw = self.with_context(|ctx| format_trait(&ctx, item, block_indent));
358362
self.push_rewrite(item.span, rw);
359363
}
360364
ast::ItemKind::TraitAlias(ref generics, ref generic_bounds) => {

tests/source/issue-2977/impl.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
macro_rules! atomic_bits {
2+
// the println macro cannot be rewritten because of the asm macro
3+
($type:ty, $ldrex:expr, $strex:expr) => {
4+
impl AtomicBits for $type {
5+
unsafe fn load_excl(address: usize) -> Self {
6+
let raw: $type;
7+
asm!($ldrex
8+
: "=r"(raw)
9+
: "r"(address)
10+
:
11+
: "volatile");
12+
raw
13+
}
14+
15+
unsafe fn store_excl(self, address: usize) -> bool {
16+
let status: $type;
17+
println!("{}",
18+
status);
19+
status == 0
20+
}
21+
}
22+
};
23+
24+
// the println macro should be rewritten here
25+
($type:ty) => {
26+
fn some_func(self) {
27+
let status: $type;
28+
println!("{}", status);
29+
}
30+
};
31+
32+
// unrewritale macro in func
33+
($type:ty, $ldrex:expr) => {
34+
unsafe fn load_excl(address: usize) -> Self {
35+
let raw: $type;
36+
asm!($ldrex
37+
: "=r"(raw)
38+
: "r"(address)
39+
:
40+
: "volatile");
41+
raw
42+
}
43+
}
44+
}

tests/source/issue-2977/trait.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
macro_rules! atomic_bits {
2+
// the println macro cannot be rewritten because of the asm macro
3+
($type:ty, $ldrex:expr, $strex:expr) => {
4+
trait $type {
5+
unsafe fn load_excl(address: usize) -> Self {
6+
let raw: $type;
7+
asm!($ldrex
8+
: "=r"(raw)
9+
: "r"(address)
10+
:
11+
: "volatile");
12+
raw
13+
}
14+
15+
unsafe fn store_excl(self, address: usize) -> bool {
16+
let status: $type;
17+
println!("{}",
18+
status);
19+
status == 0
20+
}
21+
}
22+
};
23+
24+
// the println macro should be rewritten here
25+
($type:ty) => {
26+
fn some_func(self) {
27+
let status: $type;
28+
println!("{}", status);
29+
}
30+
};
31+
32+
// unrewritale macro in func
33+
($type:ty, $ldrex:expr) => {
34+
unsafe fn load_excl(address: usize) -> Self {
35+
let raw: $type;
36+
asm!($ldrex
37+
: "=r"(raw)
38+
: "r"(address)
39+
:
40+
: "volatile");
41+
raw
42+
}
43+
}
44+
}

tests/target/issue-2977/block.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
macro_rules! atomic_bits {
2+
($ldrex:expr) => {
3+
execute(|| {
4+
asm!($ldrex
5+
: "=r"(raw)
6+
: "r"(address)
7+
:
8+
: "volatile");
9+
})
10+
};
11+
}

tests/target/issue-2977/impl.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
macro_rules! atomic_bits {
2+
// the println macro cannot be rewritten because of the asm macro
3+
($type:ty, $ldrex:expr, $strex:expr) => {
4+
impl AtomicBits for $type {
5+
unsafe fn load_excl(address: usize) -> Self {
6+
let raw: $type;
7+
asm!($ldrex
8+
: "=r"(raw)
9+
: "r"(address)
10+
:
11+
: "volatile");
12+
raw
13+
}
14+
15+
unsafe fn store_excl(self, address: usize) -> bool {
16+
let status: $type;
17+
println!("{}",
18+
status);
19+
status == 0
20+
}
21+
}
22+
};
23+
24+
// the println macro should be rewritten here
25+
($type:ty) => {
26+
fn some_func(self) {
27+
let status: $type;
28+
println!("{}", status);
29+
}
30+
};
31+
32+
// unrewritale macro in func
33+
($type:ty, $ldrex:expr) => {
34+
unsafe fn load_excl(address: usize) -> Self {
35+
let raw: $type;
36+
asm!($ldrex
37+
: "=r"(raw)
38+
: "r"(address)
39+
:
40+
: "volatile");
41+
raw
42+
}
43+
}
44+
}

tests/target/issue-2977/item.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
macro_rules! atomic_bits {
2+
($ldrex:expr) => {
3+
some_macro!(pub fn foo() {
4+
asm!($ldrex
5+
: "=r"(raw)
6+
: "r"(address)
7+
:
8+
: "volatile");
9+
})
10+
};
11+
}

tests/target/issue-2977/trait.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
macro_rules! atomic_bits {
2+
// the println macro cannot be rewritten because of the asm macro
3+
($type:ty, $ldrex:expr, $strex:expr) => {
4+
trait $type {
5+
unsafe fn load_excl(address: usize) -> Self {
6+
let raw: $type;
7+
asm!($ldrex
8+
: "=r"(raw)
9+
: "r"(address)
10+
:
11+
: "volatile");
12+
raw
13+
}
14+
15+
unsafe fn store_excl(self, address: usize) -> bool {
16+
let status: $type;
17+
println!("{}",
18+
status);
19+
status == 0
20+
}
21+
}
22+
};
23+
24+
// the println macro should be rewritten here
25+
($type:ty) => {
26+
fn some_func(self) {
27+
let status: $type;
28+
println!("{}", status);
29+
}
30+
};
31+
32+
// unrewritale macro in func
33+
($type:ty, $ldrex:expr) => {
34+
unsafe fn load_excl(address: usize) -> Self {
35+
let raw: $type;
36+
asm!($ldrex
37+
: "=r"(raw)
38+
: "r"(address)
39+
:
40+
: "volatile");
41+
raw
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)