rustfmt_nightly/
spanned.rs1use 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);
61implement_spanned!(ast::WherePredicate);
62
63impl Spanned for ast::Stmt {
64 fn span(&self) -> Span {
65 match self.kind {
66 ast::StmtKind::Let(ref local) => mk_sp(local.span().lo(), self.span.hi()),
67 ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
68 ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
69 mk_sp(expr.span().lo(), self.span.hi())
70 }
71 ast::StmtKind::MacCall(ref mac_stmt) => {
72 if mac_stmt.attrs.is_empty() {
73 self.span
74 } else {
75 mk_sp(mac_stmt.attrs[0].span.lo(), self.span.hi())
76 }
77 }
78 ast::StmtKind::Empty => self.span,
79 }
80 }
81}
82
83impl Spanned for ast::Pat {
84 fn span(&self) -> Span {
85 self.span
86 }
87}
88
89impl Spanned for ast::Ty {
90 fn span(&self) -> Span {
91 self.span
92 }
93}
94
95impl Spanned for ast::Arm {
96 fn span(&self) -> Span {
97 let lo = if self.attrs.is_empty() {
98 self.pat.span.lo()
99 } else {
100 self.attrs[0].span.lo()
101 };
102 let hi = if let Some(body) = &self.body {
103 body.span.hi()
104 } else {
105 self.pat.span.hi()
106 };
107 span_with_attrs_lo_hi!(self, lo, hi)
108 }
109}
110
111impl Spanned for ast::Param {
112 fn span(&self) -> Span {
113 if crate::items::is_named_param(self) {
114 mk_sp(crate::items::span_lo_for_param(self), self.ty.span.hi())
115 } else {
116 self.ty.span
117 }
118 }
119}
120
121impl Spanned for ast::GenericParam {
122 fn span(&self) -> Span {
123 let lo = match self.kind {
124 _ if !self.attrs.is_empty() => self.attrs[0].span.lo(),
125 ast::GenericParamKind::Const { kw_span, .. } => kw_span.lo(),
126 _ => self.ident.span.lo(),
127 };
128 let hi = if self.bounds.is_empty() {
129 self.ident.span.hi()
130 } else {
131 self.bounds.last().unwrap().span().hi()
132 };
133 let ty_hi = if let ast::GenericParamKind::Type {
134 default: Some(ref ty),
135 }
136 | ast::GenericParamKind::Const { ref ty, .. } = self.kind
137 {
138 ty.span().hi()
139 } else {
140 hi
141 };
142 mk_sp(lo, max(hi, ty_hi))
143 }
144}
145
146impl Spanned for ast::FieldDef {
147 fn span(&self) -> Span {
148 span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
150 }
151}
152
153impl Spanned for ast::FnRetTy {
154 fn span(&self) -> Span {
155 match *self {
156 ast::FnRetTy::Default(span) => span,
157 ast::FnRetTy::Ty(ref ty) => ty.span,
158 }
159 }
160}
161
162impl Spanned for ast::GenericArg {
163 fn span(&self) -> Span {
164 match *self {
165 ast::GenericArg::Lifetime(ref lt) => lt.ident.span,
166 ast::GenericArg::Type(ref ty) => ty.span(),
167 ast::GenericArg::Const(ref _const) => _const.value.span(),
168 }
169 }
170}
171
172impl Spanned for ast::GenericBound {
173 fn span(&self) -> Span {
174 match *self {
175 ast::GenericBound::Trait(ref ptr) => ptr.span,
176 ast::GenericBound::Outlives(ref l) => l.ident.span,
177 ast::GenericBound::Use(_, span) => span,
178 }
179 }
180}
181
182impl Spanned for MacroArg {
183 fn span(&self) -> Span {
184 match *self {
185 MacroArg::Expr(ref expr) => expr.span(),
186 MacroArg::Ty(ref ty) => ty.span(),
187 MacroArg::Pat(ref pat) => pat.span(),
188 MacroArg::Item(ref item) => item.span(),
189 MacroArg::Keyword(_, span) => span,
190 }
191 }
192}
193
194impl Spanned for ast::MetaItemInner {
195 fn span(&self) -> Span {
196 self.span()
197 }
198}
199
200impl Spanned for ast::PreciseCapturingArg {
201 fn span(&self) -> Span {
202 match self {
203 ast::PreciseCapturingArg::Lifetime(lt) => lt.ident.span,
204 ast::PreciseCapturingArg::Arg(path, _) => path.span,
205 }
206 }
207}
208
209impl<'a, T> Spanned for RangeOperand<'a, T> {
210 fn span(&self) -> Span {
211 self.span
212 }
213}