From acf50ee236abae0ad416360eda2a3afa8873d2a0 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Thu, 12 Oct 2017 19:00:30 -0300 Subject: [PATCH] Add tests for `auto trait`, fix parsing bug Now we can do the well formedness checks in the parser, yay! --- src/libsyntax/feature_gate.rs | 2 +- src/libsyntax/parse/parser.rs | 62 +++++++++---------- src/test/compile-fail/auto-is-contextual.rs | 29 +++++++++ .../feature-gate-optin-builtin-traits.rs | 3 + src/test/parse-fail/auto-trait-no-generics.rs | 14 +++++ src/test/parse-fail/auto-trait-no-rename.rs | 14 +++++ src/test/parse-fail/auto-trait-no-super.rs | 14 +++++ src/test/run-pass/auto-traits.rs | 35 +++++++++++ 8 files changed, 141 insertions(+), 32 deletions(-) create mode 100644 src/test/compile-fail/auto-is-contextual.rs create mode 100644 src/test/parse-fail/auto-trait-no-generics.rs create mode 100644 src/test/parse-fail/auto-trait-no-rename.rs create mode 100644 src/test/parse-fail/auto-trait-no-super.rs create mode 100644 src/test/run-pass/auto-traits.rs diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9aee2441a9d..e354d56f5af 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1394,7 +1394,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { i.span, "auto traits are experimental and possibly buggy"); } - + ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => { let msg = "`macro` is experimental"; gate_feature_post!(&self, decl_macro, i.span, msg); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c94fcf461c7..1376102568b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6014,6 +6014,37 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return Ok(Some(item)); } + if self.eat_keyword(keywords::Auto) { + self.expect_keyword(keywords::Trait)?; + // AUTO TRAIT ITEM + let (ident, + item_, + extra_attrs) = self.parse_item_auto_trait(ast::Unsafety::Normal)?; + let prev_span = self.prev_span; + let item = self.mk_item(lo.to(prev_span), + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return Ok(Some(item)); + } + if self.check_keyword(keywords::Unsafe) && + self.look_ahead(1, |t| t.is_keyword(keywords::Auto)) { + self.expect_keyword(keywords::Unsafe)?; + self.expect_keyword(keywords::Auto)?; + self.expect_keyword(keywords::Trait)?; + // UNSAFE AUTO TRAIT ITEM + let (ident, + item_, + extra_attrs) = self.parse_item_auto_trait(ast::Unsafety::Unsafe)?; + let prev_span = self.prev_span; + let item = self.mk_item(lo.to(prev_span), + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return Ok(Some(item)); + } if (self.check_keyword(keywords::Unsafe) && self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) || (self.check_keyword(keywords::Default) && @@ -6138,37 +6169,6 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return Ok(Some(item)); } - if self.eat_keyword(keywords::Auto) { - self.expect_keyword(keywords::Trait)?; - // AUTO TRAIT ITEM - let (ident, - item_, - extra_attrs) = self.parse_item_auto_trait(ast::Unsafety::Normal)?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); - } - if self.check_keyword(keywords::Unsafe) && - self.look_ahead(1, |t| t.is_keyword(keywords::Auto)) { - self.expect_keyword(keywords::Unsafe)?; - self.expect_keyword(keywords::Auto)?; - self.expect_keyword(keywords::Trait)?; - // UNSAFE AUTO TRAIT ITEM - let (ident, - item_, - extra_attrs) = self.parse_item_auto_trait(ast::Unsafety::Unsafe)?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); - } if self.eat_keyword(keywords::Struct) { // STRUCT ITEM let (ident, item_, extra_attrs) = self.parse_item_struct()?; diff --git a/src/test/compile-fail/auto-is-contextual.rs b/src/test/compile-fail/auto-is-contextual.rs new file mode 100644 index 00000000000..3d3cb9ab104 --- /dev/null +++ b/src/test/compile-fail/auto-is-contextual.rs @@ -0,0 +1,29 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +type A0 = auto; +//~^ ERROR cannot find type `auto` in this scope +type A1 = auto::auto; +//~^ ERROR Use of undeclared type or module `auto` +type A2 = auto; +//~^ ERROR cannot find type `auto` in this scope +//~| ERROR cannot find type `auto` in this scope +//~| ERROR cannot find type `auto` in this scope +type A3 = auto<::auto>; +//~^ ERROR cannot find type `auto` in this scope +//~| ERROR cannot find type `auto` in this scope +//~| ERROR Use of undeclared type or module `auto` +type A4 = auto(auto, auto) -> auto; +//~^ ERROR cannot find type `auto` in this scope +//~| ERROR cannot find type `auto` in this scope +//~| ERROR cannot find type `auto` in this scope +//~| ERROR cannot find type `auto` in this scope + +fn main() {} diff --git a/src/test/compile-fail/feature-gate-optin-builtin-traits.rs b/src/test/compile-fail/feature-gate-optin-builtin-traits.rs index db6b30c06d8..6f57266b3e1 100644 --- a/src/test/compile-fail/feature-gate-optin-builtin-traits.rs +++ b/src/test/compile-fail/feature-gate-optin-builtin-traits.rs @@ -17,6 +17,9 @@ trait DummyTrait { fn dummy(&self) {} } +auto trait AutoDummyTrait {} +//~^ ERROR auto traits are experimental and possibly buggy + impl DummyTrait for .. {} //~^ ERROR auto trait implementations are experimental and possibly buggy diff --git a/src/test/parse-fail/auto-trait-no-generics.rs b/src/test/parse-fail/auto-trait-no-generics.rs new file mode 100644 index 00000000000..59c88691bb6 --- /dev/null +++ b/src/test/parse-fail/auto-trait-no-generics.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +auto trait Auto { } +//~^ ERROR: expected `{`, found `<` diff --git a/src/test/parse-fail/auto-trait-no-rename.rs b/src/test/parse-fail/auto-trait-no-rename.rs new file mode 100644 index 00000000000..2754546779d --- /dev/null +++ b/src/test/parse-fail/auto-trait-no-rename.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +auto trait Auto { fn item() } +//~^ ERROR: expected `}`, found `fn` diff --git a/src/test/parse-fail/auto-trait-no-super.rs b/src/test/parse-fail/auto-trait-no-super.rs new file mode 100644 index 00000000000..bc0d9c1aa09 --- /dev/null +++ b/src/test/parse-fail/auto-trait-no-super.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +auto trait Auto : Send { } +//~^ ERROR: expected `{`, found `:` diff --git a/src/test/run-pass/auto-traits.rs b/src/test/run-pass/auto-traits.rs new file mode 100644 index 00000000000..94fa104e5b2 --- /dev/null +++ b/src/test/run-pass/auto-traits.rs @@ -0,0 +1,35 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(optin_builtin_traits)] + +auto trait Auto {} +// Redundant but accepted until we remove it. +impl Auto for .. {} + +unsafe auto trait AutoUnsafe {} + +impl !Auto for bool {} +impl !AutoUnsafe for bool {} + +struct AutoBool(bool); + +impl Auto for AutoBool {} +unsafe impl AutoUnsafe for AutoBool {} + +fn take_auto(_: T) {} +fn take_auto_unsafe(_: T) {} + +fn main() { + take_auto(0); + take_auto(AutoBool(true)); + take_auto_unsafe(0); + take_auto_unsafe(AutoBool(true)); +}