diff --git a/src/generics.rs b/src/generics.rs index b0fe8b02ee..ee069602b0 100644 --- a/src/generics.rs +++ b/src/generics.rs @@ -514,7 +514,9 @@ ast_struct! { #[cfg(feature = "parsing")] pub(crate) mod parsing { use crate::attr::Attribute; - use crate::error::{self, Result}; + #[cfg(feature = "full")] + use crate::error; + use crate::error::{Error, Result}; use crate::ext::IdentExt as _; use crate::generics::{ BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime, @@ -715,11 +717,11 @@ pub(crate) mod parsing { } bounds.push_value({ let allow_precise_capture = false; - let allow_tilde_const = true; + let allow_conditionally_const = true; TypeParamBound::parse_single( input, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )? }); if !input.peek(Token![+]) { @@ -752,8 +754,8 @@ pub(crate) mod parsing { impl Parse for TypeParamBound { fn parse(input: ParseStream) -> Result { let allow_precise_capture = true; - let allow_tilde_const = true; - Self::parse_single(input, allow_precise_capture, allow_tilde_const) + let allow_conditionally_const = true; + Self::parse_single(input, allow_precise_capture, allow_conditionally_const) } } @@ -761,7 +763,7 @@ pub(crate) mod parsing { pub(crate) fn parse_single( input: ParseStream, #[cfg_attr(not(feature = "full"), allow(unused_variables))] allow_precise_capture: bool, - allow_tilde_const: bool, + allow_conditionally_const: bool, ) -> Result { if input.peek(Lifetime) { return input.parse().map(TypeParamBound::Lifetime); @@ -793,21 +795,21 @@ pub(crate) mod parsing { (None, input) }; - let is_tilde_const = - cfg!(feature = "full") && content.peek(Token![~]) && content.peek2(Token![const]); - if is_tilde_const { - let tilde_token: Token![~] = content.parse()?; - let const_token: Token![const] = content.parse()?; - if !allow_tilde_const { - let msg = "`~const` is not allowed here"; - return Err(error::new2(tilde_token.span, const_token.span, msg)); + let is_conditionally_const = cfg!(feature = "full") && content.peek(token::Bracket); + if is_conditionally_const { + let conditionally_const; + let bracket_token = bracketed!(conditionally_const in content); + conditionally_const.parse::()?; + if !allow_conditionally_const { + let msg = "`[const]` is not allowed here"; + return Err(Error::new(bracket_token.span.join(), msg)); } } let mut bound: TraitBound = content.parse()?; bound.paren_token = paren_token; - if is_tilde_const { + if is_conditionally_const { Ok(TypeParamBound::Verbatim(verbatim::between(&begin, input))) } else { Ok(TypeParamBound::Trait(bound)) @@ -818,11 +820,12 @@ pub(crate) mod parsing { input: ParseStream, allow_plus: bool, allow_precise_capture: bool, - allow_tilde_const: bool, + allow_conditionally_const: bool, ) -> Result> { let mut bounds = Punctuated::new(); loop { - let bound = Self::parse_single(input, allow_precise_capture, allow_tilde_const)?; + let bound = + Self::parse_single(input, allow_precise_capture, allow_conditionally_const)?; bounds.push_value(bound); if !(allow_plus && input.peek(Token![+])) { break; @@ -833,7 +836,7 @@ pub(crate) mod parsing { || input.peek(Token![?]) || input.peek(Lifetime) || input.peek(token::Paren) - || input.peek(Token![~])) + || (allow_conditionally_const && input.peek(token::Bracket))) { break; } @@ -993,11 +996,11 @@ pub(crate) mod parsing { } bounds.push_value({ let allow_precise_capture = false; - let allow_tilde_const = true; + let allow_conditionally_const = true; TypeParamBound::parse_single( input, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )? }); if !input.peek(Token![+]) { diff --git a/src/item.rs b/src/item.rs index b574909dfc..89e710ba57 100644 --- a/src/item.rs +++ b/src/item.rs @@ -1208,11 +1208,11 @@ pub(crate) mod parsing { } bounds.push_value({ let allow_precise_capture = false; - let allow_tilde_const = true; + let allow_conditionally_const = true; TypeParamBound::parse_single( input, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )? }); if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) { @@ -2233,8 +2233,12 @@ pub(crate) mod parsing { } supertraits.push_value({ let allow_precise_capture = false; - let allow_tilde_const = true; - TypeParamBound::parse_single(input, allow_precise_capture, allow_tilde_const)? + let allow_conditionally_const = true; + TypeParamBound::parse_single( + input, + allow_precise_capture, + allow_conditionally_const, + )? }); if input.peek(Token![where]) || input.peek(token::Brace) { break; @@ -2305,8 +2309,12 @@ pub(crate) mod parsing { } bounds.push_value({ let allow_precise_capture = false; - let allow_tilde_const = false; - TypeParamBound::parse_single(input, allow_precise_capture, allow_tilde_const)? + let allow_conditionally_const = false; + TypeParamBound::parse_single( + input, + allow_precise_capture, + allow_conditionally_const, + )? }); if input.peek(Token![where]) || input.peek(Token![;]) { break; diff --git a/src/path.rs b/src/path.rs index 7744d28338..55eac9b680 100644 --- a/src/path.rs +++ b/src/path.rs @@ -379,11 +379,11 @@ pub(crate) mod parsing { } bounds.push_value({ let allow_precise_capture = false; - let allow_tilde_const = true; + let allow_conditionally_const = true; TypeParamBound::parse_single( input, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )? }); if !input.peek(Token![+]) { diff --git a/src/ty.rs b/src/ty.rs index 69fd77abea..a383bcf52d 100644 --- a/src/ty.rs +++ b/src/ty.rs @@ -404,11 +404,11 @@ pub(crate) mod parsing { bounds.push_punct(plus); bounds.push_value({ let allow_precise_capture = false; - let allow_tilde_const = false; + let allow_conditionally_const = false; TypeParamBound::parse_single( input, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )? }); } @@ -480,11 +480,11 @@ pub(crate) mod parsing { bounds.push_punct(plus); bounds.push_value({ let allow_precise_capture = false; - let allow_tilde_const = false; + let allow_conditionally_const = false; TypeParamBound::parse_single( input, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )? }); } @@ -551,11 +551,11 @@ pub(crate) mod parsing { } bounds.push_value({ let allow_precise_capture = false; - let allow_tilde_const = false; + let allow_conditionally_const = false; TypeParamBound::parse_single( input, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )? }); } @@ -849,12 +849,12 @@ pub(crate) mod parsing { allow_plus: bool, ) -> Result> { let allow_precise_capture = false; - let allow_tilde_const = false; + let allow_conditionally_const = false; let bounds = TypeParamBound::parse_multiple( input, allow_plus, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )?; let mut last_lifetime_span = None; let mut at_least_one_trait = false; @@ -899,12 +899,12 @@ pub(crate) mod parsing { pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result { let impl_token: Token![impl] = input.parse()?; let allow_precise_capture = true; - let allow_tilde_const = false; + let allow_conditionally_const = false; let bounds = TypeParamBound::parse_multiple( input, allow_plus, allow_precise_capture, - allow_tilde_const, + allow_conditionally_const, )?; let mut last_nontrait_span = None; let mut at_least_one_trait = false; @@ -929,7 +929,7 @@ pub(crate) mod parsing { } } TypeParamBound::Verbatim(_) => { - // ~const Trait + // `[const] Trait` at_least_one_trait = true; break; } diff --git a/tests/repo/mod.rs b/tests/repo/mod.rs index 1fded7c7b6..30738b23c6 100644 --- a/tests/repo/mod.rs +++ b/tests/repo/mod.rs @@ -32,75 +32,18 @@ static EXCLUDE_FILES: &[&str] = &[ "tests/ui/traits/const-traits/auxiliary/minicore.rs", "tests/ui/traits/const-traits/const-via-item-bound.rs", - // TODO: conditionally const trait bounds: `T: [const] Trait` - // https://github.com/dtolnay/syn/issues/1883 - "library/core/src/array/mod.rs", - "library/core/src/cell.rs", - "library/core/src/clone.rs", - "library/core/src/cmp.rs", - "library/core/src/cmp/bytewise.rs", - "library/core/src/convert/mod.rs", - "library/core/src/net/socket_addr.rs", - "library/core/src/num/nonzero.rs", - "library/core/src/ops/deref.rs", - "library/core/src/ops/function.rs", - "library/core/src/ops/index.rs", - "library/core/src/ops/try_trait.rs", - "library/core/src/ptr/const_ptr.rs", - "library/core/src/ptr/mut_ptr.rs", - "library/core/src/ptr/non_null.rs", - "library/core/src/result.rs", - "library/core/src/slice/cmp.rs", - "library/core/src/slice/index.rs", - "library/core/src/slice/mod.rs", - "library/core/src/str/mod.rs", - "library/core/src/str/traits.rs", - "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_bounds.rs", - "tests/run-make/const-trait-stable-toolchain/const-super-trait.rs", - "tests/rustdoc/constant/const-effect-param.rs", - "tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs", - "tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs", - "tests/ui/traits/const-traits/call-generic-in-impl.rs", - "tests/ui/traits/const-traits/call-generic-method-chain.rs", - "tests/ui/traits/const-traits/call-generic-method-dup-bound.rs", - "tests/ui/traits/const-traits/call-generic-method-pass.rs", - "tests/ui/traits/const-traits/conditionally-const-assoc-fn-in-trait-impl.rs", - "tests/ui/traits/const-traits/conditionally-const-inherent-assoc-const-fn.rs", - "tests/ui/traits/const-traits/conditionally-const-trait-bound-assoc-tys.rs", - "tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs", - "tests/ui/traits/const-traits/const-closure-trait-method.rs", - "tests/ui/traits/const-traits/const-closures.rs", - "tests/ui/traits/const-traits/const-drop-bound.rs", - "tests/ui/traits/const-traits/const-drop.rs", - "tests/ui/traits/const-traits/const-fn-trait-bound-issue-104314.rs", - "tests/ui/traits/const-traits/dont-prefer-param-env-for-infer-self-ty.rs", - "tests/ui/traits/const-traits/function-pointer-does-not-require-const.rs", - "tests/ui/traits/const-traits/inherent-impl-const-bounds.rs", - "tests/ui/traits/const-traits/issue-92111.rs", - "tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs", - "tests/ui/traits/const-traits/item-bound-entailment.rs", - "tests/ui/traits/const-traits/minicore-works.rs", - "tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs", - "tests/ui/traits/const-traits/predicate-entailment-passes.rs", - "tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs", - "tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs", - "tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs", - "tests/ui/traits/const-traits/specialization/specialize-on-conditionally-const.rs", - "tests/ui/traits/const-traits/super-traits.rs", - "tests/ui/traits/const-traits/trait-where-clause-run.rs", - "tests/ui/traits/const-traits/trait-where-clause-self-referential.rs", - "tests/ui/unpretty/ast-const-trait-bound.rs", - // TODO: unconditionally const trait bound syntax: `T: const FnOnce` // https://github.com/dtolnay/syn/issues/1885 "library/core/src/intrinsics/mod.rs", "tests/ui/generic-const-items/const-trait-impl.rs", "tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs", "tests/ui/traits/const-traits/const-bound-in-host.rs", + "tests/ui/traits/const-traits/const-drop.rs", "tests/ui/traits/const-traits/const-in-closure.rs", "tests/ui/traits/const-traits/dont-ice-on-const-pred-for-bounds.rs", "tests/ui/traits/const-traits/imply-always-const.rs", "tests/ui/traits/const-traits/minicore-const-fn-early-bound.rs", + "tests/ui/traits/const-traits/predicate-entailment-passes.rs", "tests/ui/traits/const-traits/unconstrained-var-specialization.rs", // TODO: conditionally const impl Trait: `impl [const] FnOnce()` @@ -111,6 +54,7 @@ static EXCLUDE_FILES: &[&str] = &[ "tests/ui/traits/const-traits/const-closure-issue-125866-pass.rs", "tests/ui/traits/const-traits/const-cond-for-rpitit.rs", "tests/ui/traits/const-traits/const-impl-trait.rs", + "tests/ui/traits/const-traits/dont-prefer-param-env-for-infer-self-ty.rs", // TODO: conditionally const trait bound with lifetime bindar: `T: for<'a> [const] async Trait<'a>` // https://github.com/dtolnay/syn/issues/1888