]> git.lizzy.rs Git - rust.git/blob - src/librustc_ast_passes/ast_validation.rs
parse extern consts
[rust.git] / src / librustc_ast_passes / ast_validation.rs
1 // Validate AST before lowering it to HIR.
2 //
3 // This pass is supposed to catch things that fit into AST data structures,
4 // but not permitted by the language. It runs after expansion when AST is frozen,
5 // so it can check for erroneous constructions produced by syntax extensions.
6 // This pass is supposed to perform only simple checks not requiring name resolution
7 // or type checking or some other kind of complex analysis.
8
9 use rustc_ast_pretty::pprust;
10 use rustc_data_structures::fx::FxHashMap;
11 use rustc_errors::{error_code, struct_span_err, Applicability, FatalError};
12 use rustc_parse::validate_attr;
13 use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
14 use rustc_session::lint::LintBuffer;
15 use rustc_session::Session;
16 use rustc_span::symbol::{kw, sym};
17 use rustc_span::Span;
18 use std::mem;
19 use syntax::ast::*;
20 use syntax::attr;
21 use syntax::expand::is_proc_macro_attr;
22 use syntax::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
23 use syntax::walk_list;
24
25 const MORE_EXTERN: &str =
26     "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
27
28 /// Is `self` allowed semantically as the first parameter in an `FnDecl`?
29 enum SelfSemantic {
30     Yes,
31     No,
32 }
33
34 /// A syntactic context that disallows certain kinds of bounds (e.g., `?Trait` or `?const Trait`).
35 #[derive(Clone, Copy)]
36 enum BoundContext {
37     ImplTrait,
38     TraitBounds,
39     TraitObject,
40 }
41
42 impl BoundContext {
43     fn description(&self) -> &'static str {
44         match self {
45             Self::ImplTrait => "`impl Trait`",
46             Self::TraitBounds => "supertraits",
47             Self::TraitObject => "trait objects",
48         }
49     }
50 }
51
52 struct AstValidator<'a> {
53     session: &'a Session,
54
55     /// The span of the `extern` in an `extern { ... }` block, if any.
56     extern_mod: Option<&'a Item>,
57
58     /// Are we inside a trait impl?
59     in_trait_impl: bool,
60
61     has_proc_macro_decls: bool,
62
63     /// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
64     /// Nested `impl Trait` _is_ allowed in associated type position,
65     /// e.g., `impl Iterator<Item = impl Debug>`.
66     outer_impl_trait: Option<Span>,
67
68     /// Keeps track of the `BoundContext` as we recurse.
69     ///
70     /// This is used to forbid `?const Trait` bounds in, e.g.,
71     /// `impl Iterator<Item = Box<dyn ?const Trait>`.
72     bound_context: Option<BoundContext>,
73
74     /// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
75     /// or `Foo::Bar<impl Trait>`
76     is_impl_trait_banned: bool,
77
78     /// Used to ban associated type bounds (i.e., `Type<AssocType: Bounds>`) in
79     /// certain positions.
80     is_assoc_ty_bound_banned: bool,
81
82     lint_buffer: &'a mut LintBuffer,
83 }
84
85 impl<'a> AstValidator<'a> {
86     fn with_in_trait_impl(&mut self, is_in: bool, f: impl FnOnce(&mut Self)) {
87         let old = mem::replace(&mut self.in_trait_impl, is_in);
88         f(self);
89         self.in_trait_impl = old;
90     }
91
92     fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
93         let old = mem::replace(&mut self.is_impl_trait_banned, true);
94         f(self);
95         self.is_impl_trait_banned = old;
96     }
97
98     fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) {
99         let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true);
100         f(self);
101         self.is_assoc_ty_bound_banned = old;
102     }
103
104     fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
105         let old = mem::replace(&mut self.outer_impl_trait, outer);
106         if outer.is_some() {
107             self.with_bound_context(BoundContext::ImplTrait, |this| f(this));
108         } else {
109             f(self)
110         }
111         self.outer_impl_trait = old;
112     }
113
114     fn with_bound_context(&mut self, ctx: BoundContext, f: impl FnOnce(&mut Self)) {
115         let old = self.bound_context.replace(ctx);
116         f(self);
117         self.bound_context = old;
118     }
119
120     fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) {
121         match constraint.kind {
122             AssocTyConstraintKind::Equality { .. } => {}
123             AssocTyConstraintKind::Bound { .. } => {
124                 if self.is_assoc_ty_bound_banned {
125                     self.err_handler().span_err(
126                         constraint.span,
127                         "associated type bounds are not allowed within structs, enums, or unions",
128                     );
129                 }
130             }
131         }
132         self.visit_assoc_ty_constraint(constraint);
133     }
134
135     // Mirrors `visit::walk_ty`, but tracks relevant state.
136     fn walk_ty(&mut self, t: &'a Ty) {
137         match t.kind {
138             TyKind::ImplTrait(..) => {
139                 self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
140             }
141             TyKind::TraitObject(..) => {
142                 self.with_bound_context(BoundContext::TraitObject, |this| visit::walk_ty(this, t));
143             }
144             TyKind::Path(ref qself, ref path) => {
145                 // We allow these:
146                 //  - `Option<impl Trait>`
147                 //  - `option::Option<impl Trait>`
148                 //  - `option::Option<T>::Foo<impl Trait>
149                 //
150                 // But not these:
151                 //  - `<impl Trait>::Foo`
152                 //  - `option::Option<impl Trait>::Foo`.
153                 //
154                 // To implement this, we disallow `impl Trait` from `qself`
155                 // (for cases like `<impl Trait>::Foo>`)
156                 // but we allow `impl Trait` in `GenericArgs`
157                 // iff there are no more PathSegments.
158                 if let Some(ref qself) = *qself {
159                     // `impl Trait` in `qself` is always illegal
160                     self.with_banned_impl_trait(|this| this.visit_ty(&qself.ty));
161                 }
162
163                 // Note that there should be a call to visit_path here,
164                 // so if any logic is added to process `Path`s a call to it should be
165                 // added both in visit_path and here. This code mirrors visit::walk_path.
166                 for (i, segment) in path.segments.iter().enumerate() {
167                     // Allow `impl Trait` iff we're on the final path segment
168                     if i == path.segments.len() - 1 {
169                         self.visit_path_segment(path.span, segment);
170                     } else {
171                         self.with_banned_impl_trait(|this| {
172                             this.visit_path_segment(path.span, segment)
173                         });
174                     }
175                 }
176             }
177             _ => visit::walk_ty(self, t),
178         }
179     }
180
181     fn err_handler(&self) -> &rustc_errors::Handler {
182         &self.session.diagnostic()
183     }
184
185     fn check_lifetime(&self, ident: Ident) {
186         let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Invalid];
187         if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() {
188             self.err_handler().span_err(ident.span, "lifetimes cannot use keyword names");
189         }
190     }
191
192     fn check_label(&self, ident: Ident) {
193         if ident.without_first_quote().is_reserved() {
194             self.err_handler()
195                 .span_err(ident.span, &format!("invalid label name `{}`", ident.name));
196         }
197     }
198
199     fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) {
200         if let VisibilityKind::Inherited = vis.node {
201             return;
202         }
203
204         let mut err =
205             struct_span_err!(self.session, vis.span, E0449, "unnecessary visibility qualifier");
206         if vis.node.is_pub() {
207             err.span_label(vis.span, "`pub` not permitted here because it's implied");
208         }
209         if let Some(note) = note {
210             err.note(note);
211         }
212         err.emit();
213     }
214
215     fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, bool)) {
216         for Param { pat, .. } in &decl.inputs {
217             match pat.kind {
218                 PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, None) | PatKind::Wild => {}
219                 PatKind::Ident(BindingMode::ByValue(Mutability::Mut), _, None) => {
220                     report_err(pat.span, true)
221                 }
222                 _ => report_err(pat.span, false),
223             }
224         }
225     }
226
227     fn check_trait_fn_not_async(&self, fn_span: Span, asyncness: Async) {
228         if let Async::Yes { span, .. } = asyncness {
229             struct_span_err!(
230                 self.session,
231                 fn_span,
232                 E0706,
233                 "functions in traits cannot be declared `async`"
234             )
235             .span_label(span, "`async` because of this")
236             .note("`async` trait functions are not currently supported")
237             .note("consider using the `async-trait` crate: https://crates.io/crates/async-trait")
238             .emit();
239         }
240     }
241
242     fn check_trait_fn_not_const(&self, constness: Const) {
243         if let Const::Yes(span) = constness {
244             struct_span_err!(
245                 self.session,
246                 span,
247                 E0379,
248                 "functions in traits cannot be declared const"
249             )
250             .span_label(span, "functions in traits cannot be const")
251             .emit();
252         }
253     }
254
255     // FIXME(ecstaticmorse): Instead, use `bound_context` to check this in `visit_param_bound`.
256     fn no_questions_in_bounds(&self, bounds: &GenericBounds, where_: &str, is_trait: bool) {
257         for bound in bounds {
258             if let GenericBound::Trait(ref poly, TraitBoundModifier::Maybe) = *bound {
259                 let mut err = self.err_handler().struct_span_err(
260                     poly.span,
261                     &format!("`?Trait` is not permitted in {}", where_),
262                 );
263                 if is_trait {
264                     let path_str = pprust::path_to_string(&poly.trait_ref.path);
265                     err.note(&format!("traits are `?{}` by default", path_str));
266                 }
267                 err.emit();
268             }
269         }
270     }
271
272     /// Matches `'-' lit | lit (cf. parser::Parser::parse_literal_maybe_minus)`,
273     /// or paths for ranges.
274     //
275     // FIXME: do we want to allow `expr -> pattern` conversion to create path expressions?
276     // That means making this work:
277     //
278     // ```rust,ignore (FIXME)
279     // struct S;
280     // macro_rules! m {
281     //     ($a:expr) => {
282     //         let $a = S;
283     //     }
284     // }
285     // m!(S);
286     // ```
287     fn check_expr_within_pat(&self, expr: &Expr, allow_paths: bool) {
288         match expr.kind {
289             ExprKind::Lit(..) | ExprKind::Err => {}
290             ExprKind::Path(..) if allow_paths => {}
291             ExprKind::Unary(UnOp::Neg, ref inner)
292                 if match inner.kind {
293                     ExprKind::Lit(_) => true,
294                     _ => false,
295                 } => {}
296             _ => self.err_handler().span_err(
297                 expr.span,
298                 "arbitrary expressions aren't allowed \
299                                                          in patterns",
300             ),
301         }
302     }
303
304     fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) {
305         // Check only lifetime parameters are present and that the lifetime
306         // parameters that are present have no bounds.
307         let non_lt_param_spans: Vec<_> = params
308             .iter()
309             .filter_map(|param| match param.kind {
310                 GenericParamKind::Lifetime { .. } => {
311                     if !param.bounds.is_empty() {
312                         let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
313                         self.err_handler()
314                             .span_err(spans, "lifetime bounds cannot be used in this context");
315                     }
316                     None
317                 }
318                 _ => Some(param.ident.span),
319             })
320             .collect();
321         if !non_lt_param_spans.is_empty() {
322             self.err_handler().span_err(
323                 non_lt_param_spans,
324                 "only lifetime parameters can be used in this context",
325             );
326         }
327     }
328
329     fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
330         self.check_decl_cvaradic_pos(fn_decl);
331         self.check_decl_attrs(fn_decl);
332         self.check_decl_self_param(fn_decl, self_semantic);
333     }
334
335     fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
336         match &*fn_decl.inputs {
337             [Param { ty, span, .. }] => {
338                 if let TyKind::CVarArgs = ty.kind {
339                     self.err_handler().span_err(
340                         *span,
341                         "C-variadic function must be declared with at least one named argument",
342                     );
343                 }
344             }
345             [ps @ .., _] => {
346                 for Param { ty, span, .. } in ps {
347                     if let TyKind::CVarArgs = ty.kind {
348                         self.err_handler().span_err(
349                             *span,
350                             "`...` must be the last argument of a C-variadic function",
351                         );
352                     }
353                 }
354             }
355             _ => {}
356         }
357     }
358
359     fn check_decl_attrs(&self, fn_decl: &FnDecl) {
360         fn_decl
361             .inputs
362             .iter()
363             .flat_map(|i| i.attrs.as_ref())
364             .filter(|attr| {
365                 let arr = [sym::allow, sym::cfg, sym::cfg_attr, sym::deny, sym::forbid, sym::warn];
366                 !arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(attr)
367             })
368             .for_each(|attr| {
369                 if attr.is_doc_comment() {
370                     self.err_handler()
371                         .struct_span_err(
372                             attr.span,
373                             "documentation comments cannot be applied to function parameters",
374                         )
375                         .span_label(attr.span, "doc comments are not allowed here")
376                         .emit();
377                 } else {
378                     self.err_handler().span_err(
379                         attr.span,
380                         "allow, cfg, cfg_attr, deny, \
381                 forbid, and warn are the only allowed built-in attributes in function parameters",
382                     )
383                 }
384             });
385     }
386
387     fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
388         if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) {
389             if param.is_self() {
390                 self.err_handler()
391                     .struct_span_err(
392                         param.span,
393                         "`self` parameter is only allowed in associated functions",
394                     )
395                     .span_label(param.span, "not semantically valid as function parameter")
396                     .note("associated functions are those in `impl` or `trait` definitions")
397                     .emit();
398             }
399         }
400     }
401
402     fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
403         if let Defaultness::Default = defaultness {
404             self.err_handler()
405                 .struct_span_err(span, "`default` is only allowed on items in `impl` definitions")
406                 .emit();
407         }
408     }
409
410     fn error_item_without_body(&self, sp: Span, ctx: &str, msg: &str, sugg: &str) {
411         self.err_handler()
412             .struct_span_err(sp, msg)
413             .span_suggestion(
414                 self.session.source_map().end_point(sp),
415                 &format!("provide a definition for the {}", ctx),
416                 sugg.to_string(),
417                 Applicability::HasPlaceholders,
418             )
419             .emit();
420     }
421
422     fn check_impl_item_provided<T>(&self, sp: Span, body: &Option<T>, ctx: &str, sugg: &str) {
423         if body.is_none() {
424             let msg = format!("associated {} in `impl` without body", ctx);
425             self.error_item_without_body(sp, ctx, &msg, sugg);
426         }
427     }
428
429     fn check_type_no_bounds(&self, bounds: &[GenericBound], ctx: &str) {
430         let span = match bounds {
431             [] => return,
432             [b0] => b0.span(),
433             [b0, .., bl] => b0.span().to(bl.span()),
434         };
435         self.err_handler()
436             .struct_span_err(span, &format!("bounds on `type`s in {} have no effect", ctx))
437             .emit();
438     }
439
440     fn check_foreign_ty_genericless(&self, generics: &Generics) {
441         let cannot_have = |span, descr, remove_descr| {
442             self.err_handler()
443                 .struct_span_err(
444                     span,
445                     &format!("`type`s inside `extern` blocks cannot have {}", descr),
446                 )
447                 .span_suggestion(
448                     span,
449                     &format!("remove the {}", remove_descr),
450                     String::new(),
451                     Applicability::MaybeIncorrect,
452                 )
453                 .span_label(self.current_extern_span(), "`extern` block begins here")
454                 .note(MORE_EXTERN)
455                 .emit();
456         };
457
458         if !generics.params.is_empty() {
459             cannot_have(generics.span, "generic parameters", "generic parameters");
460         }
461
462         if !generics.where_clause.predicates.is_empty() {
463             cannot_have(generics.where_clause.span, "`where` clauses", "`where` clause");
464         }
465     }
466
467     fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
468         let body = match body {
469             None => return,
470             Some(body) => body,
471         };
472         self.err_handler()
473             .struct_span_err(ident.span, &format!("incorrect `{}` inside `extern` block", kind))
474             .span_label(ident.span, "cannot have a body")
475             .span_label(body, "the invalid body")
476             .span_label(
477                 self.current_extern_span(),
478                 format!(
479                     "`extern` blocks define existing foreign {0}s and {0}s \
480                     inside of them cannot have a body",
481                     kind
482                 ),
483             )
484             .note(MORE_EXTERN)
485             .emit();
486     }
487
488     /// An `fn` in `extern { ... }` cannot have a body `{ ... }`.
489     fn check_foreign_fn_bodyless(&self, ident: Ident, body: Option<&Block>) {
490         let body = match body {
491             None => return,
492             Some(body) => body,
493         };
494         self.err_handler()
495             .struct_span_err(ident.span, "incorrect function inside `extern` block")
496             .span_label(ident.span, "cannot have a body")
497             .span_suggestion(
498                 body.span,
499                 "remove the invalid body",
500                 ";".to_string(),
501                 Applicability::MaybeIncorrect,
502             )
503             .help(
504                 "you might have meant to write a function accessible through FFI, \
505                 which can be done by writing `extern fn` outside of the `extern` block",
506             )
507             .span_label(
508                 self.current_extern_span(),
509                 "`extern` blocks define existing foreign functions and functions \
510                 inside of them cannot have a body",
511             )
512             .note(MORE_EXTERN)
513             .emit();
514     }
515
516     fn current_extern_span(&self) -> Span {
517         self.session.source_map().def_span(self.extern_mod.unwrap().span)
518     }
519
520     /// An `fn` in `extern { ... }` cannot have qualfiers, e.g. `async fn`.
521     fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) {
522         if header.has_qualifiers() {
523             self.err_handler()
524                 .struct_span_err(ident.span, "functions in `extern` blocks cannot have qualifiers")
525                 .span_label(self.current_extern_span(), "in this `extern` block")
526                 .span_suggestion(
527                     span.until(ident.span.shrink_to_lo()),
528                     "remove the qualifiers",
529                     "fn ".to_string(),
530                     Applicability::MaybeIncorrect,
531                 )
532                 .emit();
533         }
534     }
535
536     fn error_foreign_const(&self, ident: Ident, span: Span) {
537         self.err_handler()
538             .struct_span_err(ident.span, "extern items cannot be `const`")
539             .span_suggestion(
540                 span.with_hi(ident.span.lo()),
541                 "try using a static value",
542                 "static ".to_string(),
543                 Applicability::MachineApplicable,
544             )
545             .span_label(self.current_extern_span(), "in this `extern` block")
546             .note(MORE_EXTERN)
547             .emit();
548     }
549
550     /// Reject C-varadic type unless the function is foreign,
551     /// or free and `unsafe extern "C"` semantically.
552     fn check_c_varadic_type(&self, fk: FnKind<'a>) {
553         match (fk.ctxt(), fk.header()) {
554             (Some(FnCtxt::Foreign), _) => return,
555             (Some(FnCtxt::Free), Some(header)) => match header.ext {
556                 Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }) | Extern::Implicit
557                     if matches!(header.unsafety, Unsafe::Yes(_)) =>
558                 {
559                     return;
560                 }
561                 _ => {}
562             },
563             _ => {}
564         };
565
566         for Param { ty, span, .. } in &fk.decl().inputs {
567             if let TyKind::CVarArgs = ty.kind {
568                 self.err_handler()
569                     .struct_span_err(
570                         *span,
571                         "only foreign or `unsafe extern \"C\" functions may be C-variadic",
572                     )
573                     .emit();
574             }
575         }
576     }
577
578     /// We currently do not permit const generics in `const fn`,
579     /// as this is tantamount to allowing compile-time dependent typing.
580     ///
581     /// FIXME(const_generics): Is this really true / necessary? Discuss with @varkor.
582     /// At any rate, the restriction feels too syntactic. Consider moving it to e.g. typeck.
583     fn check_const_fn_const_generic(&self, span: Span, sig: &FnSig, generics: &Generics) {
584         if let Const::Yes(const_span) = sig.header.constness {
585             // Look for const generics and error if we find any.
586             for param in &generics.params {
587                 if let GenericParamKind::Const { .. } = param.kind {
588                     self.err_handler()
589                         .struct_span_err(
590                             span,
591                             "const parameters are not permitted in const functions",
592                         )
593                         .span_label(const_span, "`const` because of this")
594                         .emit();
595                 }
596             }
597         }
598     }
599
600     fn check_item_named(&self, ident: Ident, kind: &str) {
601         if ident.name != kw::Underscore {
602             return;
603         }
604         self.err_handler()
605             .struct_span_err(ident.span, &format!("`{}` items in this context need a name", kind))
606             .span_label(ident.span, format!("`_` is not a valid name for this `{}` item", kind))
607             .emit();
608     }
609 }
610
611 enum GenericPosition {
612     Param,
613     Arg,
614 }
615
616 fn validate_generics_order<'a>(
617     sess: &Session,
618     handler: &rustc_errors::Handler,
619     generics: impl Iterator<Item = (ParamKindOrd, Option<&'a [GenericBound]>, Span, Option<String>)>,
620     pos: GenericPosition,
621     span: Span,
622 ) {
623     let mut max_param: Option<ParamKindOrd> = None;
624     let mut out_of_order = FxHashMap::default();
625     let mut param_idents = vec![];
626     let mut found_type = false;
627     let mut found_const = false;
628
629     for (kind, bounds, span, ident) in generics {
630         if let Some(ident) = ident {
631             param_idents.push((kind, bounds, param_idents.len(), ident));
632         }
633         let max_param = &mut max_param;
634         match max_param {
635             Some(max_param) if *max_param > kind => {
636                 let entry = out_of_order.entry(kind).or_insert((*max_param, vec![]));
637                 entry.1.push(span);
638             }
639             Some(_) | None => *max_param = Some(kind),
640         };
641         match kind {
642             ParamKindOrd::Type => found_type = true,
643             ParamKindOrd::Const => found_const = true,
644             _ => {}
645         }
646     }
647
648     let mut ordered_params = "<".to_string();
649     if !out_of_order.is_empty() {
650         param_idents.sort_by_key(|&(po, _, i, _)| (po, i));
651         let mut first = true;
652         for (_, bounds, _, ident) in param_idents {
653             if !first {
654                 ordered_params += ", ";
655             }
656             ordered_params += &ident;
657             if let Some(bounds) = bounds {
658                 if !bounds.is_empty() {
659                     ordered_params += ": ";
660                     ordered_params += &pprust::bounds_to_string(&bounds);
661                 }
662             }
663             first = false;
664         }
665     }
666     ordered_params += ">";
667
668     let pos_str = match pos {
669         GenericPosition::Param => "parameter",
670         GenericPosition::Arg => "argument",
671     };
672
673     for (param_ord, (max_param, spans)) in &out_of_order {
674         let mut err = handler.struct_span_err(
675             spans.clone(),
676             &format!(
677                 "{} {pos}s must be declared prior to {} {pos}s",
678                 param_ord,
679                 max_param,
680                 pos = pos_str,
681             ),
682         );
683         if let GenericPosition::Param = pos {
684             err.span_suggestion(
685                 span,
686                 &format!(
687                     "reorder the {}s: lifetimes, then types{}",
688                     pos_str,
689                     if sess.features_untracked().const_generics { ", then consts" } else { "" },
690                 ),
691                 ordered_params.clone(),
692                 Applicability::MachineApplicable,
693             );
694         }
695         err.emit();
696     }
697
698     // FIXME(const_generics): we shouldn't have to abort here at all, but we currently get ICEs
699     // if we don't. Const parameters and type parameters can currently conflict if they
700     // are out-of-order.
701     if !out_of_order.is_empty() && found_type && found_const {
702         FatalError.raise();
703     }
704 }
705
706 impl<'a> Visitor<'a> for AstValidator<'a> {
707     fn visit_attribute(&mut self, attr: &Attribute) {
708         validate_attr::check_meta(&self.session.parse_sess, attr);
709     }
710
711     fn visit_expr(&mut self, expr: &'a Expr) {
712         match &expr.kind {
713             ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => {
714                 struct_span_err!(
715                     self.session,
716                     expr.span,
717                     E0472,
718                     "asm! is unsupported on this target"
719                 )
720                 .emit();
721             }
722             _ => {}
723         }
724
725         visit::walk_expr(self, expr);
726     }
727
728     fn visit_ty(&mut self, ty: &'a Ty) {
729         match ty.kind {
730             TyKind::BareFn(ref bfty) => {
731                 self.check_fn_decl(&bfty.decl, SelfSemantic::No);
732                 Self::check_decl_no_pat(&bfty.decl, |span, _| {
733                     struct_span_err!(
734                         self.session,
735                         span,
736                         E0561,
737                         "patterns aren't allowed in function pointer types"
738                     )
739                     .emit();
740                 });
741                 self.check_late_bound_lifetime_defs(&bfty.generic_params);
742             }
743             TyKind::TraitObject(ref bounds, ..) => {
744                 let mut any_lifetime_bounds = false;
745                 for bound in bounds {
746                     if let GenericBound::Outlives(ref lifetime) = *bound {
747                         if any_lifetime_bounds {
748                             struct_span_err!(
749                                 self.session,
750                                 lifetime.ident.span,
751                                 E0226,
752                                 "only a single explicit lifetime bound is permitted"
753                             )
754                             .emit();
755                             break;
756                         }
757                         any_lifetime_bounds = true;
758                     }
759                 }
760                 self.no_questions_in_bounds(bounds, "trait object types", false);
761             }
762             TyKind::ImplTrait(_, ref bounds) => {
763                 if self.is_impl_trait_banned {
764                     struct_span_err!(
765                         self.session,
766                         ty.span,
767                         E0667,
768                         "`impl Trait` is not allowed in path parameters"
769                     )
770                     .emit();
771                 }
772
773                 if let Some(outer_impl_trait_sp) = self.outer_impl_trait {
774                     struct_span_err!(
775                         self.session,
776                         ty.span,
777                         E0666,
778                         "nested `impl Trait` is not allowed"
779                     )
780                     .span_label(outer_impl_trait_sp, "outer `impl Trait`")
781                     .span_label(ty.span, "nested `impl Trait` here")
782                     .emit();
783                 }
784
785                 if !bounds
786                     .iter()
787                     .any(|b| if let GenericBound::Trait(..) = *b { true } else { false })
788                 {
789                     self.err_handler().span_err(ty.span, "at least one trait must be specified");
790                 }
791
792                 self.walk_ty(ty);
793                 return;
794             }
795             _ => {}
796         }
797
798         self.walk_ty(ty)
799     }
800
801     fn visit_label(&mut self, label: &'a Label) {
802         self.check_label(label.ident);
803         visit::walk_label(self, label);
804     }
805
806     fn visit_lifetime(&mut self, lifetime: &'a Lifetime) {
807         self.check_lifetime(lifetime.ident);
808         visit::walk_lifetime(self, lifetime);
809     }
810
811     fn visit_item(&mut self, item: &'a Item) {
812         if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) {
813             self.has_proc_macro_decls = true;
814         }
815
816         match item.kind {
817             ItemKind::Impl {
818                 unsafety,
819                 polarity,
820                 defaultness: _,
821                 constness: _,
822                 generics: _,
823                 of_trait: Some(_),
824                 ref self_ty,
825                 items: _,
826             } => {
827                 self.with_in_trait_impl(true, |this| {
828                     this.invalid_visibility(&item.vis, None);
829                     if let TyKind::Err = self_ty.kind {
830                         this.err_handler()
831                             .struct_span_err(
832                                 item.span,
833                                 "`impl Trait for .. {}` is an obsolete syntax",
834                             )
835                             .help("use `auto trait Trait {}` instead")
836                             .emit();
837                     }
838                     if let (Unsafe::Yes(span), ImplPolarity::Negative) = (unsafety, polarity) {
839                         struct_span_err!(
840                             this.session,
841                             item.span,
842                             E0198,
843                             "negative impls cannot be unsafe"
844                         )
845                         .span_label(span, "unsafe because of this")
846                         .emit();
847                     }
848
849                     visit::walk_item(this, item);
850                 });
851                 return; // Avoid visiting again.
852             }
853             ItemKind::Impl {
854                 unsafety,
855                 polarity,
856                 defaultness,
857                 constness,
858                 generics: _,
859                 of_trait: None,
860                 self_ty: _,
861                 items: _,
862             } => {
863                 self.invalid_visibility(
864                     &item.vis,
865                     Some("place qualifiers on individual impl items instead"),
866                 );
867                 if let Unsafe::Yes(span) = unsafety {
868                     struct_span_err!(
869                         self.session,
870                         item.span,
871                         E0197,
872                         "inherent impls cannot be unsafe"
873                     )
874                     .span_label(span, "unsafe because of this")
875                     .emit();
876                 }
877                 if polarity == ImplPolarity::Negative {
878                     self.err_handler().span_err(item.span, "inherent impls cannot be negative");
879                 }
880                 if defaultness == Defaultness::Default {
881                     self.err_handler()
882                         .struct_span_err(item.span, "inherent impls cannot be default")
883                         .note("only trait implementations may be annotated with default")
884                         .emit();
885                 }
886                 if let Const::Yes(span) = constness {
887                     self.err_handler()
888                         .struct_span_err(item.span, "inherent impls cannot be `const`")
889                         .span_label(span, "`const` because of this")
890                         .note("only trait implementations may be annotated with `const`")
891                         .emit();
892                 }
893             }
894             ItemKind::Fn(ref sig, ref generics, ref body) => {
895                 self.check_const_fn_const_generic(item.span, sig, generics);
896
897                 if body.is_none() {
898                     let msg = "free function without a body";
899                     self.error_item_without_body(item.span, "function", msg, " { <body> }");
900                 }
901             }
902             ItemKind::ForeignMod(_) => {
903                 let old_item = mem::replace(&mut self.extern_mod, Some(item));
904                 self.invalid_visibility(
905                     &item.vis,
906                     Some("place qualifiers on individual foreign items instead"),
907                 );
908                 visit::walk_item(self, item);
909                 self.extern_mod = old_item;
910                 return; // Avoid visiting again.
911             }
912             ItemKind::Enum(ref def, _) => {
913                 for variant in &def.variants {
914                     self.invalid_visibility(&variant.vis, None);
915                     for field in variant.data.fields() {
916                         self.invalid_visibility(&field.vis, None);
917                     }
918                 }
919             }
920             ItemKind::Trait(is_auto, _, ref generics, ref bounds, ref trait_items) => {
921                 if is_auto == IsAuto::Yes {
922                     // Auto traits cannot have generics, super traits nor contain items.
923                     if !generics.params.is_empty() {
924                         struct_span_err!(
925                             self.session,
926                             item.span,
927                             E0567,
928                             "auto traits cannot have generic parameters"
929                         )
930                         .emit();
931                     }
932                     if !bounds.is_empty() {
933                         struct_span_err!(
934                             self.session,
935                             item.span,
936                             E0568,
937                             "auto traits cannot have super traits"
938                         )
939                         .emit();
940                     }
941                     if !trait_items.is_empty() {
942                         struct_span_err!(
943                             self.session,
944                             item.span,
945                             E0380,
946                             "auto traits cannot have methods or associated items"
947                         )
948                         .emit();
949                     }
950                 }
951                 self.no_questions_in_bounds(bounds, "supertraits", true);
952
953                 // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
954                 // context for the supertraits.
955                 self.visit_vis(&item.vis);
956                 self.visit_ident(item.ident);
957                 self.visit_generics(generics);
958                 self.with_bound_context(BoundContext::TraitBounds, |this| {
959                     walk_list!(this, visit_param_bound, bounds);
960                 });
961                 walk_list!(self, visit_assoc_item, trait_items, AssocCtxt::Trait);
962                 walk_list!(self, visit_attribute, &item.attrs);
963                 return;
964             }
965             ItemKind::Mod(_) => {
966                 // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
967                 attr::first_attr_value_str_by_name(&item.attrs, sym::path);
968             }
969             ItemKind::Union(ref vdata, _) => {
970                 if let VariantData::Tuple(..) | VariantData::Unit(..) = vdata {
971                     self.err_handler()
972                         .span_err(item.span, "tuple and unit unions are not permitted");
973                 }
974                 if vdata.fields().is_empty() {
975                     self.err_handler().span_err(item.span, "unions cannot have zero fields");
976                 }
977             }
978             ItemKind::Const(.., None) => {
979                 let msg = "free constant item without body";
980                 self.error_item_without_body(item.span, "constant", msg, " = <expr>;");
981             }
982             ItemKind::Static(.., None) => {
983                 let msg = "free static item without body";
984                 self.error_item_without_body(item.span, "static", msg, " = <expr>;");
985             }
986             _ => {}
987         }
988
989         visit::walk_item(self, item)
990     }
991
992     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
993         match &fi.kind {
994             ForeignItemKind::Fn(sig, _, body) => {
995                 self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
996                 self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
997             }
998             ForeignItemKind::TyAlias(generics, bounds, body) => {
999                 self.check_foreign_kind_bodyless(fi.ident, "type", body.as_ref().map(|b| b.span));
1000                 self.check_type_no_bounds(bounds, "`extern` blocks");
1001                 self.check_foreign_ty_genericless(generics);
1002             }
1003             ForeignItemKind::Static(_, _, body) => {
1004                 self.check_foreign_kind_bodyless(fi.ident, "static", body.as_ref().map(|b| b.span));
1005             }
1006             ForeignItemKind::Const(..) => {
1007                 self.error_foreign_const(fi.ident, fi.span);
1008             }
1009             ForeignItemKind::Macro(..) => {}
1010         }
1011
1012         visit::walk_foreign_item(self, fi)
1013     }
1014
1015     // Mirrors `visit::walk_generic_args`, but tracks relevant state.
1016     fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) {
1017         match *generic_args {
1018             GenericArgs::AngleBracketed(ref data) => {
1019                 walk_list!(self, visit_generic_arg, &data.args);
1020                 validate_generics_order(
1021                     self.session,
1022                     self.err_handler(),
1023                     data.args.iter().map(|arg| {
1024                         (
1025                             match arg {
1026                                 GenericArg::Lifetime(..) => ParamKindOrd::Lifetime,
1027                                 GenericArg::Type(..) => ParamKindOrd::Type,
1028                                 GenericArg::Const(..) => ParamKindOrd::Const,
1029                             },
1030                             None,
1031                             arg.span(),
1032                             None,
1033                         )
1034                     }),
1035                     GenericPosition::Arg,
1036                     generic_args.span(),
1037                 );
1038
1039                 // Type bindings such as `Item = impl Debug` in `Iterator<Item = Debug>`
1040                 // are allowed to contain nested `impl Trait`.
1041                 self.with_impl_trait(None, |this| {
1042                     walk_list!(
1043                         this,
1044                         visit_assoc_ty_constraint_from_generic_args,
1045                         &data.constraints
1046                     );
1047                 });
1048             }
1049             GenericArgs::Parenthesized(ref data) => {
1050                 walk_list!(self, visit_ty, &data.inputs);
1051                 if let FunctionRetTy::Ty(ty) = &data.output {
1052                     // `-> Foo` syntax is essentially an associated type binding,
1053                     // so it is also allowed to contain nested `impl Trait`.
1054                     self.with_impl_trait(None, |this| this.visit_ty(ty));
1055                 }
1056             }
1057         }
1058     }
1059
1060     fn visit_generics(&mut self, generics: &'a Generics) {
1061         let mut prev_ty_default = None;
1062         for param in &generics.params {
1063             if let GenericParamKind::Type { ref default, .. } = param.kind {
1064                 if default.is_some() {
1065                     prev_ty_default = Some(param.ident.span);
1066                 } else if let Some(span) = prev_ty_default {
1067                     self.err_handler()
1068                         .span_err(span, "type parameters with a default must be trailing");
1069                     break;
1070                 }
1071             }
1072         }
1073
1074         validate_generics_order(
1075             self.session,
1076             self.err_handler(),
1077             generics.params.iter().map(|param| {
1078                 let ident = Some(param.ident.to_string());
1079                 let (kind, ident) = match &param.kind {
1080                     GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, ident),
1081                     GenericParamKind::Type { .. } => (ParamKindOrd::Type, ident),
1082                     GenericParamKind::Const { ref ty } => {
1083                         let ty = pprust::ty_to_string(ty);
1084                         (ParamKindOrd::Const, Some(format!("const {}: {}", param.ident, ty)))
1085                     }
1086                 };
1087                 (kind, Some(&*param.bounds), param.ident.span, ident)
1088             }),
1089             GenericPosition::Param,
1090             generics.span,
1091         );
1092
1093         for predicate in &generics.where_clause.predicates {
1094             if let WherePredicate::EqPredicate(ref predicate) = *predicate {
1095                 self.err_handler()
1096                     .struct_span_err(
1097                         predicate.span,
1098                         "equality constraints are not yet supported in `where` clauses",
1099                     )
1100                     .span_label(predicate.span, "not supported")
1101                     .note(
1102                         "see issue #20041 <https://github.com/rust-lang/rust/issues/20041> \
1103                          for more information",
1104                     )
1105                     .emit();
1106             }
1107         }
1108
1109         visit::walk_generics(self, generics)
1110     }
1111
1112     fn visit_generic_param(&mut self, param: &'a GenericParam) {
1113         if let GenericParamKind::Lifetime { .. } = param.kind {
1114             self.check_lifetime(param.ident);
1115         }
1116         visit::walk_generic_param(self, param);
1117     }
1118
1119     fn visit_param_bound(&mut self, bound: &'a GenericBound) {
1120         match bound {
1121             GenericBound::Trait(_, TraitBoundModifier::MaybeConst) => {
1122                 if let Some(ctx) = self.bound_context {
1123                     let msg = format!("`?const` is not permitted in {}", ctx.description());
1124                     self.err_handler().span_err(bound.span(), &msg);
1125                 }
1126             }
1127
1128             GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
1129                 self.err_handler()
1130                     .span_err(bound.span(), "`?const` and `?` are mutually exclusive");
1131             }
1132
1133             _ => {}
1134         }
1135
1136         visit::walk_param_bound(self, bound)
1137     }
1138
1139     fn visit_pat(&mut self, pat: &'a Pat) {
1140         match pat.kind {
1141             PatKind::Lit(ref expr) => {
1142                 self.check_expr_within_pat(expr, false);
1143             }
1144             PatKind::Range(ref start, ref end, _) => {
1145                 if let Some(expr) = start {
1146                     self.check_expr_within_pat(expr, true);
1147                 }
1148                 if let Some(expr) = end {
1149                     self.check_expr_within_pat(expr, true);
1150                 }
1151             }
1152             _ => {}
1153         }
1154
1155         visit::walk_pat(self, pat)
1156     }
1157
1158     fn visit_where_predicate(&mut self, p: &'a WherePredicate) {
1159         if let &WherePredicate::BoundPredicate(ref bound_predicate) = p {
1160             // A type binding, eg `for<'c> Foo: Send+Clone+'c`
1161             self.check_late_bound_lifetime_defs(&bound_predicate.bound_generic_params);
1162         }
1163         visit::walk_where_predicate(self, p);
1164     }
1165
1166     fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef, m: &'a TraitBoundModifier) {
1167         self.check_late_bound_lifetime_defs(&t.bound_generic_params);
1168         visit::walk_poly_trait_ref(self, t, m);
1169     }
1170
1171     fn visit_variant_data(&mut self, s: &'a VariantData) {
1172         self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s))
1173     }
1174
1175     fn visit_enum_def(
1176         &mut self,
1177         enum_definition: &'a EnumDef,
1178         generics: &'a Generics,
1179         item_id: NodeId,
1180         _: Span,
1181     ) {
1182         self.with_banned_assoc_ty_bound(|this| {
1183             visit::walk_enum_def(this, enum_definition, generics, item_id)
1184         })
1185     }
1186
1187     fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
1188         // Only associated `fn`s can have `self` parameters.
1189         let self_semantic = match fk.ctxt() {
1190             Some(FnCtxt::Assoc(_)) => SelfSemantic::Yes,
1191             _ => SelfSemantic::No,
1192         };
1193         self.check_fn_decl(fk.decl(), self_semantic);
1194
1195         self.check_c_varadic_type(fk);
1196
1197         // Functions cannot both be `const async`
1198         if let Some(FnHeader {
1199             constness: Const::Yes(cspan),
1200             asyncness: Async::Yes { span: aspan, .. },
1201             ..
1202         }) = fk.header()
1203         {
1204             self.err_handler()
1205                 .struct_span_err(span, "functions cannot be both `const` and `async`")
1206                 .span_label(*cspan, "`const` because of this")
1207                 .span_label(*aspan, "`async` because of this")
1208                 .emit();
1209         }
1210
1211         // Functions without bodies cannot have patterns.
1212         if let FnKind::Fn(ctxt, _, sig, _, None) = fk {
1213             Self::check_decl_no_pat(&sig.decl, |span, mut_ident| {
1214                 let (code, msg, label) = match ctxt {
1215                     FnCtxt::Foreign => (
1216                         error_code!(E0130),
1217                         "patterns aren't allowed in foreign function declarations",
1218                         "pattern not allowed in foreign function",
1219                     ),
1220                     _ => (
1221                         error_code!(E0642),
1222                         "patterns aren't allowed in functions without bodies",
1223                         "pattern not allowed in function without body",
1224                     ),
1225                 };
1226                 if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) {
1227                     self.lint_buffer.buffer_lint(PATTERNS_IN_FNS_WITHOUT_BODY, id, span, msg);
1228                 } else {
1229                     self.err_handler()
1230                         .struct_span_err(span, msg)
1231                         .span_label(span, label)
1232                         .code(code)
1233                         .emit();
1234                 }
1235             });
1236         }
1237
1238         visit::walk_fn(self, fk, span);
1239     }
1240
1241     fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
1242         if ctxt == AssocCtxt::Trait {
1243             self.check_defaultness(item.span, item.defaultness);
1244         }
1245
1246         if ctxt == AssocCtxt::Impl {
1247             match &item.kind {
1248                 AssocItemKind::Const(_, body) => {
1249                     self.check_impl_item_provided(item.span, body, "constant", " = <expr>;");
1250                 }
1251                 AssocItemKind::Fn(_, _, body) => {
1252                     self.check_impl_item_provided(item.span, body, "function", " { <body> }");
1253                 }
1254                 AssocItemKind::TyAlias(_, bounds, body) => {
1255                     self.check_impl_item_provided(item.span, body, "type", " = <type>;");
1256                     self.check_type_no_bounds(bounds, "`impl`s");
1257                 }
1258                 _ => {}
1259             }
1260         }
1261
1262         if ctxt == AssocCtxt::Trait || self.in_trait_impl {
1263             self.invalid_visibility(&item.vis, None);
1264             if let AssocItemKind::Fn(sig, _, _) = &item.kind {
1265                 self.check_trait_fn_not_const(sig.header.constness);
1266                 self.check_trait_fn_not_async(item.span, sig.header.asyncness);
1267             }
1268         }
1269
1270         match item.kind {
1271             AssocItemKind::Const(..) => self.check_item_named(item.ident, "const"),
1272             AssocItemKind::Static(..) => self
1273                 .err_handler()
1274                 .struct_span_err(item.span, "associated `static` items are not allowed")
1275                 .emit(),
1276             _ => {}
1277         }
1278
1279         self.with_in_trait_impl(false, |this| visit::walk_assoc_item(this, item, ctxt));
1280     }
1281 }
1282
1283 pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
1284     let mut validator = AstValidator {
1285         session,
1286         extern_mod: None,
1287         in_trait_impl: false,
1288         has_proc_macro_decls: false,
1289         outer_impl_trait: None,
1290         bound_context: None,
1291         is_impl_trait_banned: false,
1292         is_assoc_ty_bound_banned: false,
1293         lint_buffer: lints,
1294     };
1295     visit::walk_crate(&mut validator, krate);
1296
1297     validator.has_proc_macro_decls
1298 }