From 28164e3c047991294a3d4e7afd6b820c0c2f86ee Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 10 Feb 2025 19:47:00 +0000 Subject: [PATCH] Stop using span hack for contracts feature gating --- .../rustc_builtin_macros/src/contracts.rs | 21 +++++++--------- compiler/rustc_parse/src/parser/generics.rs | 14 ++--------- compiler/rustc_session/src/parse.rs | 5 ---- .../internal-feature-gating.stderr | 8 +++---- .../feature-gates/feature-gate-contracts.rs | 2 -- .../feature-gate-contracts.stderr | 24 ++----------------- 6 files changed, 17 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/contracts.rs b/compiler/rustc_builtin_macros/src/contracts.rs index 85a30f7bdc9b4..0cba29f2b3123 100644 --- a/compiler/rustc_builtin_macros/src/contracts.rs +++ b/compiler/rustc_builtin_macros/src/contracts.rs @@ -4,8 +4,8 @@ use rustc_ast::token; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_errors::ErrorGuaranteed; use rustc_expand::base::{AttrProcMacro, ExtCtxt}; -use rustc_span::Span; use rustc_span::symbol::{Ident, Symbol, kw, sym}; +use rustc_span::{DesugaringKind, Span}; pub(crate) struct ExpandRequires; @@ -121,23 +121,19 @@ fn expand_contract_clause( } } - // Record the span as a contract attribute expansion. - // This is used later to stop users from using the extended syntax directly - // which is gated via `contracts_internals`. - ecx.psess().contract_attribute_spans.push(attr_span); - Ok(new_tts) } fn expand_requires_tts( - _ecx: &mut ExtCtxt<'_>, + ecx: &mut ExtCtxt<'_>, attr_span: Span, annotation: TokenStream, annotated: TokenStream, ) -> Result { - expand_contract_clause(_ecx, attr_span, annotated, |new_tts| { + let feature_span = ecx.with_def_site_ctxt(attr_span); + expand_contract_clause(ecx, attr_span, annotated, |new_tts| { new_tts.push_tree(TokenTree::Token( - token::Token::from_ast_ident(Ident::new(kw::ContractRequires, attr_span)), + token::Token::from_ast_ident(Ident::new(kw::ContractRequires, feature_span)), Spacing::Joint, )); new_tts.push_tree(TokenTree::Token( @@ -155,14 +151,15 @@ fn expand_requires_tts( } fn expand_ensures_tts( - _ecx: &mut ExtCtxt<'_>, + ecx: &mut ExtCtxt<'_>, attr_span: Span, annotation: TokenStream, annotated: TokenStream, ) -> Result { - expand_contract_clause(_ecx, attr_span, annotated, |new_tts| { + let feature_span = ecx.with_def_site_ctxt(attr_span); + expand_contract_clause(ecx, attr_span, annotated, |new_tts| { new_tts.push_tree(TokenTree::Token( - token::Token::from_ast_ident(Ident::new(kw::ContractEnsures, attr_span)), + token::Token::from_ast_ident(Ident::new(kw::ContractEnsures, feature_span)), Spacing::Joint, )); new_tts.push_tree(TokenTree::Delimited( diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 86816819be275..11f0e579de5a1 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -302,26 +302,16 @@ impl<'a> Parser<'a> { pub(super) fn parse_contract( &mut self, ) -> PResult<'a, Option>> { - let gate = |span| { - if self.psess.contract_attribute_spans.contains(span) { - // span was generated via a builtin contracts attribute, so gate as end-user visible - self.psess.gated_spans.gate(sym::contracts, span); - } else { - // span was not generated via a builtin contracts attribute, so gate as internal machinery - self.psess.gated_spans.gate(sym::contracts_internals, span); - } - }; - let requires = if self.eat_keyword_noexpect(exp!(ContractRequires).kw) { + self.psess.gated_spans.gate(sym::contracts_internals, self.prev_token.span); let precond = self.parse_expr()?; - gate(precond.span); Some(precond) } else { None }; let ensures = if self.eat_keyword_noexpect(exp!(ContractEnsures).kw) { + self.psess.gated_spans.gate(sym::contracts_internals, self.prev_token.span); let postcond = self.parse_expr()?; - gate(postcond.span); Some(postcond) } else { None diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index d4db05ce139fa..e0405a71f65af 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -208,10 +208,6 @@ pub struct ParseSess { pub config: Cfg, pub check_config: CheckCfg, pub edition: Edition, - /// Places where contract attributes were expanded into unstable AST forms. - /// This is used to allowlist those spans (so that we only check them against the feature - /// gate for the externally visible interface, and not internal implmentation machinery). - pub contract_attribute_spans: AppendOnlyVec, /// Places where raw identifiers were used. This is used to avoid complaining about idents /// clashing with keywords in new editions. pub raw_identifier_spans: AppendOnlyVec, @@ -260,7 +256,6 @@ impl ParseSess { config: Cfg::default(), check_config: CheckCfg::default(), edition: ExpnId::root().expn_data().edition, - contract_attribute_spans: Default::default(), raw_identifier_spans: Default::default(), bad_unicode_identifiers: Lock::new(Default::default()), source_map, diff --git a/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr b/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr index c0e1522f54c61..7302694a7874a 100644 --- a/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr +++ b/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr @@ -1,18 +1,18 @@ error[E0658]: contract internal machinery is for internal use only - --> $DIR/internal-feature-gating.rs:16:45 + --> $DIR/internal-feature-gating.rs:16:28 | LL | fn identity_1() -> i32 contract_requires(|| true) { 10 } - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: see issue #128044 for more information = help: add `#![feature(contracts_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: contract internal machinery is for internal use only - --> $DIR/internal-feature-gating.rs:18:44 + --> $DIR/internal-feature-gating.rs:18:28 | LL | fn identity_2() -> i32 contract_ensures(|_| true) { 10 } - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = note: see issue #128044 for more information = help: add `#![feature(contracts_internals)]` to the crate attributes to enable diff --git a/tests/ui/feature-gates/feature-gate-contracts.rs b/tests/ui/feature-gates/feature-gate-contracts.rs index 5544f1d82ee4c..1759d23077b53 100644 --- a/tests/ui/feature-gates/feature-gate-contracts.rs +++ b/tests/ui/feature-gates/feature-gate-contracts.rs @@ -3,9 +3,7 @@ #[core::contracts::requires(x > 0)] pub fn requires_needs_it(x: i32) { } //~^^ ERROR use of unstable library feature `contracts` -//~^^^ ERROR contracts are incomplete #[core::contracts::ensures(|ret| *ret > 0)] pub fn ensures_needs_it() -> i32 { 10 } //~^^ ERROR use of unstable library feature `contracts` -//~^^^ ERROR contracts are incomplete diff --git a/tests/ui/feature-gates/feature-gate-contracts.stderr b/tests/ui/feature-gates/feature-gate-contracts.stderr index 4403e7df50b49..4b0f7150973f1 100644 --- a/tests/ui/feature-gates/feature-gate-contracts.stderr +++ b/tests/ui/feature-gates/feature-gate-contracts.stderr @@ -9,7 +9,7 @@ LL | #[core::contracts::requires(x > 0)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `contracts` - --> $DIR/feature-gate-contracts.rs:8:3 + --> $DIR/feature-gate-contracts.rs:7:3 | LL | #[core::contracts::ensures(|ret| *ret > 0)] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -18,26 +18,6 @@ LL | #[core::contracts::ensures(|ret| *ret > 0)] = help: add `#![feature(contracts)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: contracts are incomplete - --> $DIR/feature-gate-contracts.rs:3:1 - | -LL | #[core::contracts::requires(x > 0)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #128044 for more information - = help: add `#![feature(contracts)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: contracts are incomplete - --> $DIR/feature-gate-contracts.rs:8:1 - | -LL | #[core::contracts::ensures(|ret| *ret > 0)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #128044 for more information - = help: add `#![feature(contracts)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`.