Skip to content

Commit 77df72a

Browse files
committed
Use a less pervasive workaround for rustc bug
We still have to work around rust-lang/rust#47941 until it gets fixed upstream, but we can at least do it in a way that's less pervasive, and will be easier to remove in the future.
1 parent 14887fc commit 77df72a

File tree

2 files changed

+31
-33
lines changed

2 files changed

+31
-33
lines changed

diesel_derives2/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ homepage = "https://diesel.rs"
99
repository = "https://github.com/diesel-rs/diesel/tree/master/diesel_derives"
1010

1111
[dependencies]
12-
syn = { version = "0.12.0", features = ["full"] }
12+
syn = { version = "0.12.0", features = ["full", "fold"] }
1313
quote = "0.4"
1414
clippy = { optional = true, version = "=0.0.185" }
1515
proc-macro2 = "0.2.0"

diesel_derives2/src/meta.rs

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
use proc_macro2::Span;
22
use syn;
33
use syn::spanned::Spanned;
4+
use syn::fold::Fold;
45

56
use diagnostic_shim::*;
67

78
pub struct MetaItem {
8-
// Due to https://github.com/rust-lang/rust/issues/47941
9-
// we can only ever get the span of the #, which is better than nothing
10-
pound_span: Span,
119
meta: syn::Meta,
1210
}
1311

1412
impl MetaItem {
1513
pub fn with_name<'a>(attrs: &[syn::Attribute], name: &'a str) -> Option<Self> {
1614
attrs
1715
.iter()
18-
.filter_map(|attr| attr.interpret_meta().map(|m| (attr.pound_token.0[0], m)))
19-
.find(|&(_, ref m)| m.name() == name)
20-
.map(|(pound_span, meta)| Self { pound_span, meta })
16+
.filter_map(|attr| {
17+
attr.interpret_meta()
18+
.map(|m| FixSpan(attr.pound_token.0[0]).fold_meta(m))
19+
})
20+
.find(|m| m.name() == name)
21+
.map(|meta| Self { meta })
2122
}
2223

2324
pub fn nested_item<'a>(&self, name: &'a str) -> Result<Self, Diagnostic> {
@@ -76,10 +77,7 @@ impl MetaItem {
7677
use syn::Meta::*;
7778

7879
match self.meta {
79-
Word(mut x) => {
80-
x.span = self.span_or_pound_token(x.span);
81-
Ok(x)
82-
}
80+
Word(x) => Ok(x),
8381
_ => {
8482
let meta = &self.meta;
8583
Err(self.span().error(format!(
@@ -95,7 +93,7 @@ impl MetaItem {
9593
use syn::Meta::*;
9694

9795
match self.meta {
98-
List(ref list) => Ok(Nested(list.nested.iter(), self.pound_span)),
96+
List(ref list) => Ok(Nested(list.nested.iter())),
9997
_ => Err(self.span()
10098
.error(format!("`{0}` must be in the form `{0}(...)`", self.name()))),
10199
}
@@ -131,33 +129,20 @@ impl MetaItem {
131129
fn value_span(&self) -> Span {
132130
use syn::Meta::*;
133131

134-
let s = match self.meta {
132+
match self.meta {
135133
Word(ident) => ident.span,
136134
List(ref meta) => meta.nested.span(),
137135
NameValue(ref meta) => meta.lit.span(),
138-
};
139-
self.span_or_pound_token(s)
136+
}
140137
}
141138

142139
fn span(&self) -> Span {
143-
self.span_or_pound_token(self.meta.span())
144-
}
145-
146-
/// If the given span is affected by
147-
/// https://github.com/rust-lang/rust/issues/47941,
148-
/// returns the span of the pound token
149-
fn span_or_pound_token(&self, span: Span) -> Span {
150-
let bad_span_debug = "Span(Span { lo: BytePos(0), hi: BytePos(0), ctxt: #0 })";
151-
if format!("{:?}", span) == bad_span_debug {
152-
self.pound_span
153-
} else {
154-
span
155-
}
140+
self.meta.span()
156141
}
157142
}
158143

159144
#[cfg_attr(rustfmt, rustfmt_skip)] // https://github.com/rust-lang-nursery/rustfmt/issues/2392
160-
pub struct Nested<'a>(syn::punctuated::Iter<'a, syn::NestedMeta, Token![,]>, Span);
145+
pub struct Nested<'a>(syn::punctuated::Iter<'a, syn::NestedMeta, Token![,]>);
161146

162147
impl<'a> Iterator for Nested<'a> {
163148
type Item = MetaItem;
@@ -166,12 +151,25 @@ impl<'a> Iterator for Nested<'a> {
166151
use syn::NestedMeta::*;
167152

168153
match self.0.next() {
169-
Some(&Meta(ref item)) => Some(MetaItem {
170-
pound_span: self.1,
171-
meta: item.clone(),
172-
}),
154+
Some(&Meta(ref item)) => Some(MetaItem { meta: item.clone() }),
173155
Some(_) => self.next(),
174156
None => None,
175157
}
176158
}
177159
}
160+
161+
/// If the given span is affected by
162+
/// https://github.com/rust-lang/rust/issues/47941,
163+
/// returns the span of the pound token
164+
struct FixSpan(Span);
165+
166+
impl Fold for FixSpan {
167+
fn fold_span(&mut self, span: Span) -> Span {
168+
let bad_span_debug = "Span(Span { lo: BytePos(0), hi: BytePos(0), ctxt: #0 })";
169+
if format!("{:?}", span) == bad_span_debug {
170+
self.0
171+
} else {
172+
span
173+
}
174+
}
175+
}

0 commit comments

Comments
 (0)