From eff35e59c698df379806add4c9f2c1d8d3fe55ca Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Thu, 7 Apr 2022 18:06:53 -0700 Subject: [PATCH] Introduce dyn_star feature flag The primary purpose of this commit is to introduce the dyn_star flag so we can begin experimenting with implementation. In order to have something to do in the feature gate test, we also add parser support for `dyn* Trait` objects. These are currently treated just like `dyn Trait` objects, but this will change in the future. Note that for now `dyn* Trait` is experimental syntax to enable implementing some of the machinery needed for async fn in dyn traits without fully supporting the feature. --- compiler/rustc_ast/src/ast.rs | 1 + compiler/rustc_ast_passes/src/ast_validation.rs | 15 ++++++++++++++- compiler/rustc_feature/src/active.rs | 2 ++ compiler/rustc_parse/src/parser/ty.rs | 15 +++++++++++++-- compiler/rustc_span/src/symbol.rs | 1 + src/test/ui/dyn-star/feature-gate-dyn_star.rs | 9 +++++++++ src/test/ui/dyn-star/feature-gate-dyn_star.stderr | 12 ++++++++++++ src/test/ui/dyn-star/syntax.rs | 11 +++++++++++ 8 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/dyn-star/feature-gate-dyn_star.rs create mode 100644 src/test/ui/dyn-star/feature-gate-dyn_star.stderr create mode 100644 src/test/ui/dyn-star/syntax.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3f4911c4ecf..722d7b71c7a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2072,6 +2072,7 @@ impl TyKind { #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum TraitObjectSyntax { Dyn, + DynStar, None, } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 6a0a1b08360..5558f0c8c76 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -19,6 +19,7 @@ use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY, }; use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident}; @@ -753,7 +754,19 @@ impl<'a> AstValidator<'a> { self.maybe_lint_missing_abi(sig_span, ty.id); } } - TyKind::TraitObject(ref bounds, ..) => { + TyKind::TraitObject(ref bounds, syntax, ..) => { + if syntax == TraitObjectSyntax::DynStar + && !self.session.features_untracked().dyn_star + { + feature_err( + &self.session.parse_sess, + sym::dyn_star, + ty.span, + "dyn* trait objects are unstable", + ) + .emit(); + } + let mut any_lifetime_bounds = false; for bound in bounds { if let GenericBound::Outlives(ref lifetime) = *bound { diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 5377ebde168..72f7064b6ca 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -380,6 +380,8 @@ declare_features! ( (active, doc_cfg_hide, "1.57.0", Some(43781), None), /// Allows `#[doc(masked)]`. (active, doc_masked, "1.21.0", Some(44027), None), + /// Allows `dyn* Trait` objects. + (active, dyn_star, "1.65.0", Some(91611), None), /// Allows `X..Y` patterns. (active, exclusive_range_pattern, "1.11.0", Some(37854), None), /// Allows exhaustive pattern matching on types that contain uninhabited types. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 4a2cf74905b..ffe3618bc49 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -567,7 +567,8 @@ impl<'a> Parser<'a> { self.check_keyword(kw::Dyn) && (!self.token.uninterpolated_span().rust_2015() || self.look_ahead(1, |t| { - t.can_begin_bound() && !can_continue_type_after_non_fn_ident(t) + (t.can_begin_bound() || t.kind == TokenKind::BinOp(token::Star)) + && !can_continue_type_after_non_fn_ident(t) })) } @@ -576,10 +577,20 @@ impl<'a> Parser<'a> { /// Note that this does *not* parse bare trait objects. fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> { self.bump(); // `dyn` + + // parse dyn* types + let dyn_star = matches!(self.token.kind, TokenKind::BinOp(token::Star)); + let syntax = if dyn_star { + self.bump(); // `*` + TraitObjectSyntax::DynStar + } else { + TraitObjectSyntax::Dyn + }; + // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds(None)?; *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus); - Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)) + Ok(TyKind::TraitObject(bounds, syntax)) } /// Parses a type starting with a path. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 871bc5c1cdb..aeb535352f6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -649,6 +649,7 @@ symbols! { dropck_parametricity, dylib, dyn_metadata, + dyn_star, dyn_trait, e, edition_macro_pats, diff --git a/src/test/ui/dyn-star/feature-gate-dyn_star.rs b/src/test/ui/dyn-star/feature-gate-dyn_star.rs new file mode 100644 index 00000000000..4756661cf41 --- /dev/null +++ b/src/test/ui/dyn-star/feature-gate-dyn_star.rs @@ -0,0 +1,9 @@ +// Feature gate test for dyn_star + +/// dyn* is not necessarily the final surface syntax (if we have one at all), +/// but for now we will support it to aid in writing tests independently. +pub fn dyn_star_parameter(_: &dyn* Send) { + //~^ dyn* trait objects are unstable +} + +fn main() {} diff --git a/src/test/ui/dyn-star/feature-gate-dyn_star.stderr b/src/test/ui/dyn-star/feature-gate-dyn_star.stderr new file mode 100644 index 00000000000..2767e9478e2 --- /dev/null +++ b/src/test/ui/dyn-star/feature-gate-dyn_star.stderr @@ -0,0 +1,12 @@ +error[E0658]: dyn* trait objects are unstable + --> $DIR/feature-gate-dyn_star.rs:5:31 + | +LL | pub fn dyn_star_parameter(_: &dyn* Send) { + | ^^^^^^^^^ + | + = note: see issue #91611 for more information + = help: add `#![feature(dyn_star)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/dyn-star/syntax.rs b/src/test/ui/dyn-star/syntax.rs new file mode 100644 index 00000000000..dd96bf0672d --- /dev/null +++ b/src/test/ui/dyn-star/syntax.rs @@ -0,0 +1,11 @@ +// Make sure we can parse the `dyn* Trait` syntax +// +// check-pass + + +#![feature(dyn_star)] + +pub fn dyn_star_parameter(_: &dyn* Send) { +} + +fn main() {}