]> git.proxmox.com Git - rustc.git/blame - src/tools/rustfmt/src/spanned.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / src / tools / rustfmt / src / spanned.rs
CommitLineData
f20569fa
XL
1use std::cmp::max;
2
3use rustc_ast::{ast, ptr};
4use rustc_span::{source_map, Span};
5
6use crate::macros::MacroArg;
7use crate::utils::{mk_sp, outer_attributes};
8
9/// Spanned returns a span including attributes, if available.
10pub(crate) trait Spanned {
11 fn span(&self) -> Span;
12}
13
14impl<T: Spanned> Spanned for ptr::P<T> {
15 fn span(&self) -> Span {
16 (**self).span()
17 }
18}
19
20impl<T> Spanned for source_map::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
53// Implement `Spanned` for structs with `attrs` field.
54implement_spanned!(ast::AssocItem);
55implement_spanned!(ast::Expr);
cdc7bbd5 56implement_spanned!(ast::ExprField);
f20569fa
XL
57implement_spanned!(ast::ForeignItem);
58implement_spanned!(ast::Item);
59implement_spanned!(ast::Local);
60
61impl Spanned for ast::Stmt {
62 fn span(&self) -> Span {
63 match self.kind {
64 ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()),
65 ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
66 ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
67 mk_sp(expr.span().lo(), self.span.hi())
68 }
69 ast::StmtKind::MacCall(ref mac_stmt) => {
70 if mac_stmt.attrs.is_empty() {
71 self.span
72 } else {
73 mk_sp(mac_stmt.attrs[0].span.lo(), self.span.hi())
74 }
75 }
76 ast::StmtKind::Empty => self.span,
77 }
78 }
79}
80
81impl Spanned for ast::Pat {
82 fn span(&self) -> Span {
83 self.span
84 }
85}
86
87impl Spanned for ast::Ty {
88 fn span(&self) -> Span {
89 self.span
90 }
91}
92
93impl Spanned for ast::Arm {
94 fn span(&self) -> Span {
95 let lo = if self.attrs.is_empty() {
96 self.pat.span.lo()
97 } else {
98 self.attrs[0].span.lo()
99 };
100 span_with_attrs_lo_hi!(self, lo, self.body.span.hi())
101 }
102}
103
104impl Spanned for ast::Param {
105 fn span(&self) -> Span {
106 if crate::items::is_named_param(self) {
3c0e092e 107 mk_sp(crate::items::span_lo_for_param(self), self.ty.span.hi())
f20569fa
XL
108 } else {
109 self.ty.span
110 }
111 }
112}
113
114impl Spanned for ast::GenericParam {
115 fn span(&self) -> Span {
5e7ed085
FG
116 let lo = match self.kind {
117 _ if !self.attrs.is_empty() => self.attrs[0].span.lo(),
118 ast::GenericParamKind::Const { kw_span, .. } => kw_span.lo(),
119 _ => self.ident.span.lo(),
f20569fa
XL
120 };
121 let hi = if self.bounds.is_empty() {
122 self.ident.span.hi()
123 } else {
124 self.bounds.last().unwrap().span().hi()
125 };
126 let ty_hi = if let ast::GenericParamKind::Type {
127 default: Some(ref ty),
128 }
129 | ast::GenericParamKind::Const { ref ty, .. } = self.kind
130 {
131 ty.span().hi()
132 } else {
133 hi
134 };
135 mk_sp(lo, max(hi, ty_hi))
136 }
137}
138
cdc7bbd5 139impl Spanned for ast::FieldDef {
f20569fa
XL
140 fn span(&self) -> Span {
141 span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
142 }
143}
144
145impl Spanned for ast::WherePredicate {
146 fn span(&self) -> Span {
147 match *self {
148 ast::WherePredicate::BoundPredicate(ref p) => p.span,
149 ast::WherePredicate::RegionPredicate(ref p) => p.span,
150 ast::WherePredicate::EqPredicate(ref p) => p.span,
151 }
152 }
153}
154
155impl Spanned for ast::FnRetTy {
156 fn span(&self) -> Span {
157 match *self {
158 ast::FnRetTy::Default(span) => span,
159 ast::FnRetTy::Ty(ref ty) => ty.span,
160 }
161 }
162}
163
164impl Spanned for ast::GenericArg {
165 fn span(&self) -> Span {
166 match *self {
167 ast::GenericArg::Lifetime(ref lt) => lt.ident.span,
168 ast::GenericArg::Type(ref ty) => ty.span(),
169 ast::GenericArg::Const(ref _const) => _const.value.span(),
170 }
171 }
172}
173
174impl Spanned for ast::GenericBound {
175 fn span(&self) -> Span {
176 match *self {
177 ast::GenericBound::Trait(ref ptr, _) => ptr.span,
178 ast::GenericBound::Outlives(ref l) => l.ident.span,
179 }
180 }
181}
182
183impl Spanned for MacroArg {
184 fn span(&self) -> Span {
185 match *self {
186 MacroArg::Expr(ref expr) => expr.span(),
187 MacroArg::Ty(ref ty) => ty.span(),
188 MacroArg::Pat(ref pat) => pat.span(),
189 MacroArg::Item(ref item) => item.span(),
190 MacroArg::Keyword(_, span) => span,
191 }
192 }
193}
194
195impl Spanned for ast::NestedMetaItem {
196 fn span(&self) -> Span {
197 self.span()
198 }
199}