Skip to content

Commit e59670b

Browse files
committed
Improve feature handling
This includes a program, written using flex and bison, to extract information on unstable features from rustc source code and save it to a header file. The script does fetch files from https://github.com/rust-lang/rust (the official rustc git repository), which should be alright, as it's only intended to be run by maintainers. See https://doc.rust-lang.org/unstable-book/ for information on unstable features. gcc/rust/ChangeLog: * Make-lang.in: Handle moving feature related files into their own subdirectory. * checks/errors/rust-feature-gate.cc: Move to... * checks/errors/feature/rust-feature-gate.cc: ...here. (FeatureGate::gate): Handle removal of Feature::create. (FeatureGate::visit): Refer to AUTO_TRAITS as OPTIN_BUILTIN_TRAITS. * checks/errors/rust-feature-gate.h: Move to... * checks/errors/feature/rust-feature-gate.h: ...here. * checks/errors/rust-feature.cc: Move to... * checks/errors/feature/rust-feature.cc: ...here. (Feature::create): Remove. (Feature::feature_list): New static member variable. (Feature::name_hash_map): Use "rust-feature-defs.h" to define. (Feature::lookup): New member function definition. * checks/errors/rust-feature.h: Move to... * checks/errors/feature/rust-feature.h: ...here. (Feature::State): Add comments. (Feature::Name): Use "rust-feature-defs.h" to define. (Feature::as_string): Make const. (Feature::name): Likewise. (Feature::state): Likewise. (Feature::issue): Likewise. (Feature::description): Remove. (Feature::create): Remove. (Feature::lookup): New member function declarations. (Feature::Feature): Adjust arguments. (Feature::m_rustc_since): Rename to... (Feature::m_rust_since): ...here. (Feature::m_description): Remove. (Feature::m_reason): New member variable. (Feature::feature_list): New static member variable. * checks/errors/feature/rust-feature-defs.h: New file. contrib/ChangeLog: * rust/feature-fetch/parse.y: New file. * rust/feature-fetch/scan.l: New file. * rust/feature-fetch/.gitignore: New file. * rust/feature-fetch/Makefile: New file. * rust/feature-fetch/fetch: New file. * rust/feature-fetch/regen: New file. Signed-off-by: Owen Avery <[email protected]>
1 parent 522d2d3 commit e59670b

File tree

14 files changed

+1023
-189
lines changed

14 files changed

+1023
-189
lines changed

contrib/rust/feature-fetch/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

contrib/rust/feature-fetch/Makefile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
OUT = ../../../gcc/rust/checks/errors/feature/rust-feature-defs.h
2+
3+
all: $(OUT)
4+
5+
mk-build-dir:
6+
mkdir -p build
7+
8+
build/parse.c: parse.y mk-build-dir
9+
$(YACC) $(YFLAGS) -o $@ --defines=build/parse.h $<
10+
11+
build/parse.h: build/parse.c;
12+
13+
build/scan.c: scan.l
14+
$(LEX) $(LFLAGS) -o $@ -Ca --header-file=build/scan.h $<
15+
16+
build/scan.h: build/scan.c;
17+
18+
build/%.o: build/%.c build/parse.h build/scan.h
19+
$(CC) $(CFLAGS) -c -Ibuild -o $@ $<
20+
21+
build/feature-extract: build/parse.o build/scan.o
22+
$(CC) $(LDFLAGS) $(LDLIBS) -o $@ $^
23+
24+
build/download.rs: fetch
25+
./$< $@
26+
27+
$(OUT): build/feature-extract build/download.rs
28+
cat build/download.rs | ./$< > build/rust-feature-defs.h
29+
clang-format -i build/rust-feature-defs.h \
30+
--style=file:../../clang-format
31+
mv build/rust-feature-defs.h $(OUT)
32+
33+
clean:
34+
$(RM) -r build
35+
36+
full-clean: clean
37+
$(RM) $(OUT)

contrib/rust/feature-fetch/fetch

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/sh
2+
3+
RUST_VERSION="1.49.0"
4+
5+
[ $# = 1 ] || exit 1
6+
7+
URL_PREFIX='https://raw.githubusercontent.com/rust-lang/rust/refs/tags'
8+
URL_TEMPLATE="$URL_PREFIX/$RUST_VERSION/compiler/rustc_feature/src"
9+
10+
wget -O $1 "$URL_TEMPLATE"/{accepted,active,removed}.rs

contrib/rust/feature-fetch/parse.y

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/* Copyright (C) 2025 Free Software Foundation, Inc.
2+
3+
This file is part of GCC.
4+
5+
GCC is free software; you can redistribute it and/or modify it under
6+
the terms of the GNU General Public License as published by the Free
7+
Software Foundation; either version 3, or (at your option) any later
8+
version.
9+
10+
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with GCC; see the file COPYING3. If not see
17+
<http://www.gnu.org/licenses/>. */
18+
19+
%{
20+
21+
#include <stdlib.h>
22+
#include <stdio.h>
23+
#include <ctype.h>
24+
25+
int yylex (void);
26+
void yyerror (char const *);
27+
28+
#include "scan.h"
29+
30+
// expands to three %s parameters
31+
#define UNWRAP_OPT_STR(prefix, s) (s ? prefix "_SOME (" : prefix "_NONE"), (s ? s : ""), (s ? ")" : "")
32+
33+
%}
34+
35+
%union
36+
{
37+
char *str;
38+
};
39+
40+
%token <str> IDENT STR NUM
41+
%token SCOPE
42+
%token K_SOME K_NONE
43+
%token K_ACTIVE K_ACCEPTED K_REMOVED K_STABLE_REMOVED
44+
%token K_E_START K_E_2018
45+
46+
%type <str> issue
47+
%type <str> edition
48+
%type <str> reason
49+
50+
%%
51+
52+
multi_database: multi_database database
53+
| database
54+
;
55+
56+
database: '(' entry_list ')';
57+
58+
entry_list: entry_list entry ','
59+
| entry ','
60+
;
61+
62+
entry: '(' K_ACTIVE ',' IDENT ',' STR ',' issue ',' edition ')' {
63+
char *ident_upper = strdup ($4);
64+
for (size_t i = 0; ident_upper[i]; i++)
65+
ident_upper[i] = toupper (ident_upper[i]);
66+
printf ("FEATURE_ACTIVE (\"%s\", %s, %s, %s%s%s, EDITION_%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8), $10 ? $10 : "NONE");
67+
free ($4);
68+
free (ident_upper);
69+
free ($6);
70+
free ($8);
71+
}
72+
| '(' K_ACCEPTED ',' IDENT ',' STR ',' issue ',' K_NONE ')' {
73+
char *ident_upper = strdup ($4);
74+
for (size_t i = 0; ident_upper[i]; i++)
75+
ident_upper[i] = toupper (ident_upper[i]);
76+
printf ("FEATURE_ACCEPTED (\"%s\", %s, %s, %s%s%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8));
77+
free ($4);
78+
free (ident_upper);
79+
free ($6);
80+
free ($8);
81+
}
82+
| '(' K_REMOVED ',' IDENT ',' STR ',' issue ',' K_NONE ',' reason ')' {
83+
char *ident_upper;
84+
// HACK: convert no_debug to F_NO_DEBUG instead
85+
// since NO_DEBUG is used as an unrelated macro
86+
if (!strcmp ($4, "no_debug"))
87+
{
88+
ident_upper = strdup ("F_NO_DEBUG");
89+
}
90+
else
91+
{
92+
ident_upper = strdup ($4);
93+
for (size_t i = 0; ident_upper[i]; i++)
94+
ident_upper[i] = toupper (ident_upper[i]);
95+
}
96+
printf ("FEATURE_REMOVED (\"%s\", %s, %s, %s%s%s, %s%s%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8), UNWRAP_OPT_STR ("REASON", $12));
97+
free ($4);
98+
free (ident_upper);
99+
free ($6);
100+
free ($8);
101+
free ($12);
102+
}
103+
| '(' K_STABLE_REMOVED ',' IDENT ',' STR ',' issue ',' K_NONE ')' {
104+
char *ident_upper = strdup ($4);
105+
for (size_t i = 0; ident_upper[i]; i++)
106+
ident_upper[i] = toupper (ident_upper[i]);
107+
printf ("FEATURE_STABLE_REMOVED (\"%s\", %s, %s, %s%s%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8));
108+
free ($4);
109+
free (ident_upper);
110+
free ($6);
111+
free ($8);
112+
}
113+
;
114+
115+
issue: K_SOME '(' NUM ')' { $$ = $3; }
116+
| K_NONE { $$ = NULL; }
117+
;
118+
119+
/* TODO: expand this as needed */
120+
edition: K_NONE { $$ = NULL; }
121+
| K_SOME '(' K_E_START SCOPE K_E_2018 ')' { $$ = "2018"; }
122+
;
123+
124+
reason: K_SOME '(' STR ')' { $$ = $3; }
125+
| K_NONE { $$ = NULL; }
126+
;
127+
128+
%%
129+
130+
void yyerror (const char *msg)
131+
{
132+
fprintf (stderr, "%s\n", msg);
133+
}
134+
135+
int yywrap (void)
136+
{
137+
return 1;
138+
}
139+
140+
int main (void)
141+
{
142+
return yyparse ();
143+
}

contrib/rust/feature-fetch/regen

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh
2+
3+
cd "$(dirname "$0")"
4+
rm -f ../../../gcc/rust/checks/errors/feature/rust-feature-defs.h
5+
make all

contrib/rust/feature-fetch/scan.l

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* Copyright (C) 2025 Free Software Foundation, Inc.
2+
3+
This file is part of GCC.
4+
5+
GCC is free software; you can redistribute it and/or modify it under
6+
the terms of the GNU General Public License as published by the Free
7+
Software Foundation; either version 3, or (at your option) any later
8+
version.
9+
10+
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with GCC; see the file COPYING3. If not see
17+
<http://www.gnu.org/licenses/>. */
18+
19+
%{
20+
21+
#include "parse.h"
22+
23+
static int p_count = 0;
24+
25+
%}
26+
27+
%x INSIDE COMMENT
28+
29+
%%
30+
31+
declare_features! BEGIN (INSIDE);
32+
.|\n /* ignore */
33+
34+
<INSIDE>\( p_count++; return '(';
35+
<INSIDE>\) if (!--p_count) { BEGIN (0); } return ')';
36+
<INSIDE>, return ',';
37+
<INSIDE>:: return SCOPE;
38+
<INSIDE>Some return K_SOME;
39+
<INSIDE>None return K_NONE;
40+
<INSIDE>active return K_ACTIVE;
41+
<INSIDE>accepted return K_ACCEPTED;
42+
<INSIDE>removed return K_REMOVED;
43+
<INSIDE>stable_removed return K_STABLE_REMOVED;
44+
<INSIDE>Edition return K_E_START;
45+
<INSIDE>Edition2018 return K_E_2018;
46+
47+
<INSIDE>[A-Za-z_][A-Za-z0-9_]* yylval.str = strdup (yytext); return IDENT;
48+
<INSIDE>[1-9][0-9]* yylval.str = strdup (yytext); return NUM;
49+
<INSIDE>\"[^"]+\" yylval.str = strdup (yytext); return STR;
50+
<INSIDE>"/""/" BEGIN (COMMENT);
51+
<INSIDE>[ \n] /* ignore */
52+
<INSIDE>. { fprintf (stderr, "unrecognized character %u\n", (unsigned int) yytext[0]); exit (1); }
53+
54+
<COMMENT>. /* skip */
55+
<COMMENT>\n BEGIN (INSIDE);

gcc/rust/Make-lang.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ RUST_INCLUDES = -I $(srcdir)/rust \
444444
-I $(srcdir)/rust/checks/errors \
445445
-I $(srcdir)/rust/checks/errors/privacy \
446446
-I $(srcdir)/rust/checks/errors/borrowck \
447+
-I $(srcdir)/rust/checks/errors/feature \
447448
-I $(srcdir)/rust/util \
448449
-I $(srcdir)/rust/metadata \
449450
-I $(srcdir)/../libgrust
@@ -516,6 +517,11 @@ rust/%.o: rust/checks/errors/%.cc
516517
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
517518
$(POSTCOMPILE)
518519

520+
# build feature related files in rust folder
521+
rust/%.o: rust/checks/errors/feature/%.cc
522+
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
523+
$(POSTCOMPILE)
524+
519525
# build privacy pass files in rust folder
520526
rust/%.o: rust/checks/errors/privacy/%.cc
521527
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<

0 commit comments

Comments
 (0)