rustfmt_nightly/
spanned.rs
1use std::cmp::max;
2
3use rustc_ast::{ast, ptr};
4use rustc_span::{Span, source_map};
5
6use crate::macros::MacroArg;
7use crate::patterns::RangeOperand;
8use crate::utils::{mk_sp, outer_attributes};
9
10pub(crate) trait Spanned {
12 fn span(&self) -> Span;
13}
14
15impl<T: Spanned> Spanned for ptr::P<T> {
16 fn span(&self) -> Span {
17 (**self).span()
18 }
19}
20
21impl<T> Spanned for source_map::Spanned<T> {
22 fn span(&self) -> Span {
23 self.span
24 }
25}
26
27macro_rules! span_with_attrs_lo_hi {
28 ($this:ident, $lo:expr, $hi:expr) => {{
29 let attrs = outer_attributes(&$this.attrs);
30 if attrs.is_empty() {
31 mk_sp($lo, $hi)
32 } else {
33 mk_sp(attrs[0].span.lo(), $hi)
34 }
35 }};
36}
37
38macro_rules! span_with_attrs {
39 ($this:ident) => {
40 span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
41 };
42}
43
44macro_rules! implement_spanned {
45 ($this:ty) => {
46 impl Spanned for $this {
47 fn span(&self) -> Span {
48 span_with_attrs!(self)
49 }
50 }
51 };
52}
53
54implement_spanned!(ast::AssocItem);
56implement_spanned!(ast::Expr);
57implement_spanned!(ast::ExprField);
58implement_spanned!(ast::ForeignItem);
59implement_spanned!(ast::Item);
60implement_spanned!(ast::Local);
61
62impl Spanned for ast::Stmt {
63 fn span(&self) -> Span {
64 match self.kind {
65 ast::StmtKind::Let(ref local) => mk_sp(local.span().lo(), self.span.hi()),
66 ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
67 ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
68 mk_sp(expr.span().lo(), self.span.hi())
69 }
70 ast::StmtKind::MacCall(ref mac_stmt) => {
71 if mac_stmt.attrs.is_empty() {
72 self.span
73 } else {
74 mk_sp(mac_stmt.attrs[0].span.lo(), self.span.hi())
75 }
76 }
77 ast::StmtKind::Empty => self.span,
78 }
79 }
80}
81
82impl Spanned for ast::Pat {
83 fn span(&self) -> Span {
84 self.span
85 }
86}
87
88impl Spanned for ast::Ty {
89 fn span(&self) -> Span {
90 self.span
91 }
92}
93
94impl Spanned for ast::Arm {
95 fn span(&self) -> Span {
96 let lo = if self.attrs.is_empty() {
97 self.pat.span.lo()
98 } else {
99 self.attrs[0].span.lo()
100 };
101 let hi = if let Some(body) = &self.body {
102 body.span.hi()
103 } else {
104 self.pat.span.hi()
105 };
106 span_with_attrs_lo_hi!(self, lo, hi)
107 }
108}
109
110impl Spanned for ast::Param {
111 fn span(&self) -> Span {
112 if crate::items::is_named_param(self) {
113 mk_sp(crate::items::span_lo_for_param(self), self.ty.span.hi())
114 } else {
115 self.ty.span
116 }
117 }
118}
119
120impl Spanned for ast::GenericParam {
121 fn span(&self) -> Span {
122 let lo = match self.kind {
123 _ if !self.attrs.is_empty() => self.attrs[0].span.lo(),
124 ast::GenericParamKind::Const { kw_span, .. } => kw_span.lo(),
125 _ => self.ident.span.lo(),
126 };
127 let hi = if self.bounds.is_empty() {
128 self.ident.span.hi()
129 } else {
130 self.bounds.last().unwrap().span().hi()
131 };
132 let ty_hi = if let ast::GenericParamKind::Type {
133 default: Some(ref ty),
134 }
135 | ast::GenericParamKind::Const { ref ty, .. } = self.kind
136 {
137 ty.span().hi()
138 } else {
139 hi
140 };
141 mk_sp(lo, max(hi, ty_hi))
142 }
143}
144
145impl Spanned for ast::FieldDef {
146 fn span(&self) -> Span {
147 span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
149 }
150}
151
152impl Spanned for ast::WherePredicate {
153 fn span(&self) -> Span {
154 self.span
155 }
156}
157
158impl Spanned for ast::FnRetTy {
159 fn span(&self) -> Span {
160 match *self {
161 ast::FnRetTy::Default(span) => span,
162 ast::FnRetTy::Ty(ref ty) => ty.span,
163 }
164 }
165}
166
167impl Spanned for ast::GenericArg {
168 fn span(&self) -> Span {
169 match *self {
170 ast::GenericArg::Lifetime(ref lt) => lt.ident.span,
171 ast::GenericArg::Type(ref ty) => ty.span(),
172 ast::GenericArg::Const(ref _const) => _const.value.span(),
173 }
174 }
175}
176
177impl Spanned for ast::GenericBound {
178 fn span(&self) -> Span {
179 match *self {
180 ast::GenericBound::Trait(ref ptr) => ptr.span,
181 ast::GenericBound::Outlives(ref l) => l.ident.span,
182 ast::GenericBound::Use(_, span) => span,
183 }
184 }
185}
186
187impl Spanned for MacroArg {
188 fn span(&self) -> Span {
189 match *self {
190 MacroArg::Expr(ref expr) => expr.span(),
191 MacroArg::Ty(ref ty) => ty.span(),
192 MacroArg::Pat(ref pat) => pat.span(),
193 MacroArg::Item(ref item) => item.span(),
194 MacroArg::Keyword(_, span) => span,
195 }
196 }
197}
198
199impl Spanned for ast::MetaItemInner {
200 fn span(&self) -> Span {
201 self.span()
202 }
203}
204
205impl Spanned for ast::PreciseCapturingArg {
206 fn span(&self) -> Span {
207 match self {
208 ast::PreciseCapturingArg::Lifetime(lt) => lt.ident.span,
209 ast::PreciseCapturingArg::Arg(path, _) => path.span,
210 }
211 }
212}
213
214impl<'a, T> Spanned for RangeOperand<'a, T> {
215 fn span(&self) -> Span {
216 self.span
217 }
218}