]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/parse/obsolete.rs
rollup merge of #20642: michaelwoerister/sane-source-locations-pt1
[rust.git] / src / libsyntax / parse / obsolete.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Support for parsing unsupported, old syntaxes, for the purpose of reporting errors. Parsing of
12 //! these syntaxes is tested by compile-test/obsolete-syntax.rs.
13 //!
14 //! Obsolete syntax that becomes too hard to parse can be removed.
15
16 use ast::{Expr, ExprTup};
17 use codemap::Span;
18 use parse::parser;
19 use parse::token;
20 use ptr::P;
21
22 /// The specific types of unsupported syntax
23 #[derive(Copy, PartialEq, Eq, Hash)]
24 pub enum ObsoleteSyntax {
25     Sized,
26     ForSized,
27     ProcType,
28     ProcExpr,
29     ClosureType,
30 }
31
32 pub trait ParserObsoleteMethods {
33     /// Reports an obsolete syntax non-fatal error.
34     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
35     /// Reports an obsolete syntax non-fatal error, and returns
36     /// a placeholder expression
37     fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr>;
38     fn report(&mut self,
39               sp: Span,
40               kind: ObsoleteSyntax,
41               kind_str: &str,
42               desc: &str);
43     fn is_obsolete_ident(&mut self, ident: &str) -> bool;
44     fn eat_obsolete_ident(&mut self, ident: &str) -> bool;
45 }
46
47 impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
48     /// Reports an obsolete syntax non-fatal error.
49     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
50         let (kind_str, desc) = match kind {
51             ObsoleteSyntax::ForSized => (
52                 "for Sized?",
53                 "no longer required. Traits (and their `Self` type) do not have the `Sized` bound \
54                  by default",
55             ),
56             ObsoleteSyntax::ProcType => (
57                 "the `proc` type",
58                 "use unboxed closures instead",
59             ),
60             ObsoleteSyntax::ProcExpr => (
61                 "`proc` expression",
62                 "use a `move ||` expression instead",
63             ),
64             ObsoleteSyntax::ClosureType => (
65                 "`|usize| -> bool` closure type syntax",
66                 "use unboxed closures instead, no type annotation needed"
67             ),
68             ObsoleteSyntax::Sized => (
69                 "`Sized? T` syntax for removing the `Sized` bound",
70                 "write `T: ?Sized` instead"
71             ),
72         };
73
74         self.report(sp, kind, kind_str, desc);
75     }
76
77     /// Reports an obsolete syntax non-fatal error, and returns
78     /// a placeholder expression
79     fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr> {
80         self.obsolete(sp, kind);
81         self.mk_expr(sp.lo, sp.hi, ExprTup(vec![]))
82     }
83
84     fn report(&mut self,
85               sp: Span,
86               kind: ObsoleteSyntax,
87               kind_str: &str,
88               desc: &str) {
89         self.span_err(sp,
90                       &format!("obsolete syntax: {}", kind_str)[]);
91
92         if !self.obsolete_set.contains(&kind) {
93             self.sess
94                 .span_diagnostic
95                 .handler()
96                 .note(&format!("{}", desc)[]);
97             self.obsolete_set.insert(kind);
98         }
99     }
100
101     fn is_obsolete_ident(&mut self, ident: &str) -> bool {
102         match self.token {
103             token::Ident(sid, _) => {
104                 token::get_ident(sid) == ident
105             }
106             _ => false
107         }
108     }
109
110     fn eat_obsolete_ident(&mut self, ident: &str) -> bool {
111         if self.is_obsolete_ident(ident) {
112             self.bump();
113             true
114         } else {
115             false
116         }
117     }
118 }