rustfmt_nightly/
spanned.rs1use std::cmp::max;
2
3use rustc_ast::ast;
4use rustc_span::Span;
5
6use crate::macros::MacroArg;
7use crate::utils::{mk_sp, outer_attributes};
8
9pub(crate) trait Spanned {
11 fn span(&self) -> Span;
12}
13
14impl<T: Spanned> Spanned for Box<T> {
15 fn span(&self) -> Span {
16 (**self).span()
17 }
18}
19
20impl<T> Spanned for rustc_span::Spanned<T> {
21 fn span(&self) -> Span {
22 self.span
23 }
24}
25
26macro_rules! span_with_attrs_lo_hi {
27 ($this:ident, $lo:expr, $hi:expr) => {{
28 let attrs = outer_attributes(&$this.attrs);
29 if attrs.is_empty() {
30 mk_sp($lo, $hi)
31 } else {
32 mk_sp(attrs[0].span.lo(), $hi)
33 }
34 }};
35}
36
37macro_rules! span_with_attrs {
38 ($this:ident) => {
39 span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
40 };
41}
42
43macro_rules! implement_spanned {
44 ($this:ty) => {
45 impl Spanned for $this {
46 fn span(&self) -> Span {
47 span_with_attrs!(self)
48 }
49 }
50 };
51}
52
53implement_spanned!(ast::AssocItem);
55implement_spanned!(ast::Expr);
56implement_spanned!(ast::ExprField);
57implement_spanned!(ast::ForeignItem);
58implement_spanned!(ast::Item);
59implement_spanned!(ast::Local);
60implement_spanned!(ast::WherePredicate);
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 { span, .. } => 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::FnRetTy {
153 fn span(&self) -> Span {
154 match *self {
155 ast::FnRetTy::Default(span) => span,
156 ast::FnRetTy::Ty(ref ty) => ty.span,
157 }
158 }
159}
160
161impl Spanned for ast::GenericArg {
162 fn span(&self) -> Span {
163 match *self {
164 ast::GenericArg::Lifetime(ref lt) => lt.ident.span,
165 ast::GenericArg::Type(ref ty) => ty.span(),
166 ast::GenericArg::Const(ref _const) => _const.value.span(),
167 }
168 }
169}
170
171impl Spanned for ast::GenericBound {
172 fn span(&self) -> Span {
173 match *self {
174 ast::GenericBound::Trait(ref ptr) => ptr.span,
175 ast::GenericBound::Outlives(ref l) => l.ident.span,
176 ast::GenericBound::Use(_, span) => span,
177 }
178 }
179}
180
181impl Spanned for MacroArg {
182 fn span(&self) -> Span {
183 match *self {
184 MacroArg::Expr(ref expr) => expr.span(),
185 MacroArg::Ty(ref ty) => ty.span(),
186 MacroArg::Pat(ref pat) => pat.span(),
187 MacroArg::Item(ref item) => item.span(),
188 MacroArg::Keyword(_, span) => span,
189 }
190 }
191}
192
193impl Spanned for ast::MetaItemInner {
194 fn span(&self) -> Span {
195 self.span()
196 }
197}
198
199impl Spanned for ast::PreciseCapturingArg {
200 fn span(&self) -> Span {
201 match self {
202 ast::PreciseCapturingArg::Lifetime(lt) => lt.ident.span,
203 ast::PreciseCapturingArg::Arg(path, _) => path.span,
204 }
205 }
206}