]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/parse/obsolete.rs
auto merge of #13967 : richo/rust/features/ICE-fails, r=alexcrichton
[rust.git] / src / libsyntax / parse / obsolete.rs
1 // Copyright 2012 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 /*!
12 Support for parsing unsupported, old syntaxes, for the
13 purpose of reporting errors. Parsing of these syntaxes
14 is tested by compile-test/obsolete-syntax.rs.
15
16 Obsolete syntax that becomes too hard to parse can be
17 removed.
18 */
19
20 use ast::{Expr, ExprLit, LitNil};
21 use codemap::{Span, respan};
22 use parse::parser::Parser;
23 use parse::token;
24
25 /// The specific types of unsupported syntax
26 #[deriving(Eq, TotalEq, Hash)]
27 pub enum ObsoleteSyntax {
28     ObsoleteSwap,
29     ObsoleteUnsafeBlock,
30     ObsoleteBareFnType,
31     ObsoleteMultipleLocalDecl,
32     ObsoleteUnsafeExternFn,
33     ObsoleteTraitFuncVisibility,
34     ObsoleteConstPointer,
35     ObsoleteLoopAsContinue,
36     ObsoleteEnumWildcard,
37     ObsoleteStructWildcard,
38     ObsoleteVecDotDotWildcard,
39     ObsoleteMultipleImport,
40     ObsoleteManagedPattern,
41     ObsoleteManagedString,
42     ObsoleteManagedVec,
43     ObsoleteOwnedType,
44     ObsoleteOwnedExpr,
45     ObsoleteOwnedPattern,
46 }
47
48 pub trait ParserObsoleteMethods {
49     /// Reports an obsolete syntax non-fatal error.
50     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
51     // Reports an obsolete syntax non-fatal error, and returns
52     // a placeholder expression
53     fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr;
54     fn report(&mut self,
55               sp: Span,
56               kind: ObsoleteSyntax,
57               kind_str: &str,
58               desc: &str);
59     fn is_obsolete_ident(&mut self, ident: &str) -> bool;
60     fn eat_obsolete_ident(&mut self, ident: &str) -> bool;
61 }
62
63 impl<'a> ParserObsoleteMethods for Parser<'a> {
64     /// Reports an obsolete syntax non-fatal error.
65     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
66         let (kind_str, desc) = match kind {
67             ObsoleteSwap => (
68                 "swap",
69                 "use std::mem::{swap, replace} instead"
70             ),
71             ObsoleteUnsafeBlock => (
72                 "non-standalone unsafe block",
73                 "use an inner `unsafe { ... }` block instead"
74             ),
75             ObsoleteBareFnType => (
76                 "bare function type",
77                 "use `|A| -> B` or `extern fn(A) -> B` instead"
78             ),
79             ObsoleteMultipleLocalDecl => (
80                 "declaration of multiple locals at once",
81                 "instead of e.g. `let a = 1, b = 2`, write \
82                  `let (a, b) = (1, 2)`."
83             ),
84             ObsoleteUnsafeExternFn => (
85                 "unsafe external function",
86                 "external functions are always unsafe; remove the `unsafe` \
87                  keyword"
88             ),
89             ObsoleteTraitFuncVisibility => (
90                 "visibility not necessary",
91                 "trait functions inherit the visibility of the trait itself"
92             ),
93             ObsoleteConstPointer => (
94                 "const pointer",
95                 "instead of `&const Foo` or `@const Foo`, write `&Foo` or \
96                  `@Foo`"
97             ),
98             ObsoleteLoopAsContinue => (
99                 "`loop` instead of `continue`",
100                 "`loop` is now only used for loops and `continue` is used for \
101                  skipping iterations"
102             ),
103             ObsoleteEnumWildcard => (
104                 "enum wildcard",
105                 "use `..` instead of `*` for matching all enum fields"
106             ),
107             ObsoleteStructWildcard => (
108                 "struct wildcard",
109                 "use `..` instead of `_` for matching trailing struct fields"
110             ),
111             ObsoleteVecDotDotWildcard => (
112                 "vec slice wildcard",
113                 "use `..` instead of `.._` for matching slices"
114             ),
115             ObsoleteMultipleImport => (
116                 "multiple imports",
117                 "only one import is allowed per `use` statement"
118             ),
119             ObsoleteManagedPattern => (
120                 "managed pointer pattern",
121                 "use a nested `match` expression instead of a managed box \
122                  pattern"
123             ),
124             ObsoleteManagedString => (
125                 "managed string",
126                 "use `Rc<~str>` instead of a managed string"
127             ),
128             ObsoleteManagedVec => (
129                 "managed vector",
130                 "use `Rc<~[T]>` instead of a managed vector"
131             ),
132             ObsoleteOwnedType => (
133                 "`~` notation for owned pointers",
134                 "use `Box<T>` in `std::owned` instead"
135             ),
136             ObsoleteOwnedExpr => (
137                 "`~` notation for owned pointer allocation",
138                 "use the `box` operator instead of `~`"
139             ),
140             ObsoleteOwnedPattern => (
141                 "`~` notation for owned pointer patterns",
142                 "use the `box` operator instead of `~`"
143             ),
144         };
145
146         self.report(sp, kind, kind_str, desc);
147     }
148
149     // Reports an obsolete syntax non-fatal error, and returns
150     // a placeholder expression
151     fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr {
152         self.obsolete(sp, kind);
153         self.mk_expr(sp.lo, sp.hi, ExprLit(@respan(sp, LitNil)))
154     }
155
156     fn report(&mut self,
157               sp: Span,
158               kind: ObsoleteSyntax,
159               kind_str: &str,
160               desc: &str) {
161         self.span_err(sp, format!("obsolete syntax: {}", kind_str));
162
163         if !self.obsolete_set.contains(&kind) {
164             self.sess.span_diagnostic.handler().note(format!("{}", desc));
165             self.obsolete_set.insert(kind);
166         }
167     }
168
169     fn is_obsolete_ident(&mut self, ident: &str) -> bool {
170         match self.token {
171             token::IDENT(sid, _) => {
172                 token::get_ident(sid).equiv(&ident)
173             }
174             _ => false
175         }
176     }
177
178     fn eat_obsolete_ident(&mut self, ident: &str) -> bool {
179         if self.is_obsolete_ident(ident) {
180             self.bump();
181             true
182         } else {
183             false
184         }
185     }
186 }