Skip to content

Commit 28164e3

Browse files
Stop using span hack for contracts feature gating
1 parent 8c04e39 commit 28164e3

File tree

6 files changed

+17
-57
lines changed

6 files changed

+17
-57
lines changed

compiler/rustc_builtin_macros/src/contracts.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use rustc_ast::token;
44
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
55
use rustc_errors::ErrorGuaranteed;
66
use rustc_expand::base::{AttrProcMacro, ExtCtxt};
7-
use rustc_span::Span;
87
use rustc_span::symbol::{Ident, Symbol, kw, sym};
8+
use rustc_span::{DesugaringKind, Span};
99

1010
pub(crate) struct ExpandRequires;
1111

@@ -121,23 +121,19 @@ fn expand_contract_clause(
121121
}
122122
}
123123

124-
// Record the span as a contract attribute expansion.
125-
// This is used later to stop users from using the extended syntax directly
126-
// which is gated via `contracts_internals`.
127-
ecx.psess().contract_attribute_spans.push(attr_span);
128-
129124
Ok(new_tts)
130125
}
131126

132127
fn expand_requires_tts(
133-
_ecx: &mut ExtCtxt<'_>,
128+
ecx: &mut ExtCtxt<'_>,
134129
attr_span: Span,
135130
annotation: TokenStream,
136131
annotated: TokenStream,
137132
) -> Result<TokenStream, ErrorGuaranteed> {
138-
expand_contract_clause(_ecx, attr_span, annotated, |new_tts| {
133+
let feature_span = ecx.with_def_site_ctxt(attr_span);
134+
expand_contract_clause(ecx, attr_span, annotated, |new_tts| {
139135
new_tts.push_tree(TokenTree::Token(
140-
token::Token::from_ast_ident(Ident::new(kw::ContractRequires, attr_span)),
136+
token::Token::from_ast_ident(Ident::new(kw::ContractRequires, feature_span)),
141137
Spacing::Joint,
142138
));
143139
new_tts.push_tree(TokenTree::Token(
@@ -155,14 +151,15 @@ fn expand_requires_tts(
155151
}
156152

157153
fn expand_ensures_tts(
158-
_ecx: &mut ExtCtxt<'_>,
154+
ecx: &mut ExtCtxt<'_>,
159155
attr_span: Span,
160156
annotation: TokenStream,
161157
annotated: TokenStream,
162158
) -> Result<TokenStream, ErrorGuaranteed> {
163-
expand_contract_clause(_ecx, attr_span, annotated, |new_tts| {
159+
let feature_span = ecx.with_def_site_ctxt(attr_span);
160+
expand_contract_clause(ecx, attr_span, annotated, |new_tts| {
164161
new_tts.push_tree(TokenTree::Token(
165-
token::Token::from_ast_ident(Ident::new(kw::ContractEnsures, attr_span)),
162+
token::Token::from_ast_ident(Ident::new(kw::ContractEnsures, feature_span)),
166163
Spacing::Joint,
167164
));
168165
new_tts.push_tree(TokenTree::Delimited(

compiler/rustc_parse/src/parser/generics.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -302,26 +302,16 @@ impl<'a> Parser<'a> {
302302
pub(super) fn parse_contract(
303303
&mut self,
304304
) -> PResult<'a, Option<rustc_ast::ptr::P<ast::FnContract>>> {
305-
let gate = |span| {
306-
if self.psess.contract_attribute_spans.contains(span) {
307-
// span was generated via a builtin contracts attribute, so gate as end-user visible
308-
self.psess.gated_spans.gate(sym::contracts, span);
309-
} else {
310-
// span was not generated via a builtin contracts attribute, so gate as internal machinery
311-
self.psess.gated_spans.gate(sym::contracts_internals, span);
312-
}
313-
};
314-
315305
let requires = if self.eat_keyword_noexpect(exp!(ContractRequires).kw) {
306+
self.psess.gated_spans.gate(sym::contracts_internals, self.prev_token.span);
316307
let precond = self.parse_expr()?;
317-
gate(precond.span);
318308
Some(precond)
319309
} else {
320310
None
321311
};
322312
let ensures = if self.eat_keyword_noexpect(exp!(ContractEnsures).kw) {
313+
self.psess.gated_spans.gate(sym::contracts_internals, self.prev_token.span);
323314
let postcond = self.parse_expr()?;
324-
gate(postcond.span);
325315
Some(postcond)
326316
} else {
327317
None

compiler/rustc_session/src/parse.rs

-5
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,6 @@ pub struct ParseSess {
208208
pub config: Cfg,
209209
pub check_config: CheckCfg,
210210
pub edition: Edition,
211-
/// Places where contract attributes were expanded into unstable AST forms.
212-
/// This is used to allowlist those spans (so that we only check them against the feature
213-
/// gate for the externally visible interface, and not internal implmentation machinery).
214-
pub contract_attribute_spans: AppendOnlyVec<Span>,
215211
/// Places where raw identifiers were used. This is used to avoid complaining about idents
216212
/// clashing with keywords in new editions.
217213
pub raw_identifier_spans: AppendOnlyVec<Span>,
@@ -260,7 +256,6 @@ impl ParseSess {
260256
config: Cfg::default(),
261257
check_config: CheckCfg::default(),
262258
edition: ExpnId::root().expn_data().edition,
263-
contract_attribute_spans: Default::default(),
264259
raw_identifier_spans: Default::default(),
265260
bad_unicode_identifiers: Lock::new(Default::default()),
266261
source_map,

tests/ui/contracts/internal_machinery/internal-feature-gating.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
error[E0658]: contract internal machinery is for internal use only
2-
--> $DIR/internal-feature-gating.rs:16:45
2+
--> $DIR/internal-feature-gating.rs:16:28
33
|
44
LL | fn identity_1() -> i32 contract_requires(|| true) { 10 }
5-
| ^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^
66
|
77
= note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
88
= help: add `#![feature(contracts_internals)]` to the crate attributes to enable
99
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010

1111
error[E0658]: contract internal machinery is for internal use only
12-
--> $DIR/internal-feature-gating.rs:18:44
12+
--> $DIR/internal-feature-gating.rs:18:28
1313
|
1414
LL | fn identity_2() -> i32 contract_ensures(|_| true) { 10 }
15-
| ^^^^^^^^^^
15+
| ^^^^^^^^^^^^^^^^
1616
|
1717
= note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
1818
= help: add `#![feature(contracts_internals)]` to the crate attributes to enable

tests/ui/feature-gates/feature-gate-contracts.rs

-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
#[core::contracts::requires(x > 0)]
44
pub fn requires_needs_it(x: i32) { }
55
//~^^ ERROR use of unstable library feature `contracts`
6-
//~^^^ ERROR contracts are incomplete
76

87
#[core::contracts::ensures(|ret| *ret > 0)]
98
pub fn ensures_needs_it() -> i32 { 10 }
109
//~^^ ERROR use of unstable library feature `contracts`
11-
//~^^^ ERROR contracts are incomplete

tests/ui/feature-gates/feature-gate-contracts.stderr

+2-22
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | #[core::contracts::requires(x > 0)]
99
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010

1111
error[E0658]: use of unstable library feature `contracts`
12-
--> $DIR/feature-gate-contracts.rs:8:3
12+
--> $DIR/feature-gate-contracts.rs:7:3
1313
|
1414
LL | #[core::contracts::ensures(|ret| *ret > 0)]
1515
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -18,26 +18,6 @@ LL | #[core::contracts::ensures(|ret| *ret > 0)]
1818
= help: add `#![feature(contracts)]` to the crate attributes to enable
1919
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2020

21-
error[E0658]: contracts are incomplete
22-
--> $DIR/feature-gate-contracts.rs:3:1
23-
|
24-
LL | #[core::contracts::requires(x > 0)]
25-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26-
|
27-
= note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
28-
= help: add `#![feature(contracts)]` to the crate attributes to enable
29-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
30-
31-
error[E0658]: contracts are incomplete
32-
--> $DIR/feature-gate-contracts.rs:8:1
33-
|
34-
LL | #[core::contracts::ensures(|ret| *ret > 0)]
35-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36-
|
37-
= note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
38-
= help: add `#![feature(contracts)]` to the crate attributes to enable
39-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
40-
41-
error: aborting due to 4 previous errors
21+
error: aborting due to 2 previous errors
4222

4323
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)