And additionally enforce ? and async/const aren't mixed
This commit is contained in:
parent
898ed2ffa6
commit
de88bc5c89
@ -152,8 +152,6 @@ ast_passes_impl_trait_path = `impl Trait` is not allowed in path parameters
|
|||||||
ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
|
ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
|
||||||
.help = remove one of these features
|
.help = remove one of these features
|
||||||
|
|
||||||
ast_passes_incompatible_trait_bound_modifiers = `{$left}` and `{$right}` are mutually exclusive
|
|
||||||
|
|
||||||
ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
|
ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
|
||||||
.because = {$annotation} because of this
|
.because = {$annotation} because of this
|
||||||
.type = inherent impl for this type
|
.type = inherent impl for this type
|
||||||
|
@ -1435,17 +1435,6 @@ fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
|
|||||||
};
|
};
|
||||||
self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
|
self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
|
||||||
}
|
}
|
||||||
(
|
|
||||||
_,
|
|
||||||
BoundConstness::Always(_) | BoundConstness::Maybe(_),
|
|
||||||
BoundPolarity::Negative(_) | BoundPolarity::Maybe(_),
|
|
||||||
) => {
|
|
||||||
self.dcx().emit_err(errors::IncompatibleTraitBoundModifiers {
|
|
||||||
span: bound.span(),
|
|
||||||
left: modifiers.constness.as_str(),
|
|
||||||
right: modifiers.polarity.as_str(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,15 +657,6 @@ pub enum TildeConstReason {
|
|||||||
Item,
|
Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(ast_passes_incompatible_trait_bound_modifiers)]
|
|
||||||
pub struct IncompatibleTraitBoundModifiers {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub left: &'static str,
|
|
||||||
pub right: &'static str,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_const_and_async)]
|
#[diag(ast_passes_const_and_async)]
|
||||||
pub struct ConstAndAsync {
|
pub struct ConstAndAsync {
|
||||||
|
@ -575,6 +575,9 @@ parse_missing_trait_in_trait_impl = missing trait in a trait impl
|
|||||||
parse_modifier_lifetime = `{$modifier}` may only modify trait bounds, not lifetime bounds
|
parse_modifier_lifetime = `{$modifier}` may only modify trait bounds, not lifetime bounds
|
||||||
.suggestion = remove the `{$modifier}`
|
.suggestion = remove the `{$modifier}`
|
||||||
|
|
||||||
|
parse_modifiers_and_polarity = `{$modifiers_concatenated}` trait not allowed with `{$polarity}` trait polarity modifier
|
||||||
|
.label = there is not a well-defined meaning for a `{$modifiers_concatenated} {$polarity}` trait
|
||||||
|
|
||||||
parse_more_than_one_char = character literal may only contain one codepoint
|
parse_more_than_one_char = character literal may only contain one codepoint
|
||||||
.followed_by = this `{$chr}` is followed by the combining {$len ->
|
.followed_by = this `{$chr}` is followed by the combining {$len ->
|
||||||
[one] mark
|
[one] mark
|
||||||
|
@ -3060,3 +3060,14 @@ pub struct BinderAndPolarity {
|
|||||||
pub binder_span: Span,
|
pub binder_span: Span,
|
||||||
pub polarity: &'static str,
|
pub polarity: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_modifiers_and_polarity)]
|
||||||
|
pub struct PolarityAndModifiers {
|
||||||
|
#[primary_span]
|
||||||
|
pub polarity_span: Span,
|
||||||
|
#[label]
|
||||||
|
pub modifiers_span: Span,
|
||||||
|
pub polarity: &'static str,
|
||||||
|
pub modifiers_concatenated: String,
|
||||||
|
}
|
||||||
|
@ -930,6 +930,7 @@ fn recover_paren_lifetime(&mut self, lo: Span, lt_span: Span) -> PResult<'a, ()>
|
|||||||
/// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["async"] ["?" | "!"]
|
/// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["async"] ["?" | "!"]
|
||||||
/// ```
|
/// ```
|
||||||
fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
|
fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
|
||||||
|
let modifier_lo = self.token.span;
|
||||||
let constness = if self.eat(&token::Tilde) {
|
let constness = if self.eat(&token::Tilde) {
|
||||||
let tilde = self.prev_token.span;
|
let tilde = self.prev_token.span;
|
||||||
self.expect_keyword(kw::Const)?;
|
self.expect_keyword(kw::Const)?;
|
||||||
@ -962,6 +963,7 @@ fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
|
|||||||
} else {
|
} else {
|
||||||
BoundAsyncness::Normal
|
BoundAsyncness::Normal
|
||||||
};
|
};
|
||||||
|
let modifier_hi = self.prev_token.span;
|
||||||
|
|
||||||
let polarity = if self.eat(&token::Question) {
|
let polarity = if self.eat(&token::Question) {
|
||||||
BoundPolarity::Maybe(self.prev_token.span)
|
BoundPolarity::Maybe(self.prev_token.span)
|
||||||
@ -972,6 +974,33 @@ fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
|
|||||||
BoundPolarity::Positive
|
BoundPolarity::Positive
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Enforce the mutual-exclusivity of `const`/`async` and `?`/`!`.
|
||||||
|
match polarity {
|
||||||
|
BoundPolarity::Positive => {
|
||||||
|
// All trait bound modifiers allowed to combine with positive polarity
|
||||||
|
}
|
||||||
|
BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => {
|
||||||
|
match (asyncness, constness) {
|
||||||
|
(BoundAsyncness::Normal, BoundConstness::Never) => {
|
||||||
|
// Ok, no modifiers.
|
||||||
|
}
|
||||||
|
(_, _) => {
|
||||||
|
let constness = constness.as_str();
|
||||||
|
let asyncness = asyncness.as_str();
|
||||||
|
let glue =
|
||||||
|
if !constness.is_empty() && !asyncness.is_empty() { " " } else { "" };
|
||||||
|
let modifiers_concatenated = format!("{constness}{glue}{asyncness}");
|
||||||
|
self.dcx().emit_err(errors::PolarityAndModifiers {
|
||||||
|
polarity_span,
|
||||||
|
polarity: polarity.as_str(),
|
||||||
|
modifiers_span: modifier_lo.to(modifier_hi),
|
||||||
|
modifiers_concatenated,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(TraitBoundModifiers { constness, asyncness, polarity })
|
Ok(TraitBoundModifiers { constness, asyncness, polarity })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//@ compile-flags: -Z parse-only
|
//@ compile-flags: -Z parse-only
|
||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
struct S<
|
struct S<
|
||||||
T: 'a + Tr, // OK
|
T: 'a + Tr, // OK
|
||||||
@ -10,10 +11,20 @@ struct S<
|
|||||||
T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds
|
T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds
|
||||||
|
|
||||||
T: ~const Tr, // OK
|
T: ~const Tr, // OK
|
||||||
T: ~const ?Tr, // OK
|
T: ~const ?Tr, //~ ERROR `~const` trait not allowed with `?` trait polarity modifier
|
||||||
T: ~const Tr + 'a, // OK
|
T: ~const Tr + 'a, // OK
|
||||||
T: ~const 'a, //~ ERROR `~const` may only modify trait bounds, not lifetime bounds
|
T: ~const 'a, //~ ERROR `~const` may only modify trait bounds, not lifetime bounds
|
||||||
T: const 'a, //~ ERROR `const` may only modify trait bounds, not lifetime bounds
|
T: const 'a, //~ ERROR `const` may only modify trait bounds, not lifetime bounds
|
||||||
|
|
||||||
|
T: async Tr, // OK
|
||||||
|
T: async ?Tr, //~ ERROR `async` trait not allowed with `?` trait polarity modifier
|
||||||
|
T: async Tr + 'a, // OK
|
||||||
|
T: async 'a, //~ ERROR `async` may only modify trait bounds, not lifetime bounds
|
||||||
|
|
||||||
|
T: const async Tr, // OK
|
||||||
|
T: const async ?Tr, //~ ERROR `const async` trait not allowed with `?` trait polarity modifier
|
||||||
|
T: const async Tr + 'a, // OK
|
||||||
|
T: const async 'a, //~ ERROR `const` may only modify trait bounds, not lifetime bounds
|
||||||
>;
|
>;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: `for<...>` binder not allowed with `?` trait polarity modifier
|
error: `for<...>` binder not allowed with `?` trait polarity modifier
|
||||||
--> $DIR/bounds-type.rs:8:16
|
--> $DIR/bounds-type.rs:9:16
|
||||||
|
|
|
|
||||||
LL | T: for<'a> ?Trait,
|
LL | T: for<'a> ?Trait,
|
||||||
| ---- ^
|
| ---- ^
|
||||||
@ -7,22 +7,58 @@ LL | T: for<'a> ?Trait,
|
|||||||
| there is not a well-defined meaning for a higher-ranked `?` trait
|
| there is not a well-defined meaning for a higher-ranked `?` trait
|
||||||
|
|
||||||
error: `?` may only modify trait bounds, not lifetime bounds
|
error: `?` may only modify trait bounds, not lifetime bounds
|
||||||
--> $DIR/bounds-type.rs:10:8
|
--> $DIR/bounds-type.rs:11:8
|
||||||
|
|
|
|
||||||
LL | T: ?'a,
|
LL | T: ?'a,
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
|
error: `~const` trait not allowed with `?` trait polarity modifier
|
||||||
|
--> $DIR/bounds-type.rs:14:15
|
||||||
|
|
|
||||||
|
LL | T: ~const ?Tr,
|
||||||
|
| ------ ^
|
||||||
|
| |
|
||||||
|
| there is not a well-defined meaning for a `~const ?` trait
|
||||||
|
|
||||||
error: `~const` may only modify trait bounds, not lifetime bounds
|
error: `~const` may only modify trait bounds, not lifetime bounds
|
||||||
--> $DIR/bounds-type.rs:15:8
|
--> $DIR/bounds-type.rs:16:8
|
||||||
|
|
|
|
||||||
LL | T: ~const 'a,
|
LL | T: ~const 'a,
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: `const` may only modify trait bounds, not lifetime bounds
|
error: `const` may only modify trait bounds, not lifetime bounds
|
||||||
--> $DIR/bounds-type.rs:16:8
|
--> $DIR/bounds-type.rs:17:8
|
||||||
|
|
|
|
||||||
LL | T: const 'a,
|
LL | T: const 'a,
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: `async` trait not allowed with `?` trait polarity modifier
|
||||||
|
--> $DIR/bounds-type.rs:20:14
|
||||||
|
|
|
||||||
|
LL | T: async ?Tr,
|
||||||
|
| ----- ^
|
||||||
|
| |
|
||||||
|
| there is not a well-defined meaning for a `async ?` trait
|
||||||
|
|
||||||
|
error: `async` may only modify trait bounds, not lifetime bounds
|
||||||
|
--> $DIR/bounds-type.rs:22:8
|
||||||
|
|
|
||||||
|
LL | T: async 'a,
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: `const async` trait not allowed with `?` trait polarity modifier
|
||||||
|
--> $DIR/bounds-type.rs:25:20
|
||||||
|
|
|
||||||
|
LL | T: const async ?Tr,
|
||||||
|
| ----------- ^
|
||||||
|
| |
|
||||||
|
| there is not a well-defined meaning for a `const async ?` trait
|
||||||
|
|
||||||
|
error: `const` may only modify trait bounds, not lifetime bounds
|
||||||
|
--> $DIR/bounds-type.rs:27:8
|
||||||
|
|
|
||||||
|
LL | T: const async 'a,
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
const fn maybe_const_maybe<T: ~const ?Sized>() {}
|
const fn maybe_const_maybe<T: ~const ?Sized>() {}
|
||||||
//~^ ERROR `~const` and `?` are mutually exclusive
|
//~^ ERROR `~const` trait not allowed with `?` trait polarity modifier
|
||||||
|
|
||||||
fn const_maybe<T: const ?Sized>() {}
|
fn const_maybe<T: const ?Sized>() {}
|
||||||
//~^ ERROR `const` and `?` are mutually exclusive
|
//~^ ERROR `const` trait not allowed with `?` trait polarity modifier
|
||||||
|
|
||||||
const fn maybe_const_negative<T: ~const !Trait>() {}
|
const fn maybe_const_negative<T: ~const !Trait>() {}
|
||||||
//~^ ERROR `~const` and `!` are mutually exclusive
|
//~^ ERROR `~const` trait not allowed with `!` trait polarity modifier
|
||||||
//~| ERROR negative bounds are not supported
|
//~| ERROR negative bounds are not supported
|
||||||
|
|
||||||
fn const_negative<T: const !Trait>() {}
|
fn const_negative<T: const !Trait>() {}
|
||||||
//~^ ERROR `const` and `!` are mutually exclusive
|
//~^ ERROR `const` trait not allowed with `!` trait polarity modifier
|
||||||
//~| ERROR negative bounds are not supported
|
//~| ERROR negative bounds are not supported
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
|
@ -1,26 +1,34 @@
|
|||||||
error: `~const` and `?` are mutually exclusive
|
error: `~const` trait not allowed with `?` trait polarity modifier
|
||||||
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:31
|
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:38
|
||||||
|
|
|
|
||||||
LL | const fn maybe_const_maybe<T: ~const ?Sized>() {}
|
LL | const fn maybe_const_maybe<T: ~const ?Sized>() {}
|
||||||
| ^^^^^^^^^^^^^
|
| ------ ^
|
||||||
|
| |
|
||||||
|
| there is not a well-defined meaning for a `~const ?` trait
|
||||||
|
|
||||||
error: `const` and `?` are mutually exclusive
|
error: `const` trait not allowed with `?` trait polarity modifier
|
||||||
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:6:19
|
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:6:25
|
||||||
|
|
|
|
||||||
LL | fn const_maybe<T: const ?Sized>() {}
|
LL | fn const_maybe<T: const ?Sized>() {}
|
||||||
| ^^^^^^^^^^^^
|
| ----- ^
|
||||||
|
| |
|
||||||
|
| there is not a well-defined meaning for a `const ?` trait
|
||||||
|
|
||||||
error: `~const` and `!` are mutually exclusive
|
error: `~const` trait not allowed with `!` trait polarity modifier
|
||||||
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:34
|
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41
|
||||||
|
|
|
|
||||||
LL | const fn maybe_const_negative<T: ~const !Trait>() {}
|
LL | const fn maybe_const_negative<T: ~const !Trait>() {}
|
||||||
| ^^^^^^^^^^^^^
|
| ------ ^
|
||||||
|
| |
|
||||||
|
| there is not a well-defined meaning for a `~const !` trait
|
||||||
|
|
||||||
error: `const` and `!` are mutually exclusive
|
error: `const` trait not allowed with `!` trait polarity modifier
|
||||||
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:22
|
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28
|
||||||
|
|
|
|
||||||
LL | fn const_negative<T: const !Trait>() {}
|
LL | fn const_negative<T: const !Trait>() {}
|
||||||
| ^^^^^^^^^^^^
|
| ----- ^
|
||||||
|
| |
|
||||||
|
| there is not a well-defined meaning for a `const !` trait
|
||||||
|
|
||||||
error: negative bounds are not supported
|
error: negative bounds are not supported
|
||||||
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41
|
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41
|
||||||
|
Loading…
Reference in New Issue
Block a user