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.
This commit is contained in:
parent
fa6ee93752
commit
eff35e59c6
8 changed files with 63 additions and 3 deletions
|
@ -2072,6 +2072,7 @@ impl TyKind {
|
||||||
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
pub enum TraitObjectSyntax {
|
pub enum TraitObjectSyntax {
|
||||||
Dyn,
|
Dyn,
|
||||||
|
DynStar,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ use rustc_session::lint::builtin::{
|
||||||
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
|
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||||
};
|
};
|
||||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||||
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::{kw, sym, Ident};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
|
@ -753,7 +754,19 @@ impl<'a> AstValidator<'a> {
|
||||||
self.maybe_lint_missing_abi(sig_span, ty.id);
|
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;
|
let mut any_lifetime_bounds = false;
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
if let GenericBound::Outlives(ref lifetime) = *bound {
|
if let GenericBound::Outlives(ref lifetime) = *bound {
|
||||||
|
|
|
@ -380,6 +380,8 @@ declare_features! (
|
||||||
(active, doc_cfg_hide, "1.57.0", Some(43781), None),
|
(active, doc_cfg_hide, "1.57.0", Some(43781), None),
|
||||||
/// Allows `#[doc(masked)]`.
|
/// Allows `#[doc(masked)]`.
|
||||||
(active, doc_masked, "1.21.0", Some(44027), None),
|
(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.
|
/// Allows `X..Y` patterns.
|
||||||
(active, exclusive_range_pattern, "1.11.0", Some(37854), None),
|
(active, exclusive_range_pattern, "1.11.0", Some(37854), None),
|
||||||
/// Allows exhaustive pattern matching on types that contain uninhabited types.
|
/// Allows exhaustive pattern matching on types that contain uninhabited types.
|
||||||
|
|
|
@ -567,7 +567,8 @@ impl<'a> Parser<'a> {
|
||||||
self.check_keyword(kw::Dyn)
|
self.check_keyword(kw::Dyn)
|
||||||
&& (!self.token.uninterpolated_span().rust_2015()
|
&& (!self.token.uninterpolated_span().rust_2015()
|
||||||
|| self.look_ahead(1, |t| {
|
|| 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.
|
/// Note that this does *not* parse bare trait objects.
|
||||||
fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
|
fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
|
||||||
self.bump(); // `dyn`
|
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.
|
// Always parse bounds greedily for better error recovery.
|
||||||
let bounds = self.parse_generic_bounds(None)?;
|
let bounds = self.parse_generic_bounds(None)?;
|
||||||
*impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
|
*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.
|
/// Parses a type starting with a path.
|
||||||
|
|
|
@ -649,6 +649,7 @@ symbols! {
|
||||||
dropck_parametricity,
|
dropck_parametricity,
|
||||||
dylib,
|
dylib,
|
||||||
dyn_metadata,
|
dyn_metadata,
|
||||||
|
dyn_star,
|
||||||
dyn_trait,
|
dyn_trait,
|
||||||
e,
|
e,
|
||||||
edition_macro_pats,
|
edition_macro_pats,
|
||||||
|
|
9
src/test/ui/dyn-star/feature-gate-dyn_star.rs
Normal file
9
src/test/ui/dyn-star/feature-gate-dyn_star.rs
Normal file
|
@ -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() {}
|
12
src/test/ui/dyn-star/feature-gate-dyn_star.stderr
Normal file
12
src/test/ui/dyn-star/feature-gate-dyn_star.stderr
Normal file
|
@ -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 <https://github.com/rust-lang/rust/issues/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`.
|
11
src/test/ui/dyn-star/syntax.rs
Normal file
11
src/test/ui/dyn-star/syntax.rs
Normal file
|
@ -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() {}
|
Loading…
Add table
Add a link
Reference in a new issue