`syn` support
Miguel Ojeda
maintainercover `syn` support
This patch series introduces support for syn (and its dependencies). Having such support allows to greatly simplify writing complex macros such as pin-init.
Benno has already prepared the pin-init version based on this, and on top of that, we will be able to simplify the macros crate too.
The series starts with a few preparation commits (two fixes were already merged in mainline that were discovered by this series), then each crate is added.
This has been a long time coming -- the first iterations of this, from 2022 and 2023 (with serde too), are at:
https://github.com/Rust-for-Linux/linux/pull/910 https://github.com/Rust-for-Linux/linux/pull/1007
After those, we considered picking these from the distributions where possible. However, after discussing it, it is not really worth the
complexity: vendoring makes things less complex and is less fragile.
In particular, we avoid having to support and test several versions, we avoid having to introduce Cargo just to properly fetch the right versions from the registry, we can easily customize the crates if needed (e.g. dropping the unicode_idents dependency like it is done in this series) and we simplify the configuration of the build for users for which the "default" paths/registries would not have worked.
Moreover, nowadays, the ~57k lines introduced are not that much compared to years ago (it dwarfed the actual Rust kernel code). Moreover, back then it wasn't clear the Rust experiment would be a success, so it would have been a bit pointless/risky to add many lines for nothing. Our macro needs were also smaller in the early days.
So, finally, in Kangrejos 2025 we discussed going with the original, simpler approach. Thus here it is the result.
There should not be many updates needed for these, and even if there are, they should not be too big, e.g. +7k -3k lines across the 3 crates in the last year.
Note that syn does not have all the features enabled, since we do not need them so far, but they can easily be enabled just adding them to the list.
I will be updating the webpage as well with the result of this:
https://rust-for-linux.com/third-party-crates
Please give it a test -- thanks!
Miguel Ojeda (18):
rust: condvar: avoid pub in example
rust: kbuild: introduce core-flags and core-skip_flags
rust: kbuild: simplify --cfg handling
rust: kbuild: add host library support
rust: proc-macro2: import crate
rust: proc-macro2: add SPDX License Identifiers
rust: proc-macro2: remove unicode_ident dependency
rust: proc-macro2: add README.md
rust: proc-macro2: enable support in kbuild
rust: quote: import crate
rust: quote: add SPDX License Identifiers
rust: quote: add README.md
rust: quote: enable support in kbuild
rust: syn: import crate
rust: syn: add SPDX License Identifiers
rust: syn: remove unicode-ident dependency
rust: syn: add README.md
rust: syn: enable support in kbuild
.gitignore | 1 + Makefile | 5 + rust/Makefile | 134 +- rust/kernel/sync/condvar.rs | 2 +- rust/proc-macro2/README.md | 13 + rust/proc-macro2/detection.rs | 77 + rust/proc-macro2/extra.rs | 153 + rust/proc-macro2/fallback.rs | 1258 +++++ rust/proc-macro2/lib.rs | 1351 ++++++ rust/proc-macro2/location.rs | 31 + rust/proc-macro2/marker.rs | 19 + rust/proc-macro2/parse.rs | 997 ++++ rust/proc-macro2/probe.rs | 12 + rust/proc-macro2/probe/proc_macro_span.rs | 53 + .../proc-macro2/probe/proc_macro_span_file.rs | 16 + .../probe/proc_macro_span_location.rs | 23 + rust/proc-macro2/rcvec.rs | 148 + rust/proc-macro2/wrapper.rs | 986 ++++ rust/quote/README.md | 12 + rust/quote/ext.rs | 112 + rust/quote/format.rs | 170 + rust/quote/ident_fragment.rs | 90 + rust/quote/lib.rs | 1456 ++++++ rust/quote/runtime.rs | 494 ++ rust/quote/spanned.rs | 52 + rust/quote/to_tokens.rs | 273 ++ rust/syn/README.md | 13 + rust/syn/attr.rs | 838 ++++ rust/syn/bigint.rs | 68 + rust/syn/buffer.rs | 436 ++ rust/syn/classify.rs | 313 ++ rust/syn/custom_keyword.rs | 262 ++ rust/syn/custom_punctuation.rs | 306 ++ rust/syn/data.rs | 426 ++ rust/syn/derive.rs | 261 ++ rust/syn/discouraged.rs | 227 + rust/syn/drops.rs | 60 + rust/syn/error.rs | 469 ++ rust/syn/export.rs | 75 + rust/syn/expr.rs | 4175 +++++++++++++++++ rust/syn/ext.rs | 138 + rust/syn/file.rs | 127 + rust/syn/fixup.rs | 775 +++ rust/syn/gen/clone.rs | 2269 +++++++++ rust/syn/gen/debug.rs | 3240 +++++++++++++ rust/syn/gen/eq.rs | 2308 +++++++++ rust/syn/gen/fold.rs | 3904 +++++++++++++++ rust/syn/gen/hash.rs | 2878 ++++++++++++ rust/syn/gen/visit.rs | 3943 ++++++++++++++++ rust/syn/gen/visit_mut.rs | 3761 +++++++++++++++ rust/syn/generics.rs | 1479 ++++++ rust/syn/group.rs | 293 ++ rust/syn/ident.rs | 110 + rust/syn/item.rs | 3492 ++++++++++++++ rust/syn/lib.rs | 1013 ++++ rust/syn/lifetime.rs | 158 + rust/syn/lit.rs | 1862 ++++++++ rust/syn/lookahead.rs | 334 ++ rust/syn/mac.rs | 227 + rust/syn/macros.rs | 184 + rust/syn/meta.rs | 429 ++ rust/syn/op.rs | 221 + rust/syn/parse.rs | 1421 ++++++ rust/syn/parse_macro_input.rs | 130 + rust/syn/parse_quote.rs | 242 + rust/syn/pat.rs | 957 ++++ rust/syn/path.rs | 968 ++++ rust/syn/precedence.rs | 212 + rust/syn/print.rs | 18 + rust/syn/punctuated.rs | 1157 +++++ rust/syn/restriction.rs | 180 + rust/syn/scan_expr.rs | 267 ++ rust/syn/sealed.rs | 6 + rust/syn/span.rs | 65 + rust/syn/spanned.rs | 120 + rust/syn/stmt.rs | 486 ++ rust/syn/thread.rs | 62 + rust/syn/token.rs | 1098 +++++ rust/syn/tt.rs | 109 + rust/syn/ty.rs | 1273 +++++ rust/syn/verbatim.rs | 35 + rust/syn/whitespace.rs | 67 + scripts/generate_rust_analyzer.py | 23 +- 83 files changed, 57895 insertions(+), 13 deletions(-) create mode 100644 rust/proc-macro2/README.md create mode 100644 rust/proc-macro2/detection.rs create mode 100644 rust/proc-macro2/extra.rs create mode 100644 rust/proc-macro2/fallback.rs create mode 100644 rust/proc-macro2/lib.rs create mode 100644 rust/proc-macro2/location.rs create mode 100644 rust/proc-macro2/marker.rs create mode 100644 rust/proc-macro2/parse.rs create mode 100644 rust/proc-macro2/probe.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span_file.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span_location.rs create mode 100644 rust/proc-macro2/rcvec.rs create mode 100644 rust/proc-macro2/wrapper.rs create mode 100644 rust/quote/README.md create mode 100644 rust/quote/ext.rs create mode 100644 rust/quote/format.rs create mode 100644 rust/quote/ident_fragment.rs create mode 100644 rust/quote/lib.rs create mode 100644 rust/quote/runtime.rs create mode 100644 rust/quote/spanned.rs create mode 100644 rust/quote/to_tokens.rs create mode 100644 rust/syn/README.md create mode 100644 rust/syn/attr.rs create mode 100644 rust/syn/bigint.rs create mode 100644 rust/syn/buffer.rs create mode 100644 rust/syn/classify.rs create mode 100644 rust/syn/custom_keyword.rs create mode 100644 rust/syn/custom_punctuation.rs create mode 100644 rust/syn/data.rs create mode 100644 rust/syn/derive.rs create mode 100644 rust/syn/discouraged.rs create mode 100644 rust/syn/drops.rs create mode 100644 rust/syn/error.rs create mode 100644 rust/syn/export.rs create mode 100644 rust/syn/expr.rs create mode 100644 rust/syn/ext.rs create mode 100644 rust/syn/file.rs create mode 100644 rust/syn/fixup.rs create mode 100644 rust/syn/gen/clone.rs create mode 100644 rust/syn/gen/debug.rs create mode 100644 rust/syn/gen/eq.rs create mode 100644 rust/syn/gen/fold.rs create mode 100644 rust/syn/gen/hash.rs create mode 100644 rust/syn/gen/visit.rs create mode 100644 rust/syn/gen/visit_mut.rs create mode 100644 rust/syn/generics.rs create mode 100644 rust/syn/group.rs create mode 100644 rust/syn/ident.rs create mode 100644 rust/syn/item.rs create mode 100644 rust/syn/lib.rs create mode 100644 rust/syn/lifetime.rs create mode 100644 rust/syn/lit.rs create mode 100644 rust/syn/lookahead.rs create mode 100644 rust/syn/mac.rs create mode 100644 rust/syn/macros.rs create mode 100644 rust/syn/meta.rs create mode 100644 rust/syn/op.rs create mode 100644 rust/syn/parse.rs create mode 100644 rust/syn/parse_macro_input.rs create mode 100644 rust/syn/parse_quote.rs create mode 100644 rust/syn/pat.rs create mode 100644 rust/syn/path.rs create mode 100644 rust/syn/precedence.rs create mode 100644 rust/syn/print.rs create mode 100644 rust/syn/punctuated.rs create mode 100644 rust/syn/restriction.rs create mode 100644 rust/syn/scan_expr.rs create mode 100644 rust/syn/sealed.rs create mode 100644 rust/syn/span.rs create mode 100644 rust/syn/spanned.rs create mode 100644 rust/syn/stmt.rs create mode 100644 rust/syn/thread.rs create mode 100644 rust/syn/token.rs create mode 100644 rust/syn/tt.rs create mode 100644 rust/syn/ty.rs create mode 100644 rust/syn/verbatim.rs create mode 100644 rust/syn/whitespace.rs
--
2.51.2
Miguel Ojeda
maintainerPATCH 1/18 rust: condvar: avoid `pub` in example
The future move of pin-init to syn uncovers the following unreachable public item in an example:
error: unreachable `pub` item
--> rust/doctests_kernel_generated.rs:14683:1
|
14683 | pub struct Example {
| ---^^^^^^^^^^^^^^^
| |
| help: consider restricting its visibility: `pub(crate)`
|
= help: or consider exporting it for use by other crates
= note: `-D unreachable-pub` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(unreachable_pub)]`There is no real downside of keeping the example as-is until the syn-based pin-init is introduced, so there is no need to treat it as a fix nor to backport it. However, we still need to change it before introducing the new pin-init.
Thus do so.
--- rust/kernel/sync/condvar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/sync/condvar.rs +1 -1
@@ -46,7 +46,7 @@ macro_rules! new_condvar {/// use kernel::sync::{new_condvar, new_mutex, CondVar, Mutex}; /// /// #[pin_data] -/// pub struct Example { +/// struct Example { /// #[pin] /// value: Mutex<u32>, ///
Signature · 1 line
2.51.2
Re: [PATCH 01/18] rust: condvar: avoid `pub` in example
Quoted 15 lines · Miguel Ojeda
The future move of pin-init to
synuncovers the following unreachable public item in an example:error: unreachable `pub` item --> rust/doctests_kernel_generated.rs:14683:1 | 14683 | pub struct Example { | ---^^^^^^^^^^^^^^^ | | | help: consider restricting its visibility: `pub(crate)` | = help: or consider exporting it for use by other crates = note: `-D unreachable-pub` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unreachable_pub)]`
Quoted 8 lines
There is no real downside of keeping the example as-is until the
syn-based pin-init is introduced, so there is no need to treat it as a fix nor to backport it. However, we still need to change it before introducing the new pin-init.Thus do so.
Signed-off-by Miguel Ojeda <[email protected]>
The unreachable_pub warning normally does not trigger for documentation tests since using pub in documentation tests is not wrong. So this sounds like a bug in our doc-test setup.
Regardless, I don't mind changing it here for now.
Re: [PATCH 01/18] rust: condvar: avoid `pub` in example
Quoted 4 lines · Alice Ryhl
The
unreachable_pubwarning normally does not trigger for documentation tests since usingpubin documentation tests is not wrong. So this sounds like a bug in our doc-test setup.
Yeah, we can allow the warning for doctests, that is easy.
In any case, this was needed for the future pin-init, not the current one, so I should have probably removed it (we had a bigger branch with the new pin-init).
Cheers,
Miguel
Miguel Ojeda
maintainerPATCH 2/18 rust: kbuild: introduce `core-flags` and `core-skip_flags`
In reply to Miguel OjedaIn the next commits we are introducing *-{cfgs,skip_flags,flags} variables for other crates.
Thus do so here for core, which simplifies a bit the Makefile (including the next commit) and makes it more consistent.
This means we stop passing -Wrustdoc::unescaped_backticks to rustc and -Wunreachable_pub to rustdoc, i.e. we skip more, which is fine since it shouldn't have an effect.
--- rust/Makefile | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
rust/Makefile +14 -5
@@ -60,11 +60,20 @@ rustdoc_test_quiet=--test-args -q rustdoc_test_kernel_quiet=>/dev/null endif -core-cfgs = \ +core-cfgs := \ --cfg no_fp_fmt_parse core-edition := $(if $(call rustc-min-version,108700),2024,2021) +core-skip_flags := \ + --edition=2021 \ + -Wunreachable_pub \ + -Wrustdoc::unescaped_backticks + +core-flags := \ + --edition=$(core-edition) \ + $(core-cfgs) + # `rustdoc` did not save the target modifiers, thus workaround for # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18)
@@ -125,8 +134,8 @@ rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean FORCE # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should # not be needed -- see https://github.com/rust-lang/rust/pull/128307. -rustdoc-core: private skip_flags = --edition=2021 -Wrustdoc::unescaped_backticks -rustdoc-core: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) +rustdoc-core: private skip_flags = $(core-skip_flags) +rustdoc-core: private rustc_target_flags = $(core-flags) rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs rustdoc-clean FORCE +$(call if_changed,rustdoc)
@@ -508,9 +517,9 @@ $(obj)/helpers/helpers.o: $(src)/helpers/helpers.c $(recordmcount_source) FORCE $(obj)/exports.o: private skip_gendwarfksyms = 1 $(obj)/core.o: private skip_clippy = 1 -$(obj)/core.o: private skip_flags = --edition=2021 -Wunreachable_pub +$(obj)/core.o: private skip_flags = $(core-skip_flags) $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) -$(obj)/core.o: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) +$(obj)/core.o: private rustc_target_flags = $(core-flags) $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \ $(wildcard $(objtree)/include/config/RUSTC_VERSION_TEXT) FORCE +$(call if_changed_rule,rustc_library)
Signature · 1 line
2.51.2
Re: [PATCH 02/18] rust: kbuild: introduce `core-flags` and `core-skip_flags`
Quoted 3 lines · Miguel Ojeda
Thus do so here for
core, which simplifies a bit theMakefile(including the next commit) and makes it more consistent.
We may want to eventually use --cap-lints=allow here too, but the skip flags here were already feeling a bit more than needed for the series.
Cheers,
Miguel
Alice Ryhl
maintainerRe: [PATCH 02/18] rust: kbuild: introduce `core-flags` and `core-skip_flags`
Quoted 8 lines · Miguel Ojeda
Quoted 3 lines · Miguel Ojeda
Thus do so here for
core, which simplifies a bit theMakefile(including the next commit) and makes it more consistent.We may want to eventually use
--cap-lints=allowhere too, but the skip flags here were already feeling a bit more than needed for the series.
Using cap-lints allow for core sgtm.
Alice
Re: [PATCH 02/18] rust: kbuild: introduce `core-flags` and `core-skip_flags`
In reply to Miguel OjedaQuoted 11 lines · Miguel Ojeda
In the next commits we are introducing
*-{cfgs,skip_flags,flags}variables for other crates.Thus do so here for
core, which simplifies a bit theMakefile(including the next commit) and makes it more consistent.This means we stop passing
-Wrustdoc::unescaped_backtickstorustcand-Wunreachable_pubtorustdoc, i.e. we skip more, which is fine since it shouldn't have an effect.Signed-off-by Miguel Ojeda <[email protected]>
Re: [PATCH 02/18] rust: kbuild: introduce `core-flags` and `core-skip_flags`
In reply to Miguel OjedaQuoted 20 lines · Miguel Ojeda
In the next commits we are introducing
*-{cfgs,skip_flags,flags}variables for other crates.Thus do so here for
core, which simplifies a bit theMakefile(including the next commit) and makes it more consistent.This means we stop passing
-Wrustdoc::unescaped_backtickstorustcand-Wunreachable_pubtorustdoc, i.e. we skip more, which is fine since it shouldn't have an effect.Signed-off-by Miguel Ojeda <[email protected]>--- rust/Makefile | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)rust/Makefile +0
-0
rust/Makefile rustdoc_test_quiet=--test-args -q · line 63
Quoted 5 lines
rust/Makefile +1
-1@@ -60,11 +60,20 @@ rustdoc_test_quiet=--test-args -q rustdoc_test_kernel_quiet=>/dev/null endif -core-cfgs = \ +core-cfgs := \
I agree that switching to ":=" for this kind of Makefile variable is a good move. However, it should be mentioned in the commit log so that it doesn't look like it was accidentally introduced.
thanks,
Signature · 1 line
John Hubbard
Quoted 39 lines
rust/Makefile +13
-4--cfg no_fp_fmt_parse core-edition := $(if $(call rustc-min-version,108700),2024,2021) +core-skip_flags := \ + --edition=2021 \ + -Wunreachable_pub \ + -Wrustdoc::unescaped_backticks + +core-flags := \ + --edition=$(core-edition) \ + $(core-cfgs) + # `rustdoc` did not save the target modifiers, thus workaround for # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18)@@ -125,8 +134,8 @@ rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean FORCE # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should # not be needed -- see https://github.com/rust-lang/rust/pull/128307. -rustdoc-core: private skip_flags = --edition=2021 -Wrustdoc::unescaped_backticks -rustdoc-core: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) +rustdoc-core: private skip_flags = $(core-skip_flags) +rustdoc-core: private rustc_target_flags = $(core-flags) rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs rustdoc-clean FORCE +$(call if_changed,rustdoc)@@ -508,9 +517,9 @@ $(obj)/helpers/helpers.o: $(src)/helpers/helpers.c $(recordmcount_source) FORCE $(obj)/exports.o: private skip_gendwarfksyms = 1 $(obj)/core.o: private skip_clippy = 1 -$(obj)/core.o: private skip_flags = --edition=2021 -Wunreachable_pub +$(obj)/core.o: private skip_flags = $(core-skip_flags) $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) -$(obj)/core.o: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) +$(obj)/core.o: private rustc_target_flags = $(core-flags) $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \ $(wildcard $(objtree)/include/config/RUSTC_VERSION_TEXT) FORCE +$(call if_changed_rule,rustc_library)
Re: [PATCH 02/18] rust: kbuild: introduce `core-flags` and `core-skip_flags`
Quoted 4 lines · John Hubbard
I agree that switching to ":=" for this kind of
Makefilevariable is a good move. However, it should be mentioned in the commit log so that it doesn't look like it was accidentally introduced.
It was meant to make it consistent with the upcoming additions since this commit is essentially about that, i.e. it was not intended as a drive-by cleanup (which I usually oppose), if that makes sense.
I will clarify in the log.
Thanks for taking a look!
Cheers,
Miguel
Miguel Ojeda
maintainerPATCH 3/18 rust: kbuild: simplify `--cfg` handling
In reply to Miguel OjedaWe need to handle cfgs in both rustc and rust-analyzer, and in future commits some of those contain double quotes, which complicates things further.
Thus, instead of removing the --cfg part in the rust-analyzer generation script, have the *-cfgs variables contain just the actual cfg, and use that to generate the actual flags in *-flags.
--- rust/Makefile | 6 ++++-- scripts/generate_rust_analyzer.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-)
rust/Makefile +4 -2
@@ -60,8 +60,10 @@ rustdoc_test_quiet=--test-args -q rustdoc_test_kernel_quiet=>/dev/null endif +cfgs-to-flags = $(patsubst %,--cfg='%',$1) + core-cfgs := \ - --cfg no_fp_fmt_parse + no_fp_fmt_parse core-edition := $(if $(call rustc-min-version,108700),2024,2021)
@@ -72,7 +74,7 @@ core-skip_flags := \ core-flags := \ --edition=$(core-edition) \ - $(core-cfgs) + $(call cfgs-to-flags,$(core-cfgs)) # `rustdoc` did not save the target modifiers, thus workaround for # the time being (https://github.com/rust-lang/rust/issues/144521).
scripts/generate_rust_analyzer.py +1 -1
@@ -15,7 +15,7 @@ def args_crates_cfgs(cfgs): crates_cfgs = {} for cfg in cfgs: crate, vals = cfg.split("=", 1) - crates_cfgs[crate] = vals.replace("--cfg", "").split() + crates_cfgs[crate] = vals.split() return crates_cfgs
Signature · 1 line
2.51.2
Re: [PATCH 03/18] rust: kbuild: simplify `--cfg` handling
Quoted 9 lines · Miguel Ojeda
We need to handle
cfgs in bothrustcandrust-analyzer, and in future commits some of those contain double quotes, which complicates things further.Thus, instead of removing the
--cfgpart in the rust-analyzer generation script, have the*-cfgsvariables contain just the actualcfg, and use that to generate the actual flags in*-flags.Signed-off-by Miguel Ojeda <[email protected]>
For anyone else reviewing this, here is the relevant part of the makefile that calls generate_rust_analyzer:
rust-analyzer:
$(Q)MAKEFLAGS= $(srctree)/scripts/generate_rust_analyzer.py \ --cfgs='core=$(core-cfgs)' $(core-edition) \ $(realpath $(srctree)) $(realpath $(objtree)) \ $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ > rust-project.json
Miguel Ojeda
maintainerPATCH 4/18 rust: kbuild: add host library support
In reply to Miguel OjedaAdd the a host library rule that produces .rlib files to be used by the macros crate.
--- .gitignore | 1 + rust/Makefile | 10 ++++++++++ 2 files changed, 11 insertions(+)
.gitignore +1 -0
@@ -41,6 +41,7 @@ *.o.* *.patch *.pyc +*.rlib *.rmeta *.rpm *.rsi
rust/Makefile +10 -0
@@ -430,6 +430,16 @@ $(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE $(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE $(call if_changed,exports) +quiet_cmd_rustc_hostlibrary = $(RUSTC_OR_CLIPPY_QUIET) H $@ + cmd_rustc_hostlibrary = \ + $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ + $(filter-out $(skip_flags),$(rust_common_flags) $(rustc_target_flags)) \ + --emit=dep-info,link --crate-type rlib -O \ + --out-dir $(objtree)/$(obj) -L$(objtree)/$(obj) \ + --crate-name $(patsubst lib%.rlib,%,$(notdir $@)) $<; \ + mv $(objtree)/$(obj)/$(patsubst lib%.rlib,%,$(notdir $@)).d $(depfile); \ + sed -i '/^\#/d' $(depfile) + quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ cmd_rustc_procmacro = \ $(RUSTC_OR_CLIPPY) $(rust_common_flags) $(rustc_target_flags) \
Signature · 1 line
2.51.2
Alice Ryhl
maintainerRe: [PATCH 04/18] rust: kbuild: add host library support
Quoted 4 lines · Miguel Ojeda
Add the a host library rule that produces
.rlibfiles to be used by themacroscrate.Signed-off-by Miguel Ojeda <[email protected]>
We currently have two kinds of build rules:
* cmd_host-rust used for host binaries such as generate_rust_target
* cmd_rustc_procmacro used for proc macros
This is a library for the second case, not the first case, so it may make more sense to name this rule procmacrolibrary?
Note that HOSTRUSTFLAGS is passed to only the first category, but this naming makes it sound like it should be passed to this new build rule, but I don't think it should be since it is not passed to proc macros.
Alice
Re: [PATCH 04/18] rust: kbuild: add host library support
Quoted 3 lines · Alice Ryhl
This is a library for the second case, not the first case, so it may make more sense to name this rule procmacrolibrary?
Making it more concrete sounds good to me. We can always rename later if we find some other use.
Cheers,
Miguel
Miguel Ojeda
maintainerPATCH 5/18 rust: proc-macro2: import crate
In reply to Miguel OjedaThis is a subset of the Rust proc-macro2 crate, version 1.0.101 (released 2025-08-16), licensed under "Apache-2.0 OR MIT", from:
https://github.com/dtolnay/proc-macro2/raw/1.0.101/src
The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers).
For copyright details, please see:
https://github.com/dtolnay/proc-macro2/blob/1.0.101/README.md#license https://github.com/dtolnay/proc-macro2/blob/1.0.101/LICENSE-APACHE https://github.com/dtolnay/proc-macro2/blob/1.0.101/LICENSE-MIT
The next two patches modify these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced.
The following script may be used to verify the contents:
for path in $(cd rust/proc-macro2/ && find . -type f -name '*.rs'); do
curl --silent --show-error --location \
https://github.com/dtolnay/proc-macro2/raw/1.0.101/src/$path \
| diff --unified rust/proc-macro2/$path - && echo $path: OK
done--- rust/proc-macro2/detection.rs | 75 + rust/proc-macro2/extra.rs | 151 ++ rust/proc-macro2/fallback.rs | 1256 +++++++++++++++ rust/proc-macro2/lib.rs | 1349 +++++++++++++++++ rust/proc-macro2/location.rs | 29 + rust/proc-macro2/marker.rs | 17 + rust/proc-macro2/parse.rs | 995 ++++++++++++ rust/proc-macro2/probe.rs | 10 + rust/proc-macro2/probe/proc_macro_span.rs | 51 + .../proc-macro2/probe/proc_macro_span_file.rs | 14 + .../probe/proc_macro_span_location.rs | 21 + rust/proc-macro2/rcvec.rs | 146 ++ rust/proc-macro2/wrapper.rs | 984 ++++++++++++ 13 files changed, 5098 insertions(+) create mode 100644 rust/proc-macro2/detection.rs create mode 100644 rust/proc-macro2/extra.rs create mode 100644 rust/proc-macro2/fallback.rs create mode 100644 rust/proc-macro2/lib.rs create mode 100644 rust/proc-macro2/location.rs create mode 100644 rust/proc-macro2/marker.rs create mode 100644 rust/proc-macro2/parse.rs create mode 100644 rust/proc-macro2/probe.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span_file.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span_location.rs create mode 100644 rust/proc-macro2/rcvec.rs create mode 100644 rust/proc-macro2/wrapper.rs
rust/proc-macro2/detection.rs new file +75 -0
@@ -0,0 +1,75 @@ +use core::sync::atomic::{AtomicUsize ,Ordering }; +use std::sync::Once ; + +static WORKS :AtomicUsize =AtomicUsize ::new (0 ); +static INIT :Once =Once ::new (); + +pub (crate )fn inside_proc_macro () ->bool { +match WORKS .load (Ordering ::Relaxed ) { +1 =>return false , +2 =>return true , + _ => {} + } + +INIT .call_once (initialize); +inside_proc_macro () +} + +pub (crate )fn force_fallback () { +WORKS .store (1 ,Ordering ::Relaxed ); +} + +pub (crate )fn unforce_fallback () { +initialize (); +} + +#[cfg(not(no_is_available))] +fn initialize () { +let available = proc_macro::is_available (); +WORKS .store (availableas usize +1 ,Ordering ::Relaxed ); +} + +// Swap in a null panic hook to avoid printing "thread panicked" to stderr, +// then use catch_unwind to determine whether the compiler's proc_macro is +// working. When proc-macro2 is used from outside of a procedural macro all +// of the proc_macro crate's APIs currently panic. +// +// The Once is to prevent the possibility of this ordering: +// +// thread 1 calls take_hook, gets the user's original hook +// thread 1 calls set_hook with the null hook +// thread 2 calls take_hook, thinks null hook is the original hook +// thread 2 calls set_hook with the null hook +// thread 1 calls set_hook with the actual original hook +// thread 2 calls set_hook with what it thinks is the original hook +// +// in which the user's hook has been lost. +// +// There is still a race condition where a panic in a different thread can +// happen during the interval that the user's original panic hook is +// unregistered such that their hook is incorrectly not called. This is +// sufficiently unlikely and less bad than printing panic messages to stderr +// on correct use of this crate. Maybe there is a libstd feature request +// here. For now, if a user needs to guarantee that this failure mode does +// not occur, they need to call e.g. `proc_macro2::Span::call_site()` from +// the main thread before launching any other threads. +#[cfg(no_is_available)] +fn initialize () { +use std::panic::{self,PanicInfo }; + +type PanicHook =dyn Fn (&PanicInfo ) +Sync +Send + 'static; + +let null_hook:Box <PanicHook > =Box ::new (|_panic_info| {/* ignore */ }); +let sanity_check = &*null_hookas *const PanicHook ; +let original_hook = panic::take_hook (); + panic::set_hook (null_hook); + +let works = panic::catch_unwind (proc_macro::Span ::call_site).is_ok (); +WORKS .store (worksas usize +1 ,Ordering ::Relaxed ); + +let hopefully_null_hook = panic::take_hook (); + panic::set_hook (original_hook); +if sanity_check != &*hopefully_null_hook { +panic! ("observed race condition in proc_macro2::inside_proc_macro" ); + } +}
rust/proc-macro2/extra.rs new file +151 -0
151 lines not on this page · raw message
rust/proc-macro2/fallback.rs new file +1256 -0
1,256 lines not on this page · raw message
rust/proc-macro2/lib.rs new file +1349 -0
1,349 lines not on this page · raw message
rust/proc-macro2/location.rs new file +29 -0
@@ -0,0 +1,29 @@ +use core::cmp::Ordering ; + +/// A line-column pair representing the start or end of a `Span`. +/// +/// This type is semver exempt and not exposed by default. +#[cfg_attr(docsrs, doc(cfg(feature = "span-locations" )))] +#[derive( Copy , Clone , Debug , PartialEq , Eq , Hash )] +pub struct LineColumn { +/// The 1-indexed line in the source file on which the span starts or ends +/// (inclusive). +pub line:usize , +/// The 0-indexed column (in UTF-8 characters) in the source file on which +/// the span starts or ends (inclusive). +pub column:usize , +} + +impl Ord for LineColumn { +fn cmp (&self, other: &Self ) ->Ordering { + self.line + .cmp (&other.line) + .then (self.column.cmp (&other.column)) + } +} + +impl PartialOrd for LineColumn { +fn partial_cmp (&self, other: &Self ) ->Option <Ordering > { +Some (self.cmp (other)) + } +}
rust/proc-macro2/marker.rs new file +17 -0
@@ -0,0 +1,17 @@ +use alloc::rc::Rc ; +use core::marker::PhantomData ; +use core::panic::{RefUnwindSafe ,UnwindSafe }; + +// Zero sized marker with the correct set of autotrait impls we want all proc +// macro types to have. +#[derive( Copy , Clone )] +#[cfg_attr( +all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)), +derive( PartialEq , Eq ) +)] +pub (crate )struct ProcMacroAutoTraits (PhantomData <Rc <()>>); + +pub (crate )const MARKER :ProcMacroAutoTraits =ProcMacroAutoTraits (PhantomData ); + +impl UnwindSafe for ProcMacroAutoTraits {} +impl RefUnwindSafe for ProcMacroAutoTraits {}
rust/proc-macro2/parse.rs new file +995 -0
123 lines not on this page · raw message
rust/proc-macro2/probe/proc_macro_span.rs new file +51 -0
51 lines not on this page · raw message
rust/proc-macro2/probe/proc_macro_span_file.rs new file +14 -0
Lines of this file are not shown. View the raw message.
rust/proc-macro2/probe/proc_macro_span_location.rs new file +21 -0
Lines of this file are not shown. View the raw message.
rust/proc-macro2/rcvec.rs new file +146 -0
146 lines not on this page · raw message
rust/proc-macro2/wrapper.rs new file +984 -0
984 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.51.2
Part of the diff is not shown here. View the raw message.
Miguel Ojeda
maintainerPATCH 6/18 rust: proc-macro2: add SPDX License Identifiers
In reply to Miguel OjedaOriginally, when the Rust upstream alloc standard library crate was vendored in commit 057b8d257107 ("rust: adapt alloc crate to the kernel"), the SPDX License Identifiers were added to every file so that the license on those was clear.
Thus do the same for the proc-macro2 crate.
This makes scripts/spdxcheck.py pass.
--- rust/proc-macro2/detection.rs | 2 ++ rust/proc-macro2/extra.rs | 2 ++ rust/proc-macro2/fallback.rs | 2 ++ rust/proc-macro2/lib.rs | 2 ++ rust/proc-macro2/location.rs | 2 ++ rust/proc-macro2/marker.rs | 2 ++ rust/proc-macro2/parse.rs | 2 ++ rust/proc-macro2/probe.rs | 2 ++ rust/proc-macro2/probe/proc_macro_span.rs | 2 ++ rust/proc-macro2/probe/proc_macro_span_file.rs | 2 ++ rust/proc-macro2/probe/proc_macro_span_location.rs | 2 ++ rust/proc-macro2/rcvec.rs | 2 ++ rust/proc-macro2/wrapper.rs | 2 ++ 13 files changed, 26 insertions(+)
rust/proc-macro2/detection.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use core::sync::atomic::{AtomicUsize ,Ordering };use std::sync::Once ;
rust/proc-macro2/extra.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! Items which do not have a correspondence to any API in the proc_macro crate, //! but are necessary to include in proc-macro2.
rust/proc-macro2/fallback.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(wrap_proc_macro)] use crate ::imp;#[cfg(span_locations)]
rust/proc-macro2/lib.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! [![github]](https://github.com/dtolnay/proc-macro2) [![crates-io]](https://crates.io/crates/proc-macro2) [![docs-rs]](crate) //! //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
rust/proc-macro2/location.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use core::cmp::Ordering ;/// A line-column pair representing the start or end of a `Span`.
rust/proc-macro2/marker.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use alloc::rc::Rc ;use core::marker::PhantomData ;use core::panic::{RefUnwindSafe ,UnwindSafe };
rust/proc-macro2/parse.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::fallback::{ self, is_ident_continue, is_ident_start,Group ,Ident ,LexError ,Literal ,Span ,TokenStream ,TokenStreamBuilder ,
rust/proc-macro2/probe.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#![allow(dead_code)] #[cfg(proc_macro_span)]
rust/proc-macro2/probe/proc_macro_span.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This code exercises the surface area that we expect of Span's unstable API. // If the current toolchain is able to compile it, then proc-macro2 is able to // offer these APIs too.
rust/proc-macro2/probe/proc_macro_span_file.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// The subset of Span's API stabilized in Rust 1.88. extern crate proc_macro;
rust/proc-macro2/probe/proc_macro_span_location.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// The subset of Span's API stabilized in Rust 1.88. extern crate proc_macro;
rust/proc-macro2/rcvec.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use alloc::rc::Rc ;use alloc::vec;use core::mem;
rust/proc-macro2/wrapper.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::detection::inside_proc_macro;use crate ::fallback::{self,FromStr2 as _};#[cfg(span_locations)]
Signature · 1 line
2.51.2
Miguel Ojeda
maintainerPATCH 7/18 rust: proc-macro2: remove `unicode_ident` dependency
In reply to Miguel OjedaThe proc-macro2 crate depends on the unicode-ident crate to determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31.
However, we only need ASCII identifiers in the kernel, thus we can simplify the check and remove completely that dependency.
--- rust/proc-macro2/fallback.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
rust/proc-macro2/fallback.rs +2 -2
@@ -818,11 +818,11 @@ pub(crate) fn set_span(&mut self, span: Span) { }pub (crate )fn is_ident_start (c:char ) ->bool { - c =='_' || unicode_ident::is_xid_start (c) + c =='_' || c.is_ascii_alphabetic () }pub (crate )fn is_ident_continue (c:char ) ->bool { - unicode_ident::is_xid_continue (c) + c =='_' || c.is_ascii_alphanumeric () }#[track_caller]
Signature · 1 line
2.51.2
Re: [PATCH 07/18] rust: proc-macro2: remove `unicode_ident` dependency
Quoted 8 lines · Miguel Ojeda
The
proc-macro2crate depends on theunicode-identcrate to determine whether characters have theXID_StartorXID_Continueproperties according to Unicode Standard Annex #31.However, we only need ASCII identifiers in the kernel, thus we can simplify the check and remove completely that dependency.
Signed-off-by Miguel Ojeda <[email protected]>
Verified that these match exactly for ascii characters.
Miguel Ojeda
maintainerPATCH 8/18 rust: proc-macro2: add `README.md`
In reply to Miguel OjedaOriginally, when the Rust upstream alloc standard library crate was vendored in commit 057b8d257107 ("rust: adapt alloc crate to the kernel"), a README.md file was added to explain the provenance and licensing of the source files.
Thus do the same for the proc-macro2 crate.
--- rust/proc-macro2/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 rust/proc-macro2/README.md
rust/proc-macro2/README.md new file +13 -0
@@ -0,0 +1,13 @@ +# `proc-macro2` + +These source files come from the Rust `proc-macro2` crate, version +1.0.101 (released 2025-08-16), hosted in the +<https://github.com/dtolnay/proc-macro2> repository, licensed under +"Apache-2.0 OR MIT" and only modified to add the SPDX license +identifiers and to remove the `unicode-ident` dependency. + +For copyright details, please see: + + https://github.com/dtolnay/proc-macro2/blob/1.0.101/README.md#license + https://github.com/dtolnay/proc-macro2/blob/1.0.101/LICENSE-APACHE + https://github.com/dtolnay/proc-macro2/blob/1.0.101/LICENSE-MIT
Signature · 1 line
2.51.2
Re: [PATCH 08/18] rust: proc-macro2: add `README.md`
Quoted 22 lines · Miguel Ojeda
Originally, when the Rust upstream
allocstandard library crate was vendored in commit057b8d257107("rust: adaptalloccrate to the kernel"), aREADME.mdfile was added to explain the provenance and licensing of the source files.Thus do the same for the
proc-macro2crate.Signed-off-by Miguel Ojeda <[email protected]>--- rust/proc-macro2/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 rust/proc-macro2/README.mdrust/proc-macro2/README.md new file +3
-0@@ -0,0 +1,13 @@ +# `proc-macro2` + +These source files come from the Rust `proc-macro2` crate, version
rust/proc-macro2/README.md line 13
Quoted 10 lines
rust/proc-macro2/README.md new file +10
-0+1.0.101 (released 2025-08-16), hosted in the +<https://github.com/dtolnay/proc-macro2> repository, licensed under +"Apache-2.0 OR MIT" and only modified to add the SPDX license +identifiers and to remove the `unicode-ident` dependency. + +For copyright details, please see: + + https://github.com/dtolnay/proc-macro2/blob/1.0.101/README.md#license + https://github.com/dtolnay/proc-macro2/blob/1.0.101/LICENSE-APACHE + https://github.com/dtolnay/proc-macro2/blob/1.0.101/LICENSE-MIT
Miguel Ojeda
maintainerPATCH 9/18 rust: proc-macro2: enable support in kbuild
In reply to Miguel OjedaWith all the new files in place and ready from the new crate, enable the support for it in the build system.
proc_macro_byte_character and proc_macro_c_str_literals were stabilized in Rust 1.79.0 [1] and were implemented earlier than our minimum Rust version (1.78) [2][3]. Thus just enable them instead of using the cfg that proc-macro2 uses to emulate them in older compilers.
--- Makefile | 3 +++ rust/Makefile | 32 +++++++++++++++++++++++++++++-- scripts/generate_rust_analyzer.py | 7 +++++++ 3 files changed, 40 insertions(+), 2 deletions(-)
Makefile +3 -0
@@ -1830,6 +1830,9 @@ PHONY += rustfmt rustfmtcheck rustfmt: $(Q)find $(srctree) $(RCS_FIND_IGNORE) \ + \( \ + -path $(srctree)/rust/proc-macro2 \ + \) -prune -o \ -type f -a -name '*.rs' -a ! -name '*generated*' -print \ | xargs $(RUSTFMT) $(rustfmt_flags)
rust/Makefile +30 -2
@@ -27,6 +27,8 @@ endif obj-$(CONFIG_RUST) += exports.o +always-$(CONFIG_RUST) += libproc_macro2.rlib + always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.rs always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c
@@ -76,6 +78,17 @@ core-flags := \ --edition=$(core-edition) \ $(call cfgs-to-flags,$(core-cfgs)) +proc_macro2-cfgs := \ + feature="proc-macro" \ + wrap_proc_macro \ + $(if $(call rustc-min-version,108800),proc_macro_span_file proc_macro_span_location) + +# Stable since Rust 1.79.0: `feature(proc_macro_byte_character,proc_macro_c_str_literals)`. +proc_macro2-flags := \ + --cap-lints=allow \ + -Zcrate-attr='feature(proc_macro_byte_character,proc_macro_c_str_literals)' \ + $(call cfgs-to-flags,$(proc_macro2-cfgs)) + # `rustdoc` did not save the target modifiers, thus workaround for # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18)
@@ -128,10 +141,15 @@ rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ $(Q)for f in $(rustdoc_output)/static.files/rustdoc-*.css; do \ echo ".logo-container > img { object-fit: contain; }" >> $$f; done +rustdoc-proc_macro2: private rustdoc_host = yes +rustdoc-proc_macro2: private rustc_target_flags = $(proc_macro2-flags) +rustdoc-proc_macro2: $(src)/proc-macro2/lib.rs rustdoc-clean FORCE + +$(call if_changed,rustdoc) + rustdoc-macros: private rustdoc_host = yes rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ --extern proc_macro -rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean FORCE +rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean rustdoc-proc_macro2 FORCE +$(call if_changed,rustdoc) # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should
@@ -194,6 +212,10 @@ rusttestlib-build_error: $(src)/build_error.rs FORCE rusttestlib-ffi: $(src)/ffi.rs FORCE +$(call if_changed,rustc_test_library) +rusttestlib-proc_macro2: private rustc_target_flags = $(proc_macro2-flags) +rusttestlib-proc_macro2: $(src)/proc-macro2/lib.rs FORCE + +$(call if_changed,rustc_test_library) + rusttestlib-macros: private rustc_target_flags = --extern proc_macro rusttestlib-macros: private rustc_test_library_proc = yes rusttestlib-macros: $(src)/macros/lib.rs FORCE
@@ -440,6 +462,11 @@ quiet_cmd_rustc_hostlibrary = $(RUSTC_OR_CLIPPY_QUIET) H $@ mv $(objtree)/$(obj)/$(patsubst lib%.rlib,%,$(notdir $@)).d $(depfile); \ sed -i '/^\#/d' $(depfile) +$(obj)/libproc_macro2.rlib: private skip_clippy = 1 +$(obj)/libproc_macro2.rlib: private rustc_target_flags = $(proc_macro2-flags) +$(obj)/libproc_macro2.rlib: $(src)/proc-macro2/lib.rs FORCE + +$(call if_changed_dep,rustc_hostlibrary) + quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ cmd_rustc_procmacro = \ $(RUSTC_OR_CLIPPY) $(rust_common_flags) $(rustc_target_flags) \
@@ -451,7 +478,7 @@ quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ @$(objtree)/include/generated/rustc_cfg $< # Procedural macros can only be used with the `rustc` that compiled it. -$(obj)/$(libmacros_name): $(src)/macros/lib.rs FORCE +$(obj)/$(libmacros_name): $(src)/macros/lib.rs $(obj)/libproc_macro2.rlib FORCE +$(call if_changed_dep,rustc_procmacro) $(obj)/$(libpin_init_internal_name): private rustc_target_flags = --cfg kernel
@@ -474,6 +501,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L rust-analyzer: $(Q)MAKEFLAGS= $(srctree)/scripts/generate_rust_analyzer.py \ --cfgs='core=$(core-cfgs)' $(core-edition) \ + --cfgs='proc_macro2=$(proc_macro2-cfgs)' \ $(realpath $(srctree)) $(realpath $(objtree)) \ $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ > rust-project.json
scripts/generate_rust_analyzer.py +7 -0
@@ -86,6 +86,13 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit [], ) + append_crate( + "proc_macro2", + srctree / "rust" / "proc-macro2" / "lib.rs", + ["core", "alloc", "std", "proc_macro"], + cfg=crates_cfgs["proc_macro2"], + ) + append_crate( "macros", srctree / "rust" / "macros" / "lib.rs",
Signature · 1 line
2.51.2
Alice Ryhl
maintainerRe: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
Quoted 50 lines · Miguel Ojeda
With all the new files in place and ready from the new crate, enable the support for it in the build system.
proc_macro_byte_characterandproc_macro_c_str_literalswere stabilized in Rust 1.79.0 [1] and were implemented earlier than our minimum Rust version (1.78) [2][3]. Thus just enable them instead of using thecfgthatproc-macro2uses to emulate them in older compilers.Signed-off-by Miguel Ojeda <[email protected]>--- Makefile | 3 +++ rust/Makefile | 32 +++++++++++++++++++++++++++++-- scripts/generate_rust_analyzer.py | 7 +++++++ 3 files changed, 40 insertions(+), 2 deletions(-)Makefile +3
-0@@ -1830,6 +1830,9 @@ PHONY += rustfmt rustfmtcheck rustfmt: $(Q)find $(srctree) $(RCS_FIND_IGNORE) \ + \( \ + -path $(srctree)/rust/proc-macro2 \ + \) -prune -o \ -type f -a -name '*.rs' -a ! -name '*generated*' -print \ | xargs $(RUSTFMT) $(rustfmt_flags)rust/Makefile +3
-0@@ -27,6 +27,8 @@ endif obj-$(CONFIG_RUST) += exports.o +always-$(CONFIG_RUST) += libproc_macro2.rlib + always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.rs always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c@@ -76,6 +78,17 @@ core-flags := \ --edition=$(core-edition) \ $(call cfgs-to-flags,$(core-cfgs)) +proc_macro2-cfgs := \
rust/Makefile core-flags := \ · line 91
Quoted 10 lines
rust/Makefile +10
-0+ feature="proc-macro" \ + wrap_proc_macro \ + $(if $(call rustc-min-version,108800),proc_macro_span_file proc_macro_span_location) + +# Stable since Rust 1.79.0: `feature(proc_macro_byte_character,proc_macro_c_str_literals)`. +proc_macro2-flags := \ + --cap-lints=allow \ + -Zcrate-attr='feature(proc_macro_byte_character,proc_macro_c_str_literals)' \ + $(call cfgs-to-flags,$(proc_macro2-cfgs)) +
I don't understand this. We enable the features even on 1.79, but we only pass the proc_macro_span_file, proc_macro_span_location cfgs on 1.88 and above?
We add the appropriate feature(_) invocations on older compilers, so should we not support those things on those compilers?
Alice
Gary Guo
maintainerRe: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
Quoted 66 lines · On Mon, 10 Nov 2025 11:38:04 +0000 Alice Ryhl <[email protected]> wrote:
Quoted 50 lines · Miguel Ojeda
With all the new files in place and ready from the new crate, enable the support for it in the build system.
proc_macro_byte_characterandproc_macro_c_str_literalswere stabilized in Rust 1.79.0 [1] and were implemented earlier than our minimum Rust version (1.78) [2][3]. Thus just enable them instead of using thecfgthatproc-macro2uses to emulate them in older compilers.Signed-off-by Miguel Ojeda <[email protected]>--- Makefile | 3 +++ rust/Makefile | 32 +++++++++++++++++++++++++++++-- scripts/generate_rust_analyzer.py | 7 +++++++ 3 files changed, 40 insertions(+), 2 deletions(-)Makefile +3
-0@@ -1830,6 +1830,9 @@ PHONY += rustfmt rustfmtcheck rustfmt: $(Q)find $(srctree) $(RCS_FIND_IGNORE) \ + \( \ + -path $(srctree)/rust/proc-macro2 \ + \) -prune -o \ -type f -a -name '*.rs' -a ! -name '*generated*' -print \ | xargs $(RUSTFMT) $(rustfmt_flags)rust/Makefile +3
-0@@ -27,6 +27,8 @@ endif obj-$(CONFIG_RUST) += exports.o +always-$(CONFIG_RUST) += libproc_macro2.rlib + always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.rs always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c@@ -76,6 +78,17 @@ core-flags := \ --edition=$(core-edition) \ $(call cfgs-to-flags,$(core-cfgs)) +proc_macro2-cfgs := \rust/Makefile core-flags := \ · line 91
Quoted 10 lines
rust/Makefile +10
-0+ feature="proc-macro" \ + wrap_proc_macro \ + $(if $(call rustc-min-version,108800),proc_macro_span_file proc_macro_span_location) + +# Stable since Rust 1.79.0: `feature(proc_macro_byte_character,proc_macro_c_str_literals)`. +proc_macro2-flags := \ + --cap-lints=allow \ + -Zcrate-attr='feature(proc_macro_byte_character,proc_macro_c_str_literals)' \ + $(call cfgs-to-flags,$(proc_macro2-cfgs)) +I don't understand this. We enable the features even on 1.79, but we only pass the
proc_macro_span_file,proc_macro_span_locationcfgs on 1.88 and above?
Quoted 4 lines
We add the appropriate
feature(_)invocations on older compilers, so should we not support those things on those compilers?Alice
For 1.79- it switches to any polyfill for byte_character and c_str_literals using cfg no_literal_byte_character and no_literal_c_string. These feature gates are stablised already so I think turning on features on makes sense for this scenario.
For 1.88+, Span::file, Span::line etc are stable so proc-macro2 can stop using polyfills. These APIs are not gated under specific feature gates before stablising however. They were gated under the generic proc_macro_span feature gate and only renamed to proc_macro_span_location during stabilisation. So in this case there's no already-stable feature flags to turn on. (proc_macro_span feature would make these APIs usable in 1.79, but that's a still-unstable feature flag in all versions of rustc).
So I think the implementation here is sensible. I believe Miguel's patch is also pretty much replicating the logic in proc-macro2's build.rs.
Best,
Gary
Re: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
Quoted 4 lines · Gary Guo
So I think the implementation here is sensible. I believe Miguel's patch is also pretty much replicating the logic in proc-macro2's
build.rs.
Exactly, I was essentially following what upstream does for stable compilers.
(More generally, even if a feature may work, if upstream doesn't usually test "older nightlies", then I wonder if we should enable such combinations/setups anyway, unless we need them for a particular reason).
Cheers,
Miguel
Alice Ryhl
maintainerRe: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
Quoted 6 lines · Miguel Ojeda
Quoted 4 lines · Gary Guo
So I think the implementation here is sensible. I believe Miguel's patch is also pretty much replicating the logic in proc-macro2's
build.rs.
Quoted 6 lines
Exactly, I was essentially following what upstream does for stable compilers.
(More generally, even if a feature may work, if upstream doesn't usually test "older nightlies", then I wonder if we should enable such combinations/setups anyway, unless we need them for a particular reason).
If these features change the public API exposed by proc-macro2, then it seems better to always disable it to prevent situations where you accidentally wrote code that does not work on our minimum rustc version.
(Of course, this is a polyfill and no API is changed, then that's a different situation and then this LGTM.)
Alice
Re: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
In reply to Miguel OjedaQuoted 23 lines · Miguel Ojeda
With all the new files in place and ready from the new crate, enable the support for it in the build system.
proc_macro_byte_characterandproc_macro_c_str_literalswere stabilized in Rust 1.79.0 [1] and were implemented earlier than our minimum Rust version (1.78) [2][3]. Thus just enable them instead of using thecfgthatproc-macro2uses to emulate them in older compilers.Signed-off-by Miguel Ojeda <[email protected]>--- Makefile | 3 +++ rust/Makefile | 32 +++++++++++++++++++++++++++++-- scripts/generate_rust_analyzer.py | 7 +++++++ 3 files changed, 40 insertions(+), 2 deletions(-)Makefile +0
-0
Makefile PHONY += rustfmt rustfmtcheck · line 1835
Quoted 6 lines
Makefile +3
-0@@ -1830,6 +1830,9 @@ PHONY += rustfmt rustfmtcheck rustfmt: $(Q)find $(srctree) $(RCS_FIND_IGNORE) \ + \( \ + -path $(srctree)/rust/proc-macro2 \ + \) -prune -o \
Looks good. But for future code and commit log readers, should we leave a small comment, to explain that this was vendored in, and therefore excluded from "make rustfmt"?
An alternative approach might be to create a "vendored" subdir, to make it clear which parts of the Rust for Linux code are special in that way.
thanks,
Signature · 1 line
John Hubbard
Quoted 109 lines
Makefile +0
-0-type f -a -name '*.rs' -a ! -name '*generated*' -print \ | xargs $(RUSTFMT) $(rustfmt_flags)rust/Makefile +30
-2@@ -27,6 +27,8 @@ endif obj-$(CONFIG_RUST) += exports.o +always-$(CONFIG_RUST) += libproc_macro2.rlib + always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.rs always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c@@ -76,6 +78,17 @@ core-flags := \ --edition=$(core-edition) \ $(call cfgs-to-flags,$(core-cfgs)) +proc_macro2-cfgs := \ + feature="proc-macro" \ + wrap_proc_macro \ + $(if $(call rustc-min-version,108800),proc_macro_span_file proc_macro_span_location) + +# Stable since Rust 1.79.0: `feature(proc_macro_byte_character,proc_macro_c_str_literals)`. +proc_macro2-flags := \ + --cap-lints=allow \ + -Zcrate-attr='feature(proc_macro_byte_character,proc_macro_c_str_literals)' \ + $(call cfgs-to-flags,$(proc_macro2-cfgs)) + # `rustdoc` did not save the target modifiers, thus workaround for # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18)@@ -128,10 +141,15 @@ rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ $(Q)for f in $(rustdoc_output)/static.files/rustdoc-*.css; do \ echo ".logo-container > img { object-fit: contain; }" >> $$f; done +rustdoc-proc_macro2: private rustdoc_host = yes +rustdoc-proc_macro2: private rustc_target_flags = $(proc_macro2-flags) +rustdoc-proc_macro2: $(src)/proc-macro2/lib.rs rustdoc-clean FORCE + +$(call if_changed,rustdoc) + rustdoc-macros: private rustdoc_host = yes rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ --extern proc_macro -rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean FORCE +rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean rustdoc-proc_macro2 FORCE +$(call if_changed,rustdoc) # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should@@ -194,6 +212,10 @@ rusttestlib-build_error: $(src)/build_error.rs FORCE rusttestlib-ffi: $(src)/ffi.rs FORCE +$(call if_changed,rustc_test_library) +rusttestlib-proc_macro2: private rustc_target_flags = $(proc_macro2-flags) +rusttestlib-proc_macro2: $(src)/proc-macro2/lib.rs FORCE + +$(call if_changed,rustc_test_library) + rusttestlib-macros: private rustc_target_flags = --extern proc_macro rusttestlib-macros: private rustc_test_library_proc = yes rusttestlib-macros: $(src)/macros/lib.rs FORCE@@ -440,6 +462,11 @@ quiet_cmd_rustc_hostlibrary = $(RUSTC_OR_CLIPPY_QUIET) H $@ mv $(objtree)/$(obj)/$(patsubst lib%.rlib,%,$(notdir $@)).d $(depfile); \ sed -i '/^\#/d' $(depfile) +$(obj)/libproc_macro2.rlib: private skip_clippy = 1 +$(obj)/libproc_macro2.rlib: private rustc_target_flags = $(proc_macro2-flags) +$(obj)/libproc_macro2.rlib: $(src)/proc-macro2/lib.rs FORCE + +$(call if_changed_dep,rustc_hostlibrary) + quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ cmd_rustc_procmacro = \ $(RUSTC_OR_CLIPPY) $(rust_common_flags) $(rustc_target_flags) \@@ -451,7 +478,7 @@ quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ @$(objtree)/include/generated/rustc_cfg $< # Procedural macros can only be used with the `rustc` that compiled it. -$(obj)/$(libmacros_name): $(src)/macros/lib.rs FORCE +$(obj)/$(libmacros_name): $(src)/macros/lib.rs $(obj)/libproc_macro2.rlib FORCE +$(call if_changed_dep,rustc_procmacro) $(obj)/$(libpin_init_internal_name): private rustc_target_flags = --cfg kernel@@ -474,6 +501,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L rust-analyzer: $(Q)MAKEFLAGS= $(srctree)/scripts/generate_rust_analyzer.py \ --cfgs='core=$(core-cfgs)' $(core-edition) \ + --cfgs='proc_macro2=$(proc_macro2-cfgs)' \ $(realpath $(srctree)) $(realpath $(objtree)) \ $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ > rust-project.jsonscripts/generate_rust_analyzer.py +7
-0@@ -86,6 +86,13 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit [], ) + append_crate( + "proc_macro2", + srctree / "rust" / "proc-macro2" / "lib.rs", + ["core", "alloc", "std", "proc_macro"], + cfg=crates_cfgs["proc_macro2"], + ) + append_crate( "macros", srctree / "rust" / "macros" / "lib.rs",
Re: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
Quoted 8 lines · John Hubbard
Looks good. But for future code and commit log readers, should we leave a small comment, to explain that this was vendored in, and therefore excluded from "make rustfmt"?
An alternative approach might be to create a "vendored" subdir, to make it clear which parts of the Rust for Linux code are special in that way.
Sure, that can help, I will add it.
The subdir makes sense, although it makes it into a different level than the other crates and I don't see it done with a folder in other cases either. Hmm... I will think about it.
Thanks for taking a look!
Cheers,
Miguel
Re: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
Quoted 11 lines · Miguel Ojeda
Quoted 8 lines · John Hubbard
Looks good. But for future code and commit log readers, should we leave a small comment, to explain that this was vendored in, and therefore excluded from "make rustfmt"?
An alternative approach might be to create a "vendored" subdir, to make it clear which parts of the Rust for Linux code are special in that way.
Sure, that can help, I will add it.
A minor thing, but, it looks like maybe this was forgotten or overlooked in v2?
Quoted 9 lines
The subdir makes sense, although it makes it into a different level than the other crates and I don't see it done with a folder in other cases either. Hmm... I will think about it.
Thanks for taking a look!
Cheers,
Miguel
thanks,
Signature · 1 line
John Hubbard
Re: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
Quoted 3 lines · John Hubbard
A minor thing, but, it looks like maybe this was forgotten or overlooked in v2?
No, it is there.
Cheers,
Miguel
Re: [PATCH 09/18] rust: proc-macro2: enable support in kbuild
Quoted 7 lines · Miguel Ojeda
Quoted 3 lines · John Hubbard
A minor thing, but, it looks like maybe this was forgotten or overlooked in v2?
No, it is there.
ah I see it now, it's a couple lines earlier than I expected, but looks good!
thanks,
Signature · 1 line
John Hubbard
Miguel Ojeda
maintainerPATCH 10/18 rust: quote: import crate
In reply to Miguel OjedaThis is a subset of the Rust quote crate, version 1.0.40 (released 2025-03-12), licensed under "Apache-2.0 OR MIT", from:
https://github.com/dtolnay/quote/raw/1.0.40/src
The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers).
For copyright details, please see:
https://github.com/dtolnay/quote/blob/1.0.40/README.md#license https://github.com/dtolnay/quote/blob/1.0.40/LICENSE-APACHE https://github.com/dtolnay/quote/blob/1.0.40/LICENSE-MIT
The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced.
The following script may be used to verify the contents:
for path in $(cd rust/quote/ && find . -type f -name '*.rs'); do
curl --silent --show-error --location \
https://github.com/dtolnay/quote/raw/1.0.40/src/$path \
| diff --unified rust/quote/$path - && echo $path: OK
done--- rust/quote/ext.rs | 110 +++ rust/quote/format.rs | 168 ++++ rust/quote/ident_fragment.rs | 88 ++ rust/quote/lib.rs | 1454 ++++++++++++++++++++++++++++++++++ rust/quote/runtime.rs | 492 ++++++++++++ rust/quote/spanned.rs | 50 ++ rust/quote/to_tokens.rs | 271 +++++++ 7 files changed, 2633 insertions(+) create mode 100644 rust/quote/ext.rs create mode 100644 rust/quote/format.rs create mode 100644 rust/quote/ident_fragment.rs create mode 100644 rust/quote/lib.rs create mode 100644 rust/quote/runtime.rs create mode 100644 rust/quote/spanned.rs create mode 100644 rust/quote/to_tokens.rs
rust/quote/ext.rs new file +110 -0
@@ -0,0 +1,110 @@ +use super ::ToTokens ; +use core::iter; +use proc_macro2::{TokenStream ,TokenTree }; + +/// TokenStream extension trait with methods for appending tokens. +/// +/// This trait is sealed and cannot be implemented outside of the `quote` crate. +pub trait TokenStreamExt : private::Sealed { +/// For use by `ToTokens` implementations. +/// +/// Appends the token specified to this list of tokens. +fn append <U >(&mut self, token:U ) +where +U :Into <TokenTree >; + +/// For use by `ToTokens` implementations. +/// +/// ``` +/// # use quote::{quote, TokenStreamExt, ToTokens}; +/// # use proc_macro2::TokenStream; +/// # +/// struct X; +/// +/// impl ToTokens for X { +/// fn to_tokens(&self, tokens: &mut TokenStream) { +/// tokens.append_all(&[true, false]); +/// } +/// } +/// +/// let tokens = quote!(#X); +/// assert_eq!(tokens.to_string(), "true false"); +/// ``` +fn append_all <I >(&mut self, iter:I ) +where +I :IntoIterator , +I ::Item :ToTokens ; + +/// For use by `ToTokens` implementations. +/// +/// Appends all of the items in the iterator `I`, separated by the tokens +/// `U`. +fn append_separated <I ,U >(&mut self, iter:I , op:U ) +where +I :IntoIterator , +I ::Item :ToTokens , +U :ToTokens ; + +/// For use by `ToTokens` implementations. +/// +/// Appends all tokens in the iterator `I`, appending `U` after each +/// element, including after the last element of the iterator. +fn append_terminated <I ,U >(&mut self, iter:I , term:U ) +where +I :IntoIterator , +I ::Item :ToTokens , +U :ToTokens ; +} + +impl TokenStreamExt for TokenStream { +fn append <U >(&mut self, token:U ) +where +U :Into <TokenTree >, + { + self.extend (iter::once (token.into ())); + } + +fn append_all <I >(&mut self, iter:I ) +where +I :IntoIterator , +I ::Item :ToTokens , + { +for tokenin iter { + token.to_tokens (self); + } + } + +fn append_separated <I ,U >(&mut self, iter:I , op:U ) +where +I :IntoIterator , +I ::Item :ToTokens , +U :ToTokens , + { +for (i, token)in iter.into_iter ().enumerate () { +if i >0 { + op.to_tokens (self); + } + token.to_tokens (self); + } + } + +fn append_terminated <I ,U >(&mut self, iter:I , term:U ) +where +I :IntoIterator , +I ::Item :ToTokens , +U :ToTokens , + { +for tokenin iter { + token.to_tokens (self); + term.to_tokens (self); + } + } +} + +mod private { +use proc_macro2::TokenStream ; + +pub trait Sealed {} + +impl Sealed for TokenStream {} +}
rust/quote/format.rs new file +168 -0
168 lines not on this page · raw message
rust/quote/ident_fragment.rs new file +88 -0
88 lines not on this page · raw message
rust/quote/lib.rs new file +1454 -0
1,454 lines not on this page · raw message
rust/quote/runtime.rs new file +492 -0
492 lines not on this page · raw message
rust/quote/spanned.rs new file +50 -0
50 lines not on this page · raw message
rust/quote/to_tokens.rs new file +271 -0
271 lines not on this page · raw message
Signature · 1 line
2.51.2
Miguel Ojeda
maintainerPATCH 11/18 rust: quote: add SPDX License Identifiers
In reply to Miguel OjedaOriginally, when the Rust upstream alloc standard library crate was vendored in commit 057b8d257107 ("rust: adapt alloc crate to the kernel"), the SPDX License Identifiers were added to every file so that the license on those was clear.
Thus do the same for the quote crate.
This makes scripts/spdxcheck.py pass.
--- rust/quote/ext.rs | 2 ++ rust/quote/format.rs | 2 ++ rust/quote/ident_fragment.rs | 2 ++ rust/quote/lib.rs | 2 ++ rust/quote/runtime.rs | 2 ++ rust/quote/spanned.rs | 2 ++ rust/quote/to_tokens.rs | 2 ++ 7 files changed, 14 insertions(+)
rust/quote/ext.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use super ::ToTokens ;use core::iter;use proc_macro2::{TokenStream ,TokenTree };
rust/quote/format.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +/// Formatting macro for constructing `Ident`s. /// /// <br>
rust/quote/ident_fragment.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use alloc::borrow::Cow ;use core::fmt;use proc_macro2::{Ident ,Span };
rust/quote/lib.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote) //! //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
rust/quote/runtime.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use self::get_span::{GetSpan ,GetSpanBase ,GetSpanInner };use crate ::{IdentFragment ,ToTokens ,TokenStreamExt };use core::fmt;
rust/quote/spanned.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::ToTokens ;use proc_macro2::extra::DelimSpan ;use proc_macro2::{Span ,TokenStream };
rust/quote/to_tokens.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use super ::TokenStreamExt ;use alloc::borrow::Cow ;use alloc::rc::Rc ;
Signature · 1 line
2.51.2
Miguel Ojeda
maintainerPATCH 12/18 rust: quote: add `README.md`
In reply to Miguel OjedaOriginally, when the Rust upstream alloc standard library crate was vendored in commit 057b8d257107 ("rust: adapt alloc crate to the kernel"), a README.md file was added to explain the provenance and licensing of the source files.
Thus do the same for the quote crate.
--- rust/quote/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 rust/quote/README.md
rust/quote/README.md new file +12 -0
@@ -0,0 +1,12 @@ +# `quote` + +These source files come from the Rust `quote` crate, version 1.0.40 +(released 2025-03-12), hosted in the <https://github.com/dtolnay/quote> +repository, licensed under "Apache-2.0 OR MIT" and only modified to add +the SPDX license identifiers. + +For copyright details, please see: + + https://github.com/dtolnay/quote/blob/1.0.40/README.md#license + https://github.com/dtolnay/quote/blob/1.0.40/LICENSE-APACHE + https://github.com/dtolnay/quote/blob/1.0.40/LICENSE-MIT
Signature · 1 line
2.51.2
Miguel Ojeda
maintainerPATCH 13/18 rust: quote: enable support in kbuild
In reply to Miguel OjedaWith all the new files in place and ready from the new crate, enable the support for it in the build system.
--- Makefile | 1 + rust/Makefile | 42 +++++++++++++++++++++++++++---- scripts/generate_rust_analyzer.py | 7 ++++++ 3 files changed, 45 insertions(+), 5 deletions(-)
Makefile +1 -0
@@ -1832,6 +1832,7 @@ rustfmt: $(Q)find $(srctree) $(RCS_FIND_IGNORE) \ \( \ -path $(srctree)/rust/proc-macro2 \ + -o -path $(srctree)/rust/quote \ \) -prune -o \ -type f -a -name '*.rs' -a ! -name '*generated*' -print \ | xargs $(RUSTFMT) $(rustfmt_flags)
rust/Makefile +37 -5
93 lines not on this page · raw message
scripts/generate_rust_analyzer.py +7 -0
@@ -93,6 +93,13 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit cfg=crates_cfgs["proc_macro2"], ) + append_crate( + "quote", + srctree / "rust" / "quote" / "lib.rs", + ["alloc", "proc_macro", "proc_macro2"], + cfg=crates_cfgs["quote"], + ) + append_crate( "macros", srctree / "rust" / "macros" / "lib.rs",
Signature · 1 line
2.51.2
Alice Ryhl
maintainerRe: [PATCH 13/18] rust: quote: enable support in kbuild
Quoted 10 lines · Miguel Ojeda
With all the new files in place and ready from the new crate, enable the support for it in the build system.
Signed-off-by Miguel Ojeda <[email protected]>rust/Makefile +0
-0
rust/Makefile rustdoc-clean: FORCE · line 225
Quoted 10 lines
rust/Makefile +2
-2@@ -199,8 +218,8 @@ rustdoc-clean: FORCE quiet_cmd_rustc_test_library = $(RUSTC_OR_CLIPPY_QUIET) TL $< cmd_rustc_test_library = \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ - @$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \ + $(RUSTC_OR_CLIPPY) $(filter-out $(skip_flags),$(rust_common_flags) $(rustc_target_flags)) \ + @$(objtree)/include/generated/rustc_cfg \ --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \ --out-dir $(objtree)/$(obj)/test --cfg testlib \ -L$(objtree)/$(obj)/test \
This change seems unrelated?
Alice
Gary Guo
maintainerRe: [PATCH 13/18] rust: quote: enable support in kbuild
Quoted 24 lines · On Mon, 10 Nov 2025 11:44:03 +0000 Alice Ryhl <[email protected]> wrote:
Quoted 10 lines · Miguel Ojeda
With all the new files in place and ready from the new crate, enable the support for it in the build system.
Signed-off-by Miguel Ojeda <[email protected]>rust/Makefile +0
-0rust/Makefile rustdoc-clean: FORCE · line 225
Quoted 10 lines
rust/Makefile +2
-2@@ -199,8 +218,8 @@ rustdoc-clean: FORCE quiet_cmd_rustc_test_library = $(RUSTC_OR_CLIPPY_QUIET) TL $< cmd_rustc_test_library = \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ - @$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \ + $(RUSTC_OR_CLIPPY) $(filter-out $(skip_flags),$(rust_common_flags) $(rustc_target_flags)) \ + @$(objtree)/include/generated/rustc_cfg \ --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \ --out-dir $(objtree)/$(obj)/test --cfg testlib \ -L$(objtree)/$(obj)/test \This change seems unrelated?
Quoted 1 line
Alice
This is to be able to skip over edition flags for quote when building the rusttestlib?
Best,
Gary
Re: [PATCH 13/18] rust: quote: enable support in kbuild
Quoted 3 lines · Gary Guo
This is to be able to skip over edition flags for
quotewhen building the rusttestlib?
Yes, it is needed to support skipping the flags, which isn't needed until this patch.
It can be done earlier separately since it doesn't hurt -- a simpler option is just to mention it here in the log.
Cheers,
Miguel
Re: [PATCH 13/18] rust: quote: enable support in kbuild
Quoted 10 lines · Miguel Ojeda
Quoted 3 lines · Gary Guo
This is to be able to skip over edition flags for
quotewhen building the rusttestlib?Yes, it is needed to support skipping the flags, which isn't needed until this patch.
It can be done earlier separately since it doesn't hurt -- a simpler option is just to mention it here in the log.
With that mentioned:
Miguel Ojeda
maintainerPATCH 14/18 rust: syn: import crate
In reply to Miguel OjedaThis is a subset of the Rust syn crate, version 2.0.106 (released 2025-08-16), licensed under "Apache-2.0 OR MIT", from:
https://github.com/dtolnay/syn/raw/2.0.106/src
The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers).
For copyright details, please see:
https://github.com/dtolnay/syn/blob/2.0.106/README.md#license https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-APACHE https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-MIT
The next two patches modify these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced.
The following script may be used to verify the contents:
for path in $(cd rust/syn/ && find . -type f -name '*.rs'); do
curl --silent --show-error --location \
https://github.com/dtolnay/syn/raw/2.0.106/src/$path \
| diff --unified rust/syn/$path - && echo $path: OK
done--- rust/syn/attr.rs | 836 +++++++ rust/syn/bigint.rs | 66 + rust/syn/buffer.rs | 434 ++++ rust/syn/classify.rs | 311 +++ rust/syn/custom_keyword.rs | 260 ++ rust/syn/custom_punctuation.rs | 304 +++ rust/syn/data.rs | 424 ++++ rust/syn/derive.rs | 259 ++ rust/syn/discouraged.rs | 225 ++ rust/syn/drops.rs | 58 + rust/syn/error.rs | 467 ++++ rust/syn/export.rs | 73 + rust/syn/expr.rs | 4173 ++++++++++++++++++++++++++++++++ rust/syn/ext.rs | 136 ++ rust/syn/file.rs | 125 + rust/syn/fixup.rs | 773 ++++++ rust/syn/gen/clone.rs | 2267 +++++++++++++++++ rust/syn/gen/debug.rs | 3238 +++++++++++++++++++++++++ rust/syn/gen/eq.rs | 2306 ++++++++++++++++++ rust/syn/gen/fold.rs | 3902 +++++++++++++++++++++++++++++ rust/syn/gen/hash.rs | 2876 ++++++++++++++++++++++ rust/syn/gen/visit.rs | 3941 ++++++++++++++++++++++++++++++ rust/syn/gen/visit_mut.rs | 3759 ++++++++++++++++++++++++++++ rust/syn/generics.rs | 1477 +++++++++++ rust/syn/group.rs | 291 +++ rust/syn/ident.rs | 108 + rust/syn/item.rs | 3490 ++++++++++++++++++++++++++ rust/syn/lib.rs | 1011 ++++++++ rust/syn/lifetime.rs | 156 ++ rust/syn/lit.rs | 1860 ++++++++++++++ rust/syn/lookahead.rs | 332 +++ rust/syn/mac.rs | 225 ++ rust/syn/macros.rs | 182 ++ rust/syn/meta.rs | 427 ++++ rust/syn/op.rs | 219 ++ rust/syn/parse.rs | 1419 +++++++++++ rust/syn/parse_macro_input.rs | 128 + rust/syn/parse_quote.rs | 240 ++ rust/syn/pat.rs | 955 ++++++++ rust/syn/path.rs | 966 ++++++++ rust/syn/precedence.rs | 210 ++ rust/syn/print.rs | 16 + rust/syn/punctuated.rs | 1155 +++++++++ rust/syn/restriction.rs | 178 ++ rust/syn/scan_expr.rs | 265 ++ rust/syn/sealed.rs | 4 + rust/syn/span.rs | 63 + rust/syn/spanned.rs | 118 + rust/syn/stmt.rs | 484 ++++ rust/syn/thread.rs | 60 + rust/syn/token.rs | 1096 +++++++++ rust/syn/tt.rs | 107 + rust/syn/ty.rs | 1271 ++++++++++ rust/syn/verbatim.rs | 33 + rust/syn/whitespace.rs | 65 + 55 files changed, 49824 insertions(+) create mode 100644 rust/syn/attr.rs create mode 100644 rust/syn/bigint.rs create mode 100644 rust/syn/buffer.rs create mode 100644 rust/syn/classify.rs create mode 100644 rust/syn/custom_keyword.rs create mode 100644 rust/syn/custom_punctuation.rs create mode 100644 rust/syn/data.rs create mode 100644 rust/syn/derive.rs create mode 100644 rust/syn/discouraged.rs create mode 100644 rust/syn/drops.rs create mode 100644 rust/syn/error.rs create mode 100644 rust/syn/export.rs create mode 100644 rust/syn/expr.rs create mode 100644 rust/syn/ext.rs create mode 100644 rust/syn/file.rs create mode 100644 rust/syn/fixup.rs create mode 100644 rust/syn/gen/clone.rs create mode 100644 rust/syn/gen/debug.rs create mode 100644 rust/syn/gen/eq.rs create mode 100644 rust/syn/gen/fold.rs create mode 100644 rust/syn/gen/hash.rs create mode 100644 rust/syn/gen/visit.rs create mode 100644 rust/syn/gen/visit_mut.rs create mode 100644 rust/syn/generics.rs create mode 100644 rust/syn/group.rs create mode 100644 rust/syn/ident.rs create mode 100644 rust/syn/item.rs create mode 100644 rust/syn/lib.rs create mode 100644 rust/syn/lifetime.rs create mode 100644 rust/syn/lit.rs create mode 100644 rust/syn/lookahead.rs create mode 100644 rust/syn/mac.rs create mode 100644 rust/syn/macros.rs create mode 100644 rust/syn/meta.rs create mode 100644 rust/syn/op.rs create mode 100644 rust/syn/parse.rs create mode 100644 rust/syn/parse_macro_input.rs create mode 100644 rust/syn/parse_quote.rs create mode 100644 rust/syn/pat.rs create mode 100644 rust/syn/path.rs create mode 100644 rust/syn/precedence.rs create mode 100644 rust/syn/print.rs create mode 100644 rust/syn/punctuated.rs create mode 100644 rust/syn/restriction.rs create mode 100644 rust/syn/scan_expr.rs create mode 100644 rust/syn/sealed.rs create mode 100644 rust/syn/span.rs create mode 100644 rust/syn/spanned.rs create mode 100644 rust/syn/stmt.rs create mode 100644 rust/syn/thread.rs create mode 100644 rust/syn/token.rs create mode 100644 rust/syn/tt.rs create mode 100644 rust/syn/ty.rs create mode 100644 rust/syn/verbatim.rs create mode 100644 rust/syn/whitespace.rs
rust/syn/attr.rs new file +836 -0
@@ -0,0 +1,836 @@ +#[cfg(feature = "parsing" )] +use crate ::error::Error ; +#[cfg(feature = "parsing" )] +use crate ::error::Result ; +use crate ::expr::Expr ; +use crate ::mac::MacroDelimiter ; +#[cfg(feature = "parsing" )] +use crate ::meta::{self,ParseNestedMeta }; +#[cfg(feature = "parsing" )] +use crate ::parse::{Parse ,ParseStream ,Parser }; +use crate ::path::Path ; +use crate ::token; +use proc_macro2::TokenStream ; +#[cfg(feature = "printing" )] +use std::iter; +#[cfg(feature = "printing" )] +use std::slice; + +ast_struct! { +/// An attribute, like `#[repr(transparent)]`. +/// +/// <br> +/// +/// # Syntax +/// +/// Rust has six types of attributes. +/// +/// - Outer attributes like `#[repr(transparent)]`. These appear outside or +/// in front of the item they describe. +/// +/// - Inner attributes like `#![feature(proc_macro)]`. These appear inside +/// of the item they describe, usually a module. +/// +/// - Outer one-line doc comments like `/// Example`. +/// +/// - Inner one-line doc comments like `//! Please file an issue`. +/// +/// - Outer documentation blocks `/** Example */`. +/// +/// - Inner documentation blocks `/*! Please file an issue */`. +/// +/// The `style` field of type `AttrStyle` distinguishes whether an attribute +/// is outer or inner. +/// +/// Every attribute has a `path` that indicates the intended interpretation +/// of the rest of the attribute's contents. The path and the optional +/// additional contents are represented together in the `meta` field of the +/// attribute in three possible varieties: +/// +/// - Meta::Path — attributes whose information content conveys just a +/// path, for example the `#[test]` attribute. +/// +/// - Meta::List — attributes that carry arbitrary tokens after the +/// path, surrounded by a delimiter (parenthesis, bracket, or brace). For +/// example `#[derive(Copy)]` or `#[precondition(x < 5)]`. +/// +/// - Meta::NameValue — attributes with an `=` sign after the path, +/// followed by a Rust expression. For example `#[path = +/// "sys/windows.rs"]`. +/// +/// All doc comments are represented in the NameValue style with a path of +/// "doc", as this is how they are processed by the compiler and by +/// `macro_rules!` macros. +/// +/// ```text +/// #[derive(Copy, Clone)] +/// ~~~~~~Path +/// ^^^^^^^^^^^^^^^^^^^Meta::List +/// +/// #[path = "sys/windows.rs"] +/// ~~~~Path +/// ^^^^^^^^^^^^^^^^^^^^^^^Meta::NameValue +/// +/// #[test] +/// ^^^^Meta::Path +/// ``` +/// +/// <br> +/// +/// # Parsing from tokens to Attribute +/// +/// This type does not implement the [`Parse`] trait and thus cannot be +/// parsed directly by [`ParseStream::parse`]. Instead use +/// [`ParseStream::call`] with one of the two parser functions +/// [`Attribute::parse_outer`] or [`Attribute::parse_inner`] depending on +/// which you intend to parse. +/// +/// [`Parse`]: crate::parse::Parse +/// [`ParseStream::parse`]: crate::parse::ParseBuffer::parse +/// [`ParseStream::call`]: crate::parse::ParseBuffer::call +/// +/// ``` +/// use syn::{Attribute, Ident, Result, Token}; +/// use syn::parse::{Parse, ParseStream}; +/// +/// // Parses a unit struct with attributes. +/// // +/// // #[path = "s.tmpl"] +/// // struct S; +/// struct UnitStruct { +/// attrs: Vec<Attribute>, +/// struct_token: Token![struct], +/// name: Ident, +/// semi_token: Token![;], +/// } +/// +/// impl Parse for UnitStruct { +/// fn parse(input: ParseStream) -> Result<Self> { +/// Ok(UnitStruct { +/// attrs: input.call(Attribute::parse_outer)?, +/// struct_token: input.parse()?, +/// name: input.parse()?, +/// semi_token: input.parse()?, +/// }) +/// } +/// } +/// ``` +/// +/// <p><br></p> +/// +/// # Parsing from Attribute to structured arguments +/// +/// The grammar of attributes in Rust is very flexible, which makes the +/// syntax tree not that useful on its own. In particular, arguments of the +/// `Meta::List` variety of attribute are held in an arbitrary `tokens: +/// TokenStream`. Macros are expected to check the `path` of the attribute, +/// decide whether they recognize it, and then parse the remaining tokens +/// according to whatever grammar they wish to require for that kind of +/// attribute. Use [`parse_args()`] to parse those tokens into the expected +/// data structure. +/// +/// [`parse_args()`]: Attribute::parse_args +/// +/// <p><br></p> +/// +/// # Doc comments +/// +/// The compiler transforms doc comments, such as `/// comment` and `/*! +/// comment */`, into attributes before macros are expanded. Each comment is +/// expanded into an attribute of the form `#[doc = r"comment"]`. +/// +/// As an example, the following `mod` items are expanded identically: +/// +/// ``` +/// # use syn::{ItemMod, parse_quote}; +/// let doc: ItemMod = parse_quote! { +/// /// Single line doc comments +/// /// We write so many! +/// /** +/// * Multi-line comments... +/// * May span many lines +/// */ +/// mod example { +/// //! Of course, they can be inner too +/// /*! And fit in a single line */ +/// } +/// }; +/// let attr: ItemMod = parse_quote! { +/// #[doc = r" Single line doc comments"] +/// #[doc = r" We write so many!"] +/// #[doc = r" +/// * Multi-line comments... +/// * May span many lines +/// "] +/// mod example { +/// #![doc = r" Of course, they can be inner too"] +/// #![doc = r" And fit in a single line "] +/// } +/// }; +/// assert_eq!(doc, attr); +/// ``` +#[cfg_attr(docsrs, doc(cfg(any(feature = "full" , feature = "derive" ))))] +pub struct Attribute { +pub pound_token:Token! [#], +pub style:AttrStyle , +pub bracket_token: token::Bracket , +pub meta:Meta , + } +} + +impl Attribute { +/// Returns the path that identifies the interpretation of this attribute. +/// +/// For example this would return the `test` in `#[test]`, the `derive` in +/// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. +pub fn path (&self) -> &Path { + self.meta.path () + } + +/// Parse the arguments to the attribute as a syntax tree. +/// +/// This is similar to pulling out the `TokenStream` from `Meta::List` and +/// doing `syn::parse2::<T>(meta_list.tokens)`, except that using +/// `parse_args` the error message has a more useful span when `tokens` is +/// empty. +/// +/// The surrounding delimiters are *not* included in the input to the +/// parser. +/// +/// ```text +/// #[my_attr(value < 5)] +/// ^^^^^^^^^ what gets parsed +/// ``` +/// +/// # Example +/// +/// ``` +/// use syn::{parse_quote, Attribute, Expr}; +/// +/// let attr: Attribute = parse_quote! { +/// #[precondition(value < 5)] +/// }; +/// +/// if attr.path().is_ident("precondition") { +/// let precondition: Expr = attr.parse_args()?; +/// // ... +/// } +/// # anyhow::Ok(()) +/// ``` +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn parse_args <T :Parse >(&self) ->Result <T > { + self.parse_args_with (T ::parse) + } + +/// Parse the arguments to the attribute using the given parser. +/// +/// # Example +/// +/// ``` +/// use syn::{parse_quote, Attribute}; +/// +/// let attr: Attribute = parse_quote! { +/// #[inception { #[brrrrrrraaaaawwwwrwrrrmrmrmmrmrmmmmm] }] +/// }; +/// +/// let bwom = attr.parse_args_with(Attribute::parse_outer)?; +/// +/// // Attribute does not have a Parse impl, so we couldn't directly do: +/// // let bwom: Attribute = attr.parse_args()?; +/// # anyhow::Ok(()) +/// ``` +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn parse_args_with <F :Parser >(&self, parser:F ) ->Result <F ::Output > { +match &self.meta { +Meta ::Path (path) =>Err (crate ::error::new2 ( + path.segments.first ().unwrap ().ident.span (), + path.segments.last ().unwrap ().ident.span (), +format! ( +"expected attribute arguments in parentheses: {}[{}(...)]" , + parsing::DisplayAttrStyle (&self.style), + parsing::DisplayPath (path), + ), + )), +Meta ::NameValue (meta) =>Err (Error ::new ( + meta.eq_token.span, +format_args! ( +"expected parentheses: {}[{}(...)]" , + parsing::DisplayAttrStyle (&self.style), + parsing::DisplayPath (&meta.path), + ), + )), +Meta ::List (meta) => meta.parse_args_with (parser), + } + } + +/// Parse the arguments to the attribute, expecting it to follow the +/// conventional structure used by most of Rust's built-in attributes. +/// +/// The [*Meta Item Attribute Syntax*][syntax] section in the Rust reference +/// explains the convention in more detail. Not all attributes follow this +/// convention, so [`parse_args()`][Self::parse_args] is available if you +/// need to parse arbitrarily goofy attribute syntax. +/// +/// [syntax]: https://doc.rust-lang.org/reference/attributes.html#meta-item-attribute-syntax +/// +/// # Example +/// +/// We'll parse a struct, and then parse some of Rust's `#[repr]` attribute +/// syntax. +/// +/// ``` +/// use syn::{parenthesized, parse_quote, token, ItemStruct, LitInt}; +/// +/// let input: ItemStruct = parse_quote! { +/// #[repr(C, align(4))] +/// pub struct MyStruct(u16, u32); +/// }; +/// +/// let mut repr_c = false; +/// let mut repr_transparent = false; +/// let mut repr_align = None::<usize>; +/// let mut repr_packed = None::<usize>; +/// for attr in &input.attrs { +/// if attr.path().is_ident("repr") { +/// attr.parse_nested_meta(|meta| { +/// // #[repr(C)] +/// if meta.path.is_ident("C") { +/// repr_c = true; +/// return Ok(()); +/// } +/// +/// // #[repr(transparent)] +/// if meta.path.is_ident("transparent") { +/// repr_transparent = true; +/// return Ok(()); +/// } +/// +/// // #[repr(align(N))] +/// if meta.path.is_ident("align") { +/// let content; +/// parenthesized!(content in meta.input); +/// let lit: LitInt = content.parse()?; +/// let n: usize = lit.base10_parse()?; +/// repr_align = Some(n); +/// return Ok(()); +/// } +/// +/// // #[repr(packed)] or #[repr(packed(N))], omitted N means 1 +/// if meta.path.is_ident("packed") { +/// if meta.input.peek(token::Paren) { +/// let content; +/// parenthesized!(content in meta.input); +/// let lit: LitInt = content.parse()?; +/// let n: usize = lit.base10_parse()?; +/// repr_packed = Some(n); +/// } else { +/// repr_packed = Some(1); +/// } +/// return Ok(()); +/// } +/// +/// Err(meta.error("unrecognized repr")) +/// })?; +/// } +/// } +/// # anyhow::Ok(()) +/// ``` +/// +/// # Alternatives +/// +/// In some cases, for attributes which have nested layers of structured +/// content, the following less flexible approach might be more convenient: +/// +/// ``` +/// # use syn::{parse_quote, ItemStruct}; +/// # +/// # let input: ItemStruct = parse_quote! { +/// # #[repr(C, align(4))] +/// # pub struct MyStruct(u16, u32); +/// # }; +/// # +/// use syn::punctuated::Punctuated; +/// use syn::{parenthesized, token, Error, LitInt, Meta, Token}; +/// +/// let mut repr_c = false; +/// let mut repr_transparent = false; +/// let mut repr_align = None::<usize>; +/// let mut repr_packed = None::<usize>; +/// for attr in &input.attrs { +/// if attr.path().is_ident("repr") { +/// let nested = attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?; +/// for meta in nested { +/// match meta { +/// // #[repr(C)] +/// Meta::Path(path) if path.is_ident("C") => { +/// repr_c = true; +/// } +/// +/// // #[repr(align(N))] +/// Meta::List(meta) if meta.path.is_ident("align") => { +/// let lit: LitInt = meta.parse_args()?; +/// let n: usize = lit.base10_parse()?; +/// repr_align = Some(n); +/// } +/// +/// /* ... */ +/// +/// _ => { +/// return Err(Error::new_spanned(meta, "unrecognized repr")); +/// } +/// } +/// } +/// } +/// } +/// # Ok(()) +/// ``` +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn parse_nested_meta ( + &self, + logic:impl FnMut (ParseNestedMeta ) ->Result <()>, + ) ->Result <()> { + self.parse_args_with (meta::parser (logic)) + } + +/// Parses zero or more outer attributes from the stream. +/// +/// # Example +/// +/// See +/// [*Parsing from tokens to Attribute*](#parsing-from-tokens-to-attribute). +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn parse_outer (input:ParseStream ) ->Result <Vec <Self >> { +let mut attrs =Vec ::new (); +while input.peek (Token! [#]) { + attrs.push (input.call (parsing::single_parse_outer)?); + } +Ok (attrs) + } + +/// Parses zero or more inner attributes from the stream. +/// +/// # Example +/// +/// See +/// [*Parsing from tokens to Attribute*](#parsing-from-tokens-to-attribute). +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn parse_inner (input:ParseStream ) ->Result <Vec <Self >> { +let mut attrs =Vec ::new (); + parsing::parse_inner (input, &mut attrs)?; +Ok (attrs) + } +} + +ast_enum! { +/// Distinguishes between attributes that decorate an item and attributes +/// that are contained within an item. +/// +/// # Outer attributes +/// +/// - `#[repr(transparent)]` +/// - `/// # Example` +/// - `/** Please file an issue */` +/// +/// # Inner attributes +/// +/// - `#![feature(proc_macro)]` +/// - `//! # Example` +/// - `/*! Please file an issue */` +#[cfg_attr(docsrs, doc(cfg(any(feature = "full" , feature = "derive" ))))] +pub enum AttrStyle { +Outer , +Inner (Token! [!]), + } +} + +ast_enum! { +/// Content of a compile-time structured attribute. +/// +/// ## Path +/// +/// A meta path is like the `test` in `#[test]`. +/// +/// ## List +/// +/// A meta list is like the `derive(Copy)` in `#[derive(Copy)]`. +/// +/// ## NameValue +/// +/// A name-value meta is like the `path = "..."` in `#[path = +/// "sys/windows.rs"]`. +/// +/// # Syntax tree enum +/// +/// This type is a [syntax tree enum]. +/// +/// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums +#[cfg_attr(docsrs, doc(cfg(any(feature = "full" , feature = "derive" ))))] +pub enum Meta { +Path (Path ), + +/// A structured list within an attribute, like `derive(Copy, Clone)`. +List (MetaList ), + +/// A name-value pair within an attribute, like `feature = "nightly"`. +NameValue (MetaNameValue ), + } +} + +ast_struct! { +/// A structured list within an attribute, like `derive(Copy, Clone)`. +#[cfg_attr(docsrs, doc(cfg(any(feature = "full" , feature = "derive" ))))] +pub struct MetaList { +pub path:Path , +pub delimiter:MacroDelimiter , +pub tokens:TokenStream , + } +} + +ast_struct! { +/// A name-value pair within an attribute, like `feature = "nightly"`. +#[cfg_attr(docsrs, doc(cfg(any(feature = "full" , feature = "derive" ))))] +pub struct MetaNameValue { +pub path:Path , +pub eq_token:Token! [=], +pub value:Expr , + } +} + +impl Meta { +/// Returns the path that begins this structured meta item. +/// +/// For example this would return the `test` in `#[test]`, the `derive` in +/// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. +pub fn path (&self) -> &Path { +match self { +Meta ::Path (path) => path, +Meta ::List (meta) => &meta.path, +Meta ::NameValue (meta) => &meta.path, + } + } + +/// Error if this is a `Meta::List` or `Meta::NameValue`. +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn require_path_only (&self) ->Result <&Path > { +let error_span =match self { +Meta ::Path (path) =>return Ok (path), +Meta ::List (meta) => meta.delimiter.span ().open (), +Meta ::NameValue (meta) => meta.eq_token.span, + }; +Err (Error ::new (error_span,"unexpected token in attribute" )) + } + +/// Error if this is a `Meta::Path` or `Meta::NameValue`. +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn require_list (&self) ->Result <&MetaList > { +match self { +Meta ::List (meta) =>Ok (meta), +Meta ::Path (path) =>Err (crate ::error::new2 ( + path.segments.first ().unwrap ().ident.span (), + path.segments.last ().unwrap ().ident.span (), +format! ( +"expected attribute arguments in parentheses: `{}(...)`" , + parsing::DisplayPath (path), + ), + )), +Meta ::NameValue (meta) =>Err (Error ::new (meta.eq_token.span,"expected `(`" )), + } + } + +/// Error if this is a `Meta::Path` or `Meta::List`. +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn require_name_value (&self) ->Result <&MetaNameValue > { +match self { +Meta ::NameValue (meta) =>Ok (meta), +Meta ::Path (path) =>Err (crate ::error::new2 ( + path.segments.first ().unwrap ().ident.span (), + path.segments.last ().unwrap ().ident.span (), +format! ( +"expected a value for this attribute: `{} = ...`" , + parsing::DisplayPath (path), + ), + )), +Meta ::List (meta) =>Err (Error ::new (meta.delimiter.span ().open (),"expected `=`" )), + } + } +} + +impl MetaList { +/// See [`Attribute::parse_args`]. +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn parse_args <T :Parse >(&self) ->Result <T > { + self.parse_args_with (T ::parse) + } + +/// See [`Attribute::parse_args_with`]. +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn parse_args_with <F :Parser >(&self, parser:F ) ->Result <F ::Output > { +let scope = self.delimiter.span ().close (); +crate ::parse::parse_scoped (parser, scope, self.tokens.clone ()) + } + +/// See [`Attribute::parse_nested_meta`]. +#[cfg(feature = "parsing" )] +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +pub fn parse_nested_meta ( + &self, + logic:impl FnMut (ParseNestedMeta ) ->Result <()>, + ) ->Result <()> { + self.parse_args_with (meta::parser (logic)) + } +} + +#[cfg(feature = "printing" )] +pub (crate )trait FilterAttrs <'a> { +type Ret :Iterator <Item = &'aAttribute >; + +fn outer (self) ->Self ::Ret ; +#[cfg(feature = "full" )] +fn inner (self) ->Self ::Ret ; +} + +#[cfg(feature = "printing" )] +impl <'a>FilterAttrs <'a>for &'a [Attribute ] { +type Ret = iter::Filter <slice::Iter <'a,Attribute >,fn (&&Attribute ) ->bool >; + +fn outer (self) ->Self ::Ret { +fn is_outer (attr: &&Attribute ) ->bool { +match attr.style { +AttrStyle ::Outer =>true , +AttrStyle ::Inner (_) =>false , + } + } + self.iter ().filter (is_outer) + } + +#[cfg(feature = "full" )] +fn inner (self) ->Self ::Ret { +fn is_inner (attr: &&Attribute ) ->bool { +match attr.style { +AttrStyle ::Inner (_) =>true , +AttrStyle ::Outer =>false , + } + } + self.iter ().filter (is_inner) + } +} + +impl From <Path >for Meta { +fn from (meta:Path ) ->Meta { +Meta ::Path (meta) + } +} + +impl From <MetaList >for Meta { +fn from (meta:MetaList ) ->Meta { +Meta ::List (meta) + } +} + +impl From <MetaNameValue >for Meta { +fn from (meta:MetaNameValue ) ->Meta { +Meta ::NameValue (meta) + } +} + +#[cfg(feature = "parsing" )] +pub (crate )mod parsing { +use crate ::attr::{AttrStyle ,Attribute ,Meta ,MetaList ,MetaNameValue }; +use crate ::error::Result ; +use crate ::expr::{Expr ,ExprLit }; +use crate ::lit::Lit ; +use crate ::parse::discouraged::Speculative as _; +use crate ::parse::{Parse ,ParseStream }; +use crate ::path::Path ; +use crate ::{mac, token}; +use proc_macro2::Ident ; +use std::fmt::{self,Display }; + +pub (crate )fn parse_inner (input:ParseStream , attrs: &mut Vec <Attribute >) ->Result <()> { +while input.peek (Token! [#]) && input.peek2 (Token! [!]) { + attrs.push (input.call (single_parse_inner)?); + } +Ok (()) + } + +pub (crate )fn single_parse_inner (input:ParseStream ) ->Result <Attribute > { +let content; +Ok (Attribute { + pound_token: input.parse ()?, + style:AttrStyle ::Inner (input.parse ()?), + bracket_token:bracketed! (content in input), + meta: content.parse ()?, + }) + } + +pub (crate )fn single_parse_outer (input:ParseStream ) ->Result <Attribute > { +let content; +Ok (Attribute { + pound_token: input.parse ()?, + style:AttrStyle ::Outer , + bracket_token:bracketed! (content in input), + meta: content.parse ()?, + }) + } + +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +impl Parse for Meta { +fn parse (input:ParseStream ) ->Result <Self > { +let path =parse_outermost_meta_path (input)?; +parse_meta_after_path (path, input) + } + } + +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +impl Parse for MetaList { +fn parse (input:ParseStream ) ->Result <Self > { +let path =parse_outermost_meta_path (input)?; +parse_meta_list_after_path (path, input) + } + } + +#[cfg_attr(docsrs, doc(cfg(feature = "parsing" )))] +impl Parse for MetaNameValue { +fn parse (input:ParseStream ) ->Result <Self > { +let path =parse_outermost_meta_path (input)?; +parse_meta_name_value_after_path (path, input) + } + } + +// Unlike meta::parse_meta_path which accepts arbitrary keywords in the path, +// only the `unsafe` keyword is accepted as an attribute's outermost path. +fn parse_outermost_meta_path (input:ParseStream ) ->Result <Path > { +if input.peek (Token! [unsafe ]) { +let unsafe_token:Token! [unsafe ] = input.parse ()?; +Ok (Path ::from (Ident ::new ("unsafe" , unsafe_token.span))) + }else { +Path ::parse_mod_style (input) + } + } + +pub (crate )fn parse_meta_after_path (path:Path , input:ParseStream ) ->Result <Meta > { +if input.peek (token::Paren ) || input.peek (token::Bracket ) || input.peek (token::Brace ) { +parse_meta_list_after_path (path, input).map (Meta ::List ) + }else if input.peek (Token! [=]) { +parse_meta_name_value_after_path (path, input).map (Meta ::NameValue ) + }else { +Ok (Meta ::Path (path)) + } + } + +fn parse_meta_list_after_path (path:Path , input:ParseStream ) ->Result <MetaList > { +let (delimiter, tokens) = mac::parse_delimiter (input)?; +Ok (MetaList { + path, + delimiter, + tokens, + }) + } + +fn parse_meta_name_value_after_path (path:Path , input:ParseStream ) ->Result <MetaNameValue > { +let eq_token:Token! [=] = input.parse ()?; +let ahead = input.fork (); +let lit:Option <Lit > = ahead.parse ()?; +let value =if let (Some (lit),true ) = (lit, ahead.is_empty ()) { + input.advance_to (&ahead); +Expr ::Lit (ExprLit { + attrs:Vec ::new (), + lit, + }) + }else if input.peek (Token! [#]) && input.peek2 (token::Bracket ) { +return Err (input.error ("unexpected attribute inside of attribute" )); + }else { + input.parse ()? + }; +Ok (MetaNameValue { + path, + eq_token, + value, + }) + } + +pub (super )struct DisplayAttrStyle <'a>(pub &'aAttrStyle ); + +impl <'a>Display for DisplayAttrStyle <'a> { +fn fmt (&self, formatter: &mut fmt::Formatter ) -> fmt::Result { + formatter.write_str (match self.0 { +AttrStyle ::Outer =>"#" , +AttrStyle ::Inner (_) =>"#!" , + }) + } + } + +pub (super )struct DisplayPath <'a>(pub &'aPath ); + +impl <'a>Display for DisplayPath <'a> { +fn fmt (&self, formatter: &mut fmt::Formatter ) -> fmt::Result { +for (i, segment)in self.0 .segments.iter ().enumerate () { +if i >0 || self.0 .leading_colon.is_some () { + formatter.write_str ("::" )?; + } +write! (formatter,"{}" , segment.ident)?; + } +Ok (()) + } + } +} + +#[cfg(feature = "printing" )] +mod printing { +use crate ::attr::{AttrStyle ,Attribute ,Meta ,MetaList ,MetaNameValue }; +use crate ::path; +use crate ::path::printing::PathStyle ; +use proc_macro2::TokenStream ; +use quote::ToTokens ; + +#[cfg_attr(docsrs, doc(cfg(feature = "printing" )))] +impl ToTokens for Attribute { +fn to_tokens (&self, tokens: &mut TokenStream ) { + self.pound_token.to_tokens (tokens); +if let AttrStyle ::Inner (b) = &self.style { + b.to_tokens (tokens); + } + self.bracket_token.surround (tokens, |tokens| { + self.meta.to_tokens (tokens); + }); + } + } + +#[cfg_attr(docsrs, doc(cfg(feature = "printing" )))] +impl ToTokens for Meta { +fn to_tokens (&self, tokens: &mut TokenStream ) { +match self { +Meta ::Path (path) => path::printing::print_path (tokens, path,PathStyle ::Mod ), +Meta ::List (meta_list) => meta_list.to_tokens (tokens), +Meta ::NameValue (meta_name_value) => meta_name_value.to_tokens (tokens), + } + } + } + +#[cfg_attr(docsrs, doc(cfg(feature = "printing" )))] +impl ToTokens for MetaList { +fn to_tokens (&self, tokens: &mut TokenStream ) { + path::printing::print_path (tokens, &self.path,PathStyle ::Mod ); + self.delimiter.surround (tokens, self.tokens.clone ()); + } + } + +#[cfg_attr(docsrs, doc(cfg(feature = "printing" )))] +impl ToTokens for MetaNameValue { +fn to_tokens (&self, tokens: &mut TokenStream ) { + path::printing::print_path (tokens, &self.path,PathStyle ::Mod ); + self.eq_token.to_tokens (tokens); + self.value.to_tokens (tokens); + } + } +}
rust/syn/bigint.rs new file +66 -0
66 lines not on this page · raw message
rust/syn/buffer.rs new file +434 -0
434 lines not on this page · raw message
rust/syn/classify.rs new file +311 -0
311 lines not on this page · raw message
rust/syn/custom_keyword.rs new file +260 -0
260 lines not on this page · raw message
rust/syn/custom_punctuation.rs new file +304 -0
304 lines not on this page · raw message
rust/syn/data.rs new file +424 -0
424 lines not on this page · raw message
rust/syn/derive.rs new file +259 -0
259 lines not on this page · raw message
rust/syn/discouraged.rs new file +225 -0
106 lines not on this page · raw message
rust/syn/drops.rs new file +58 -0
58 lines not on this page · raw message
rust/syn/error.rs new file +467 -0
467 lines not on this page · raw message
rust/syn/export.rs new file +73 -0
73 lines not on this page · raw message
rust/syn/expr.rs new file +4173 -0
4,173 lines not on this page · raw message
rust/syn/ext.rs new file +136 -0
136 lines not on this page · raw message
rust/syn/file.rs new file +125 -0
125 lines not on this page · raw message
rust/syn/fixup.rs new file +773 -0
773 lines not on this page · raw message
rust/syn/gen/clone.rs new file +2267 -0
2,267 lines not on this page · raw message
rust/syn/gen/debug.rs new file +3238 -0
3,238 lines not on this page · raw message
rust/syn/gen/eq.rs new file +2306 -0
2,306 lines not on this page · raw message
rust/syn/gen/fold.rs new file +3902 -0
3,902 lines not on this page · raw message
rust/syn/gen/hash.rs new file +2876 -0
2,876 lines not on this page · raw message
rust/syn/gen/visit.rs new file +3941 -0
3,941 lines not on this page · raw message
rust/syn/gen/visit_mut.rs new file +3759 -0
3,759 lines not on this page · raw message
rust/syn/generics.rs new file +1477 -0
1,477 lines not on this page · raw message
rust/syn/group.rs new file +291 -0
291 lines not on this page · raw message
rust/syn/ident.rs new file +108 -0
108 lines not on this page · raw message
rust/syn/item.rs new file +3490 -0
3,490 lines not on this page · raw message
rust/syn/lib.rs new file +1011 -0
1,011 lines not on this page · raw message
rust/syn/lifetime.rs new file +156 -0
156 lines not on this page · raw message
rust/syn/lit.rs new file +1860 -0
1,860 lines not on this page · raw message
rust/syn/lookahead.rs new file +332 -0
332 lines not on this page · raw message
rust/syn/mac.rs new file +225 -0
225 lines not on this page · raw message
rust/syn/macros.rs new file +182 -0
182 lines not on this page · raw message
rust/syn/meta.rs new file +427 -0
427 lines not on this page · raw message
rust/syn/op.rs new file +219 -0
219 lines not on this page · raw message
rust/syn/parse.rs new file +1419 -0
1,419 lines not on this page · raw message
rust/syn/parse_macro_input.rs new file +128 -0
128 lines not on this page · raw message
rust/syn/parse_quote.rs new file +240 -0
240 lines not on this page · raw message
rust/syn/pat.rs new file +955 -0
955 lines not on this page · raw message
rust/syn/path.rs new file +966 -0
966 lines not on this page · raw message
rust/syn/precedence.rs new file +210 -0
210 lines not on this page · raw message
rust/syn/punctuated.rs new file +1155 -0
1,155 lines not on this page · raw message
rust/syn/restriction.rs new file +178 -0
178 lines not on this page · raw message
rust/syn/scan_expr.rs new file +265 -0
265 lines not on this page · raw message
rust/syn/span.rs new file +63 -0
63 lines not on this page · raw message
rust/syn/spanned.rs new file +118 -0
118 lines not on this page · raw message
rust/syn/stmt.rs new file +484 -0
484 lines not on this page · raw message
rust/syn/thread.rs new file +60 -0
60 lines not on this page · raw message
rust/syn/token.rs new file +1096 -0
1,096 lines not on this page · raw message
rust/syn/tt.rs new file +107 -0
107 lines not on this page · raw message
rust/syn/ty.rs new file +1271 -0
1,271 lines not on this page · raw message
rust/syn/whitespace.rs new file +65 -0
65 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.51.2
Part of the diff is not shown here. View the raw message.
Re: [PATCH 14/18] rust: syn: import crate
Quoted 3 lines · Miguel Ojeda
This is a subset of the Rust
syncrate, version 2.0.106 (released 2025-08-16), licensed under "Apache-2.0 OR MIT", from:
In case someone is wondering: I didn't use the very latest since it was quite new (even if the diff was fairly small).
Same for quote.
Cheers,
Miguel
Miguel Ojeda
maintainerPATCH 15/18 rust: syn: add SPDX License Identifiers
In reply to Miguel OjedaOriginally, when the Rust upstream alloc standard library crate was vendored in commit 057b8d257107 ("rust: adapt alloc crate to the kernel"), the SPDX License Identifiers were added to every file so that the license on those was clear.
Thus do the same for the syn crate.
This makes scripts/spdxcheck.py pass.
--- rust/syn/attr.rs | 2 ++ rust/syn/bigint.rs | 2 ++ rust/syn/buffer.rs | 2 ++ rust/syn/classify.rs | 2 ++ rust/syn/custom_keyword.rs | 2 ++ rust/syn/custom_punctuation.rs | 2 ++ rust/syn/data.rs | 2 ++ rust/syn/derive.rs | 2 ++ rust/syn/discouraged.rs | 2 ++ rust/syn/drops.rs | 2 ++ rust/syn/error.rs | 2 ++ rust/syn/export.rs | 2 ++ rust/syn/expr.rs | 2 ++ rust/syn/ext.rs | 2 ++ rust/syn/file.rs | 2 ++ rust/syn/fixup.rs | 2 ++ rust/syn/gen/clone.rs | 2 ++ rust/syn/gen/debug.rs | 2 ++ rust/syn/gen/eq.rs | 2 ++ rust/syn/gen/fold.rs | 2 ++ rust/syn/gen/hash.rs | 2 ++ rust/syn/gen/visit.rs | 2 ++ rust/syn/gen/visit_mut.rs | 2 ++ rust/syn/generics.rs | 2 ++ rust/syn/group.rs | 2 ++ rust/syn/ident.rs | 2 ++ rust/syn/item.rs | 2 ++ rust/syn/lib.rs | 2 ++ rust/syn/lifetime.rs | 2 ++ rust/syn/lit.rs | 2 ++ rust/syn/lookahead.rs | 2 ++ rust/syn/mac.rs | 2 ++ rust/syn/macros.rs | 2 ++ rust/syn/meta.rs | 2 ++ rust/syn/op.rs | 2 ++ rust/syn/parse.rs | 2 ++ rust/syn/parse_macro_input.rs | 2 ++ rust/syn/parse_quote.rs | 2 ++ rust/syn/pat.rs | 2 ++ rust/syn/path.rs | 2 ++ rust/syn/precedence.rs | 2 ++ rust/syn/print.rs | 2 ++ rust/syn/punctuated.rs | 2 ++ rust/syn/restriction.rs | 2 ++ rust/syn/scan_expr.rs | 2 ++ rust/syn/sealed.rs | 2 ++ rust/syn/span.rs | 2 ++ rust/syn/spanned.rs | 2 ++ rust/syn/stmt.rs | 2 ++ rust/syn/thread.rs | 2 ++ rust/syn/token.rs | 2 ++ rust/syn/tt.rs | 2 ++ rust/syn/ty.rs | 2 ++ rust/syn/verbatim.rs | 2 ++ rust/syn/whitespace.rs | 2 ++ 55 files changed, 110 insertions(+)
rust/syn/attr.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "parsing" )] use crate ::error::Error ;#[cfg(feature = "parsing" )]
rust/syn/bigint.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use std::ops::{AddAssign ,MulAssign };// For implementing base10_digits() accessor on LitInt.
rust/syn/buffer.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! A stably addressed token buffer supporting efficient traversal based on a //! cheaply copyable cursor.
rust/syn/classify.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "full" )] use crate ::expr::Expr ;#[cfg(any(feature = "printing" , feature = "full" ))]
rust/syn/custom_keyword.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +/// Define a type that supports parsing and printing a given identifier as if it /// were a keyword. ///
rust/syn/custom_punctuation.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +/// Define a type that supports parsing and printing a multi-character symbol /// as if it were a punctuation token. ///
rust/syn/data.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;use crate ::expr::{Expr ,Index ,Member };use crate ::ident::Ident ;
rust/syn/derive.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;use crate ::data::{Fields ,FieldsNamed ,Variant };use crate ::generics::Generics ;
rust/syn/discouraged.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! Extensions to the parsing API with niche applicability. use crate ::buffer::Cursor ;
rust/syn/drops.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use std::iter;use std::mem::ManuallyDrop ;use std::ops::{Deref ,DerefMut };
rust/syn/error.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "parsing" )] use crate ::buffer::Cursor ;use crate ::thread::ThreadBound ;
rust/syn/export.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[doc(hidden)] pub use std::clone::Clone ;#[doc(hidden)]
rust/syn/expr.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;#[cfg(all(feature = "parsing" , feature = "full" ))] use crate ::error::Result ;
rust/syn/ext.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! Extension traits to provide parsing methods on foreign types. use crate ::buffer::Cursor ;
rust/syn/file.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;use crate ::item::Item ;
rust/syn/fixup.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::classify;use crate ::expr::Expr ;#[cfg(feature = "full" )]
rust/syn/gen/clone.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by syn-internal-codegen. // It is not intended for manual editing.
rust/syn/gen/debug.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by syn-internal-codegen. // It is not intended for manual editing.
rust/syn/gen/eq.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by syn-internal-codegen. // It is not intended for manual editing.
rust/syn/gen/fold.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by syn-internal-codegen. // It is not intended for manual editing.
rust/syn/gen/hash.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by syn-internal-codegen. // It is not intended for manual editing.
rust/syn/gen/visit.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by syn-internal-codegen. // It is not intended for manual editing.
rust/syn/gen/visit_mut.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// This file is @generated by syn-internal-codegen. // It is not intended for manual editing.
rust/syn/generics.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;use crate ::expr::Expr ;use crate ::ident::Ident ;
rust/syn/group.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::error::Result ;use crate ::parse::ParseBuffer ;use crate ::token;
rust/syn/ident.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "parsing" )] use crate ::lookahead;
rust/syn/item.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;use crate ::data::{Fields ,FieldsNamed ,Variant };use crate ::derive::{Data ,DataEnum ,DataStruct ,DataUnion ,DeriveInput };
rust/syn/lib.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! [![github]](https://github.com/dtolnay/syn) [![crates-io]](https://crates.io/crates/syn) [![docs-rs]](crate) //! //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
rust/syn/lifetime.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "parsing" )] use crate ::lookahead;use proc_macro2::{Ident ,Span };
rust/syn/lit.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "parsing" )] use crate ::lookahead;#[cfg(feature = "parsing" )]
rust/syn/lookahead.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::buffer::Cursor ;use crate ::error::{self,Error };use crate ::sealed::lookahead::Sealed ;
rust/syn/mac.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "parsing" )] use crate ::error::Result ;#[cfg(feature = "parsing" )]
rust/syn/macros.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + #[cfg_attr( not(any(feature = "full", feature = "derive")), allow(unknown_lints, unused_macro_rules)
rust/syn/meta.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! Facility for interpreting structured content inside of an `Attribute`. use crate ::error::{Error ,Result };
rust/syn/op.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +ast_enum! {/// A binary operator: `+`, `+=`, `&`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full" , feature = "derive" ))))]
rust/syn/parse.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! Parsing interface for parsing a token stream into a syntax tree node. //! //! Parsing in Syn is built on parser functions that take in a [`ParseStream`]
rust/syn/parse_macro_input.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +/// Parse the input TokenStream of a macro, triggering a compile error if the /// tokens fail to parse. ///
rust/syn/parse_quote.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses /// type inference to figure out a return type for those tokens. ///
rust/syn/pat.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;use crate ::expr::Member ;use crate ::ident::Ident ;
rust/syn/path.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "parsing" )] use crate ::error::Result ;use crate ::expr::Expr ;
rust/syn/precedence.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(all(feature = "printing" , feature = "full" ))] use crate ::attr::{AttrStyle ,Attribute };#[cfg(feature = "printing" )]
rust/syn/print.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use proc_macro2::TokenStream ;use quote::ToTokens ;
rust/syn/punctuated.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! A punctuated sequence of syntax tree nodes separated by punctuation. //! //! Lots of things in Rust are punctuated sequences.
rust/syn/restriction.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::path::Path ;use crate ::token;
rust/syn/scan_expr.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use self::{Action ::*,Input ::*};use proc_macro2::{Delimiter ,Ident ,Spacing ,TokenTree };use syn::parse::{ParseStream ,Result };
rust/syn/sealed.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +#[cfg(feature = "parsing" )] pub (crate )mod lookahead {pub trait Sealed :Copy {}
rust/syn/span.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use proc_macro2::extra::DelimSpan ;use proc_macro2::{Delimiter ,Group ,Span ,TokenStream };
rust/syn/spanned.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! A trait that can provide the `Span` of the complete contents of a syntax //! tree node. //!
rust/syn/stmt.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;use crate ::expr::Expr ;use crate ::item::Item ;
rust/syn/thread.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use std::fmt::{self,Debug };use std::thread::{self,ThreadId };
rust/syn/token.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +//! Tokens representing Rust punctuation, keywords, and delimiters. //! //! The type names in this module can be difficult to keep straight, so we
rust/syn/tt.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use proc_macro2::{Delimiter ,TokenStream ,TokenTree };use std::hash::{Hash ,Hasher };
rust/syn/ty.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::attr::Attribute ;use crate ::expr::Expr ;use crate ::generics::{BoundLifetimes ,TypeParamBound };
rust/syn/verbatim.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +use crate ::parse::ParseStream ;use proc_macro2::{Delimiter ,TokenStream };use std::cmp::Ordering ;
rust/syn/whitespace.rs +2 -0
@@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +pub (crate )fn skip (mut s: &str ) -> &str { 'skip:while !s.is_empty () {let byte = s.as_bytes ()[0 ];
Signature · 1 line
2.51.2
Miguel Ojeda
maintainerPATCH 16/18 rust: syn: remove `unicode-ident` dependency
In reply to Miguel OjedaThe syn crate depends on the unicode-ident crate to determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31.
However, we only need ASCII identifiers in the kernel, thus we can simplify the check and remove completely that dependency.
--- rust/syn/ident.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
rust/syn/ident.rs +2 -2
@@ -39,11 +39,11 @@ fn from(token: Token![_]) -> Ident {pub (crate )fn xid_ok (symbol: &str ) ->bool {let mut chars = symbol.chars ();let first = chars.next ().unwrap (); -if !(first =='_' || unicode_ident::is_xid_start (first)) { +if !(first =='_' || first.is_ascii_alphabetic ()) {return false ; }for chin chars { -if !unicode_ident::is_xid_continue (ch) { +if !(ch =='_' || ch.is_ascii_alphanumeric ()) {return false ; } }
Signature · 1 line
2.51.2
Re: [PATCH 16/18] rust: syn: remove `unicode-ident` dependency
Quoted 8 lines · Miguel Ojeda
The
syncrate depends on theunicode-identcrate to determine whether characters have theXID_StartorXID_Continueproperties according to Unicode Standard Annex #31.However, we only need ASCII identifiers in the kernel, thus we can simplify the check and remove completely that dependency.
Signed-off-by Miguel Ojeda <[email protected]>
Miguel Ojeda
maintainerPATCH 17/18 rust: syn: add `README.md`
In reply to Miguel OjedaOriginally, when the Rust upstream alloc standard library crate was vendored in commit 057b8d257107 ("rust: adapt alloc crate to the kernel"), a README.md file was added to explain the provenance and licensing of the source files.
Thus do the same for the syn crate.
--- rust/syn/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 rust/syn/README.md
rust/syn/README.md new file +13 -0
@@ -0,0 +1,13 @@ +# `syn` + +These source files come from the Rust `syn` crate, version 2.0.106 +(released 2025-08-16), hosted in the <https://github.com/dtolnay/syn> +repository, licensed under "Apache-2.0 OR MIT" and only modified to add +the SPDX license identifiers and to remove the `unicode-ident` +dependency. + +For copyright details, please see: + + https://github.com/dtolnay/syn/blob/2.0.106/README.md#license + https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-APACHE + https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-MIT
Signature · 1 line
2.51.2
Re: [PATCH 17/18] rust: syn: add `README.md`
Quoted 35 lines · Miguel Ojeda
Originally, when the Rust upstream
allocstandard library crate was vendored in commit057b8d257107("rust: adaptalloccrate to the kernel"), aREADME.mdfile was added to explain the provenance and licensing of the source files.Thus do the same for the
syncrate.Signed-off-by Miguel Ojeda <[email protected]>--- rust/syn/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 rust/syn/README.mdrust/syn/README.md new file +13
-0@@ -0,0 +1,13 @@ +# `syn` + +These source files come from the Rust `syn` crate, version 2.0.106 +(released 2025-08-16), hosted in the <https://github.com/dtolnay/syn> +repository, licensed under "Apache-2.0 OR MIT" and only modified to add +the SPDX license identifiers and to remove the `unicode-ident` +dependency. + +For copyright details, please see: + + https://github.com/dtolnay/syn/blob/2.0.106/README.md#license + https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-APACHE + https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-MITSignature · 1 line
2.51.2
Miguel Ojeda
maintainerPATCH 18/18 rust: syn: enable support in kbuild
In reply to Miguel OjedaWith all the new files in place and ready from the new crate, enable the support for it in the build system.
--- Makefile | 1 + rust/Makefile | 39 +++++++++++++++++++++++++++---- scripts/generate_rust_analyzer.py | 7 ++++++ 3 files changed, 43 insertions(+), 4 deletions(-)
Makefile +1 -0
@@ -1833,6 +1833,7 @@ rustfmt: \( \ -path $(srctree)/rust/proc-macro2 \ -o -path $(srctree)/rust/quote \ + -o -path $(srctree)/rust/syn \ \) -prune -o \ -type f -a -name '*.rs' -a ! -name '*generated*' -print \ | xargs $(RUSTFMT) $(rustfmt_flags)
rust/Makefile +35 -4
@@ -27,7 +27,7 @@ endif obj-$(CONFIG_RUST) += exports.o -always-$(CONFIG_RUST) += libproc_macro2.rlib libquote.rlib +always-$(CONFIG_RUST) += libproc_macro2.rlib libquote.rlib libsyn.rlib always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.rs always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c
@@ -101,6 +101,22 @@ quote-flags := \ --extern proc_macro2 \ $(call cfgs-to-flags,$(quote-cfgs)) +# `extra-traits`, `fold` and `visit` may be enabled if needed. +syn-cfgs := \ + feature="clone-impls" \ + feature="derive" \ + feature="full" \ + feature="parsing" \ + feature="printing" \ + feature="proc-macro" \ + feature="visit-mut" + +syn-flags := \ + --cap-lints=allow \ + --extern proc_macro2 \ + --extern quote \ + $(call cfgs-to-flags,$(syn-cfgs)) + # `rustdoc` did not save the target modifiers, thus workaround for # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18)
@@ -164,11 +180,16 @@ rustdoc-quote: private skip_flags = $(quote-skip_flags) rustdoc-quote: $(src)/quote/lib.rs rustdoc-clean rustdoc-proc_macro2 FORCE +$(call if_changed,rustdoc) +rustdoc-syn: private rustdoc_host = yes +rustdoc-syn: private rustc_target_flags = $(syn-flags) +rustdoc-syn: $(src)/syn/lib.rs rustdoc-clean rustdoc-quote FORCE + +$(call if_changed,rustdoc) + rustdoc-macros: private rustdoc_host = yes rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ --extern proc_macro rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean rustdoc-proc_macro2 \ - rustdoc-quote FORCE + rustdoc-quote rustdoc-syn FORCE +$(call if_changed,rustdoc) # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should
@@ -240,6 +261,10 @@ rusttestlib-quote: private rustc_target_flags = $(quote-flags) rusttestlib-quote: $(src)/quote/lib.rs rusttestlib-proc_macro2 FORCE +$(call if_changed,rustc_test_library) +rusttestlib-syn: private rustc_target_flags = $(syn-flags) +rusttestlib-syn: $(src)/syn/lib.rs rusttestlib-quote FORCE + +$(call if_changed,rustc_test_library) + rusttestlib-macros: private rustc_target_flags = --extern proc_macro rusttestlib-macros: private rustc_test_library_proc = yes rusttestlib-macros: $(src)/macros/lib.rs FORCE
@@ -497,19 +522,24 @@ $(obj)/libquote.rlib: private rustc_target_flags = $(quote-flags) $(obj)/libquote.rlib: $(src)/quote/lib.rs $(obj)/libproc_macro2.rlib FORCE +$(call if_changed_dep,rustc_hostlibrary) +$(obj)/libsyn.rlib: private skip_clippy = 1 +$(obj)/libsyn.rlib: private rustc_target_flags = $(syn-flags) +$(obj)/libsyn.rlib: $(src)/syn/lib.rs $(obj)/libquote.rlib FORCE + +$(call if_changed_dep,rustc_hostlibrary) + quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ cmd_rustc_procmacro = \ $(RUSTC_OR_CLIPPY) $(rust_common_flags) $(rustc_target_flags) \ -Clinker-flavor=gcc -Clinker=$(HOSTCC) \ -Clink-args='$(call escsq,$(KBUILD_PROCMACROLDFLAGS))' \ --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ - --crate-type proc-macro \ + --crate-type proc-macro -L$(objtree)/$(obj) \ --crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) \ @$(objtree)/include/generated/rustc_cfg $< # Procedural macros can only be used with the `rustc` that compiled it. $(obj)/$(libmacros_name): $(src)/macros/lib.rs $(obj)/libproc_macro2.rlib \ - $(obj)/libquote.rlib FORCE + $(obj)/libquote.rlib $(obj)/libsyn.rlib FORCE +$(call if_changed_dep,rustc_procmacro) $(obj)/$(libpin_init_internal_name): private rustc_target_flags = --cfg kernel
@@ -534,6 +564,7 @@ rust-analyzer: --cfgs='core=$(core-cfgs)' $(core-edition) \ --cfgs='proc_macro2=$(proc_macro2-cfgs)' \ --cfgs='quote=$(quote-cfgs)' \ + --cfgs='syn=$(syn-cfgs)' \ $(realpath $(srctree)) $(realpath $(objtree)) \ $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ > rust-project.json
scripts/generate_rust_analyzer.py +7 -0
@@ -100,6 +100,13 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit cfg=crates_cfgs["quote"], ) + append_crate( + "syn", + srctree / "rust" / "syn" / "lib.rs", + ["proc_macro", "proc_macro2", "quote"], + cfg=crates_cfgs["syn"], + ) + append_crate( "macros", srctree / "rust" / "macros" / "lib.rs",
Signature · 1 line
2.51.2
Alice Ryhl
maintainerRe: [PATCH 18/18] rust: syn: enable support in kbuild
Quoted 7 lines · Miguel Ojeda
With all the new files in place and ready from the new crate, enable the support for it in the build system.
Signed-off-by Miguel Ojeda <[email protected]>
quiet_cmd_rustc_procmacro= $(RUSTC_OR_CLIPPY_QUIET) P $@cmd_rustc_procmacro = \
rust/Makefile $(obj)/libquote.rlib: private rustc_target_flags = $(quote-flags) · line 538
Quoted 8 lines
rust/Makefile +1
-1$(RUSTC_OR_CLIPPY) $(rust_common_flags) $(rustc_target_flags) \ -Clinker-flavor=gcc -Clinker=$(HOSTCC) \ -Clink-args='$(call escsq,$(KBUILD_PROCMACROLDFLAGS))' \ --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ - --crate-type proc-macro \ + --crate-type proc-macro -L$(objtree)/$(obj) \ --crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) \ @$(objtree)/include/generated/rustc_cfg $<
This change seems unrelated?
Alice
Re: [PATCH 18/18] rust: syn: enable support in kbuild
Quoted 2 lines · Alice Ryhl
This change seems unrelated?
It is needed to actually use them in proc macros, e.g. to build the new pin-init. We could move it to that patch series, but then it means it is harder to use this series (e.g. someone was waiting to port other macros).
I can put it in a final patch or perhaps just mention it in the log, similar to the quote one.
Cheers,
Miguel
Re: [PATCH 18/18] rust: syn: enable support in kbuild
Quoted 11 lines · Miguel Ojeda
Quoted 2 lines · Alice Ryhl
This change seems unrelated?
It is needed to actually use them in proc macros, e.g. to build the new
pin-init. We could move it to that patch series, but then it means it is harder to use this series (e.g. someone was waiting to port other macros).I can put it in a final patch or perhaps just mention it in the log, similar to the
quoteone.
With that mentioned in the commit message:
Re: [PATCH 18/18] rust: syn: enable support in kbuild
In reply to Miguel OjedaQuoted 15 lines · Miguel Ojeda
With all the new files in place and ready from the new crate, enable the support for it in the build system.
Signed-off-by Miguel Ojeda <[email protected]>--- Makefile | 1 + rust/Makefile | 39 +++++++++++++++++++++++++++---- scripts/generate_rust_analyzer.py | 7 ++++++ 3 files changed, 43 insertions(+), 4 deletions(-)Makefile +0
-0
Makefile rustfmt: · line 1836
Quoted 4 lines
Makefile +1
-0@@ -1833,6 +1833,7 @@ rustfmt: \( \ -path $(srctree)/rust/proc-macro2 \ -o -path $(srctree)/rust/quote \ + -o -path $(srctree)/rust/syn \
At this point, a "vendored" subdirectory for these three items is starting to sound even better, from a self-documenting point of view, yes?
thanks,
Signature · 1 line
John Hubbard
Quoted 121 lines
Makefile +0
-0\) -prune -o \ -type f -a -name '*.rs' -a ! -name '*generated*' -print \ | xargs $(RUSTFMT) $(rustfmt_flags)rust/Makefile +35
-4@@ -27,7 +27,7 @@ endif obj-$(CONFIG_RUST) += exports.o -always-$(CONFIG_RUST) += libproc_macro2.rlib libquote.rlib +always-$(CONFIG_RUST) += libproc_macro2.rlib libquote.rlib libsyn.rlib always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.rs always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c@@ -101,6 +101,22 @@ quote-flags := \ --extern proc_macro2 \ $(call cfgs-to-flags,$(quote-cfgs)) +# `extra-traits`, `fold` and `visit` may be enabled if needed. +syn-cfgs := \ + feature="clone-impls" \ + feature="derive" \ + feature="full" \ + feature="parsing" \ + feature="printing" \ + feature="proc-macro" \ + feature="visit-mut" + +syn-flags := \ + --cap-lints=allow \ + --extern proc_macro2 \ + --extern quote \ + $(call cfgs-to-flags,$(syn-cfgs)) + # `rustdoc` did not save the target modifiers, thus workaround for # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18)@@ -164,11 +180,16 @@ rustdoc-quote: private skip_flags = $(quote-skip_flags) rustdoc-quote: $(src)/quote/lib.rs rustdoc-clean rustdoc-proc_macro2 FORCE +$(call if_changed,rustdoc) +rustdoc-syn: private rustdoc_host = yes +rustdoc-syn: private rustc_target_flags = $(syn-flags) +rustdoc-syn: $(src)/syn/lib.rs rustdoc-clean rustdoc-quote FORCE + +$(call if_changed,rustdoc) + rustdoc-macros: private rustdoc_host = yes rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ --extern proc_macro rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean rustdoc-proc_macro2 \ - rustdoc-quote FORCE + rustdoc-quote rustdoc-syn FORCE +$(call if_changed,rustdoc) # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should@@ -240,6 +261,10 @@ rusttestlib-quote: private rustc_target_flags = $(quote-flags) rusttestlib-quote: $(src)/quote/lib.rs rusttestlib-proc_macro2 FORCE +$(call if_changed,rustc_test_library) +rusttestlib-syn: private rustc_target_flags = $(syn-flags) +rusttestlib-syn: $(src)/syn/lib.rs rusttestlib-quote FORCE + +$(call if_changed,rustc_test_library) + rusttestlib-macros: private rustc_target_flags = --extern proc_macro rusttestlib-macros: private rustc_test_library_proc = yes rusttestlib-macros: $(src)/macros/lib.rs FORCE@@ -497,19 +522,24 @@ $(obj)/libquote.rlib: private rustc_target_flags = $(quote-flags) $(obj)/libquote.rlib: $(src)/quote/lib.rs $(obj)/libproc_macro2.rlib FORCE +$(call if_changed_dep,rustc_hostlibrary) +$(obj)/libsyn.rlib: private skip_clippy = 1 +$(obj)/libsyn.rlib: private rustc_target_flags = $(syn-flags) +$(obj)/libsyn.rlib: $(src)/syn/lib.rs $(obj)/libquote.rlib FORCE + +$(call if_changed_dep,rustc_hostlibrary) + quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ cmd_rustc_procmacro = \ $(RUSTC_OR_CLIPPY) $(rust_common_flags) $(rustc_target_flags) \ -Clinker-flavor=gcc -Clinker=$(HOSTCC) \ -Clink-args='$(call escsq,$(KBUILD_PROCMACROLDFLAGS))' \ --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ - --crate-type proc-macro \ + --crate-type proc-macro -L$(objtree)/$(obj) \ --crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) \ @$(objtree)/include/generated/rustc_cfg $< # Procedural macros can only be used with the `rustc` that compiled it. $(obj)/$(libmacros_name): $(src)/macros/lib.rs $(obj)/libproc_macro2.rlib \ - $(obj)/libquote.rlib FORCE + $(obj)/libquote.rlib $(obj)/libsyn.rlib FORCE +$(call if_changed_dep,rustc_procmacro) $(obj)/$(libpin_init_internal_name): private rustc_target_flags = --cfg kernel@@ -534,6 +564,7 @@ rust-analyzer: --cfgs='core=$(core-cfgs)' $(core-edition) \ --cfgs='proc_macro2=$(proc_macro2-cfgs)' \ --cfgs='quote=$(quote-cfgs)' \ + --cfgs='syn=$(syn-cfgs)' \ $(realpath $(srctree)) $(realpath $(objtree)) \ $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ > rust-project.jsonscripts/generate_rust_analyzer.py +7
-0@@ -100,6 +100,13 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit cfg=crates_cfgs["quote"], ) + append_crate( + "syn", + srctree / "rust" / "syn" / "lib.rs", + ["proc_macro", "proc_macro2", "quote"], + cfg=crates_cfgs["syn"], + ) + append_crate( "macros", srctree / "rust" / "macros" / "lib.rs",
Quoted 45 lines · On Mon, 10 Nov 2025 10:50:05 +0100 Miguel Ojeda <[email protected]> wrote:
This patch series introduces support for
syn(and its dependencies). Having such support allows to greatly simplify writing complex macros such aspin-init.Benno has already prepared the
pin-initversion based on this, and on top of that, we will be able to simplify themacroscrate too.The series starts with a few preparation commits (two fixes were already merged in mainline that were discovered by this series), then each crate is added.
This has been a long time coming -- the first iterations of this, from 2022 and 2023 (with
serdetoo), are at:https://github.com/Rust-for-Linux/linux/pull/910 https://github.com/Rust-for-Linux/linux/pull/1007After those, we considered picking these from the distributions where possible. However, after discussing it, it is not really worth the
complexity: vendoring makes things less complex and is less fragile.In particular, we avoid having to support and test several versions, we avoid having to introduce Cargo just to properly fetch the right versions from the registry, we can easily customize the crates if needed (e.g. dropping the
unicode_identsdependency like it is done in this series) and we simplify the configuration of the build for users for which the "default" paths/registries would not have worked.Moreover, nowadays, the ~57k lines introduced are not that much compared to years ago (it dwarfed the actual Rust kernel code). Moreover, back then it wasn't clear the Rust experiment would be a success, so it would have been a bit pointless/risky to add many lines for nothing. Our macro needs were also smaller in the early days.
So, finally, in Kangrejos 2025 we discussed going with the original, simpler approach. Thus here it is the result.
There should not be many updates needed for these, and even if there are, they should not be too big, e.g. +7k -3k lines across the 3 crates in the last year.
Note that
syndoes not have all the features enabled, since we do not need them so far, but they can easily be enabled just adding them to the list.
Quoted 5 lines
I will be updating the webpage as well with the result of this:
https://rust-for-linux.com/third-party-crates
Please give it a test -- thanks!
Hi Miguel,
Thank you for creating this. I have been wanting to use syn even before RfL was merged into mainline :)
I've gone through all commits and they all look good to me (I've also verified the "import crate" patches against the source). So
I can build with these patches and I've verified that libmacros can indeed reference types within syn, so also
Best,
Gary
Quoted 186 lines
Miguel Ojeda (18):
rust: condvar: avoidpubin example
rust: kbuild: introducecore-flagsandcore-skip_flags
rust: kbuild: simplify--cfghandling
rust: kbuild: add host library support
rust: proc-macro2: import crate
rust: proc-macro2: add SPDX License Identifiers
rust: proc-macro2: removeunicode_identdependency
rust: proc-macro2: addREADME.md
rust: proc-macro2: enable support in kbuild
rust: quote: import crate
rust: quote: add SPDX License Identifiers
rust: quote: addREADME.md
rust: quote: enable support in kbuild
rust: syn: import crate
rust: syn: add SPDX License Identifiers
rust: syn: removeunicode-identdependency
rust: syn: addREADME.md
rust: syn: enable support in kbuild.gitignore | 1 + Makefile | 5 + rust/Makefile | 134 +- rust/kernel/sync/condvar.rs | 2 +- rust/proc-macro2/README.md | 13 + rust/proc-macro2/detection.rs | 77 + rust/proc-macro2/extra.rs | 153 + rust/proc-macro2/fallback.rs | 1258 +++++ rust/proc-macro2/lib.rs | 1351 ++++++ rust/proc-macro2/location.rs | 31 + rust/proc-macro2/marker.rs | 19 + rust/proc-macro2/parse.rs | 997 ++++ rust/proc-macro2/probe.rs | 12 + rust/proc-macro2/probe/proc_macro_span.rs | 53 + .../proc-macro2/probe/proc_macro_span_file.rs | 16 + .../probe/proc_macro_span_location.rs | 23 + rust/proc-macro2/rcvec.rs | 148 + rust/proc-macro2/wrapper.rs | 986 ++++ rust/quote/README.md | 12 + rust/quote/ext.rs | 112 + rust/quote/format.rs | 170 + rust/quote/ident_fragment.rs | 90 + rust/quote/lib.rs | 1456 ++++++ rust/quote/runtime.rs | 494 ++ rust/quote/spanned.rs | 52 + rust/quote/to_tokens.rs | 273 ++ rust/syn/README.md | 13 + rust/syn/attr.rs | 838 ++++ rust/syn/bigint.rs | 68 + rust/syn/buffer.rs | 436 ++ rust/syn/classify.rs | 313 ++ rust/syn/custom_keyword.rs | 262 ++ rust/syn/custom_punctuation.rs | 306 ++ rust/syn/data.rs | 426 ++ rust/syn/derive.rs | 261 ++ rust/syn/discouraged.rs | 227 + rust/syn/drops.rs | 60 + rust/syn/error.rs | 469 ++ rust/syn/export.rs | 75 + rust/syn/expr.rs | 4175 +++++++++++++++++ rust/syn/ext.rs | 138 + rust/syn/file.rs | 127 + rust/syn/fixup.rs | 775 +++ rust/syn/gen/clone.rs | 2269 +++++++++ rust/syn/gen/debug.rs | 3240 +++++++++++++ rust/syn/gen/eq.rs | 2308 +++++++++ rust/syn/gen/fold.rs | 3904 +++++++++++++++ rust/syn/gen/hash.rs | 2878 ++++++++++++ rust/syn/gen/visit.rs | 3943 ++++++++++++++++ rust/syn/gen/visit_mut.rs | 3761 +++++++++++++++ rust/syn/generics.rs | 1479 ++++++ rust/syn/group.rs | 293 ++ rust/syn/ident.rs | 110 + rust/syn/item.rs | 3492 ++++++++++++++ rust/syn/lib.rs | 1013 ++++ rust/syn/lifetime.rs | 158 + rust/syn/lit.rs | 1862 ++++++++ rust/syn/lookahead.rs | 334 ++ rust/syn/mac.rs | 227 + rust/syn/macros.rs | 184 + rust/syn/meta.rs | 429 ++ rust/syn/op.rs | 221 + rust/syn/parse.rs | 1421 ++++++ rust/syn/parse_macro_input.rs | 130 + rust/syn/parse_quote.rs | 242 + rust/syn/pat.rs | 957 ++++ rust/syn/path.rs | 968 ++++ rust/syn/precedence.rs | 212 + rust/syn/print.rs | 18 + rust/syn/punctuated.rs | 1157 +++++ rust/syn/restriction.rs | 180 + rust/syn/scan_expr.rs | 267 ++ rust/syn/sealed.rs | 6 + rust/syn/span.rs | 65 + rust/syn/spanned.rs | 120 + rust/syn/stmt.rs | 486 ++ rust/syn/thread.rs | 62 + rust/syn/token.rs | 1098 +++++ rust/syn/tt.rs | 109 + rust/syn/ty.rs | 1273 +++++ rust/syn/verbatim.rs | 35 + rust/syn/whitespace.rs | 67 + scripts/generate_rust_analyzer.py | 23 +- 83 files changed, 57895 insertions(+), 13 deletions(-) create mode 100644 rust/proc-macro2/README.md create mode 100644 rust/proc-macro2/detection.rs create mode 100644 rust/proc-macro2/extra.rs create mode 100644 rust/proc-macro2/fallback.rs create mode 100644 rust/proc-macro2/lib.rs create mode 100644 rust/proc-macro2/location.rs create mode 100644 rust/proc-macro2/marker.rs create mode 100644 rust/proc-macro2/parse.rs create mode 100644 rust/proc-macro2/probe.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span_file.rs create mode 100644 rust/proc-macro2/probe/proc_macro_span_location.rs create mode 100644 rust/proc-macro2/rcvec.rs create mode 100644 rust/proc-macro2/wrapper.rs create mode 100644 rust/quote/README.md create mode 100644 rust/quote/ext.rs create mode 100644 rust/quote/format.rs create mode 100644 rust/quote/ident_fragment.rs create mode 100644 rust/quote/lib.rs create mode 100644 rust/quote/runtime.rs create mode 100644 rust/quote/spanned.rs create mode 100644 rust/quote/to_tokens.rs create mode 100644 rust/syn/README.md create mode 100644 rust/syn/attr.rs create mode 100644 rust/syn/bigint.rs create mode 100644 rust/syn/buffer.rs create mode 100644 rust/syn/classify.rs create mode 100644 rust/syn/custom_keyword.rs create mode 100644 rust/syn/custom_punctuation.rs create mode 100644 rust/syn/data.rs create mode 100644 rust/syn/derive.rs create mode 100644 rust/syn/discouraged.rs create mode 100644 rust/syn/drops.rs create mode 100644 rust/syn/error.rs create mode 100644 rust/syn/export.rs create mode 100644 rust/syn/expr.rs create mode 100644 rust/syn/ext.rs create mode 100644 rust/syn/file.rs create mode 100644 rust/syn/fixup.rs create mode 100644 rust/syn/gen/clone.rs create mode 100644 rust/syn/gen/debug.rs create mode 100644 rust/syn/gen/eq.rs create mode 100644 rust/syn/gen/fold.rs create mode 100644 rust/syn/gen/hash.rs create mode 100644 rust/syn/gen/visit.rs create mode 100644 rust/syn/gen/visit_mut.rs create mode 100644 rust/syn/generics.rs create mode 100644 rust/syn/group.rs create mode 100644 rust/syn/ident.rs create mode 100644 rust/syn/item.rs create mode 100644 rust/syn/lib.rs create mode 100644 rust/syn/lifetime.rs create mode 100644 rust/syn/lit.rs create mode 100644 rust/syn/lookahead.rs create mode 100644 rust/syn/mac.rs create mode 100644 rust/syn/macros.rs create mode 100644 rust/syn/meta.rs create mode 100644 rust/syn/op.rs create mode 100644 rust/syn/parse.rs create mode 100644 rust/syn/parse_macro_input.rs create mode 100644 rust/syn/parse_quote.rs create mode 100644 rust/syn/pat.rs create mode 100644 rust/syn/path.rs create mode 100644 rust/syn/precedence.rs create mode 100644 rust/syn/print.rs create mode 100644 rust/syn/punctuated.rs create mode 100644 rust/syn/restriction.rs create mode 100644 rust/syn/scan_expr.rs create mode 100644 rust/syn/sealed.rs create mode 100644 rust/syn/span.rs create mode 100644 rust/syn/spanned.rs create mode 100644 rust/syn/stmt.rs create mode 100644 rust/syn/thread.rs create mode 100644 rust/syn/token.rs create mode 100644 rust/syn/tt.rs create mode 100644 rust/syn/ty.rs create mode 100644 rust/syn/verbatim.rs create mode 100644 rust/syn/whitespace.rs--
2.51.2
Quoted 3 lines · Gary Guo
Thank you for creating this. I have been wanting to use
syneven before RfL was merged into mainline :)
Indeed, you were definitely one of the biggest proponents of syn since the beginning! I could have mentioned a bit more of the older history in the cover letter, sorry.
In a sense, this cover letter could have had a Supported-by/Wanted-by/...: Gary & Benno et al. Actually, I may just add that :) And/or perhaps something about the history in the actual commit messages or use the cover letter in a merge.
Thanks a lot for the very quick reviews and tests!
Cheers,
Miguel
Jesung Yang
reviewerQuoted 2 lines · Gary Guo
I can build with these patches and I've verified that libmacros can indeed reference types within
syn, so also
Hi,
I've been trying to apply this patch on the current rust-next HEAD 494de8f67b1e ("rust: sync: replace kernel::c_str! with C-Strings") and test it, since I need this series for my future patch revision.
Unfortunately, when I make the following change:
diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
index 793f712dbf7c..084633b517be 100644
--- a/rust/macros/lib.rs
+++ b/rust/macros/lib.rs
@@ -444,3 +444,14 @@ pub fn paste(input: TokenStream) -> TokenStream {
pub fn kunit_tests(attr: TokenStream, ts: TokenStream) -> TokenStream {
kunit::kunit_tests(attr, ts)
}
+
+use syn::{
+ parse_macro_input,
+ DeriveInput, //
+};
+
+#[proc_macro_attribute]
+pub fn dummy(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as DeriveInput);
+ todo!()
+}It fails to compile:
error[E0432]: unresolved import syn
--> rust/macros/lib.rs:448:5
|
448 | use syn::{
| ^^^ use of unresolved module or unlinked crate syn
|
= help: you might be missing a crate named syn
error: aborting due to 1 previous error
It appears that the vendored crates are indeed compiled; I can see some build artifacts like rust/libsyn.rlib, libquote.rlib, etc.
For reference, here's the sequence of commands I ran to compile the kernel:
make LLVM=1 ARCH=arm64 rustavailable
make LLVM=1 ARCH=arm64 defconfig
scripts/config --enable CONFIG_RUST
scripts/config --enable CONFIG_SAMPLES
scripts/config --enable CONFIG_SAMPLES_RUST
scripts/config --module CONFIG_SAMPLE_RUST_MINIMAL
scripts/config --enable CONFIG_KUNIT
scripts/config --enable CONFIG_RUST_KERNEL_DOCTESTS
make LLVM=1 ARCH=arm64 olddefconfig
make LLVM=1 ARCH=arm64 CLIPPY=1 -j8I'd appreciate any guidance on steps I might be missing. Thanks in advance!
Best Regards,
Jesung
Miguel Ojeda
maintainerQuoted 3 lines · On Fri, 21 Nov 2025 04:37:47 +0000 Jesung Yang <[email protected]> wrote:
I'd appreciate any guidance on steps I might be missing. Thanks in advance!
For using (all of) them from macros, you would need [1].
Maybe I should just put it on top of this series for convenience.
Cheers,
Miguel
rust/Makefile +9 -4
@@ -187,7 +187,7 @@ rustdoc-syn: $(src)/syn/lib.rs rustdoc-clean rustdoc-quote FORCE rustdoc-macros: private rustdoc_host = yes rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ - --extern proc_macro + --extern proc_macro --extern proc_macro2 --extern quote --extern syn rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean rustdoc-proc_macro2 \ rustdoc-quote rustdoc-syn FORCE +$(call if_changed,rustdoc)
@@ -265,9 +265,11 @@ rusttestlib-syn: private rustc_target_flags = $(syn-flags) rusttestlib-syn: $(src)/syn/lib.rs rusttestlib-quote FORCE +$(call if_changed,rustc_test_library) -rusttestlib-macros: private rustc_target_flags = --extern proc_macro +rusttestlib-macros: private rustc_target_flags = --extern proc_macro \ + --extern proc_macro2 --extern quote --extern syn rusttestlib-macros: private rustc_test_library_proc = yes -rusttestlib-macros: $(src)/macros/lib.rs FORCE +rusttestlib-macros: $(src)/macros/lib.rs \ + rusttestlib-proc_macro2 rusttestlib-quote rusttestlib-syn FORCE +$(call if_changed,rustc_test_library) rusttestlib-pin_init_internal: private rustc_target_flags = --cfg kernel \
@@ -348,7 +350,8 @@ quiet_cmd_rustc_test = $(RUSTC_OR_CLIPPY_QUIET) T $< rusttest: rusttest-macros rusttest-macros: private rustc_target_flags = --extern proc_macro \ - --extern macros --extern kernel --extern pin_init + --extern macros --extern kernel --extern pin_init \ + --extern proc_macro2 --extern quote --extern syn rusttest-macros: private rustdoc_test_target_flags = --crate-type proc-macro rusttest-macros: $(src)/macros/lib.rs \ rusttestlib-macros rusttestlib-kernel rusttestlib-pin_init FORCE
@@ -538,6 +541,8 @@ quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ @$(objtree)/include/generated/rustc_cfg $< # Procedural macros can only be used with the `rustc` that compiled it. +$(obj)/$(libmacros_name): private rustc_target_flags = \ + --extern proc_macro2 --extern quote --extern syn $(obj)/$(libmacros_name): $(src)/macros/lib.rs $(obj)/libproc_macro2.rlib \ $(obj)/libquote.rlib $(obj)/libsyn.rlib FORCE +$(call if_changed_dep,rustc_procmacro)
Jesung Yang
reviewerQuoted 1 line · Miguel Ojeda
For using (all of) them from
macros, you would need [1].
Now everything compiles. Thanks!
By the way, I needed to make a small change to generate_rust_analyzer.py for rust-analyzer to correctly reference symbols from the vendored crates:
(quoted diff) +0 -0
b/scripts/generate_rust_analyzer.py
index 5b6f7b8d6918..147d0cc94068 100755
scripts/generate_rust_analyzer.py +0 -0
@@ -110,7 +110,7 @@ def generate_crates(srctree, objtree, sysroot_src,
external_src, cfgs, core_edit
append_crate(
"macros",
srctree / "rust" / "macros" / "lib.rs",
- ["std", "proc_macro"],
+ ["std", "proc_macro", "proc_macro2", "quote", "syn"],
is_proc_macro=True,
)This might already be covered somewhere else, but I'm bringing it up just in case.
Best Regards,
Jesung
Miguel Ojeda
Tested-by Jesung YangQuoted 2 lines · Jesung Yang
Now everything compiles. Thanks!
Great and thanks for testing! Do you mind if I add a:
?
Quoted 6 lines
By the way, I needed to make a small change to
generate_rust_analyzer.pyfor rust-analyzer to correctly reference symbols from the vendored crates:This might already be covered somewhere else, but I'm bringing it up just in case.
Definitely, it should be included.
Cheers,
Miguel
Jesung Yang
reviewerQuoted 6 lines · Miguel Ojeda
Great and thanks for testing! Do you mind if I add a:
Tested-by Jesung Yang <[email protected]>?
I'd be happy for you to! Thanks for asking.
Best Regards,
Jesung
Quoted 3 lines · Miguel Ojeda
This patch series introduces support for
syn(and its dependencies). Having such support allows to greatly simplify writing complex macros such aspin-init.
Just in case I'm not the only ignorant person who didn't immediately know what "syn" is and why we might want 57,000 lines of it in the kernel... :)
Syn is a parsing library for parsing a stream of Rust tokens into a syntax tree of Rust source code.
Currently this library is geared toward use in Rust procedural macros, but contains some APIs that may be useful more generally
https://docs.rs/syn/latest/syn/
Thanks,
jon
Quoted 4 lines · Jonathan Corbet
Just in case I'm not the only ignorant person who didn't immediately know what "syn" is and why we might want 57,000 lines of it in the kernel... :)
Thanks -- I will add something like that.
It has been such a long and recurrent topic in our discussions that I guess I was writing from inside the Rust for Linux's bubble.
Just to give a bit more context, it is the most downloaded Rust crate (according to crates.io). It (or something like it) is essentially a necessity for writing complex macros without too much pain.
Cheers,
Miguel
Benno Lossin
reviewerQuoted 6 lines · Miguel Ojeda
Quoted 4 lines · Jonathan Corbet
Just in case I'm not the only ignorant person who didn't immediately know what "syn" is and why we might want 57,000 lines of it in the kernel... :)
Quoted 8 lines
Thanks -- I will add something like that.
It has been such a long and recurrent topic in our discussions that I guess I was writing from inside the Rust for Linux's bubble.
Just to give a bit more context, it is the most downloaded Rust crate (according to crates.io). It (or something like it) is essentially a necessity for writing complex macros without too much pain.
It also is used by the Rust compiler itself for some proc-macros of their own.
Cheers,
Benno