Skip to content

Borrow a &str implicit argument without alloc - #288

Merged
soareschen merged 1 commit into
mainfrom
docs/no-std-implicits
Nov 7, 2026
Merged

soareschen merged 1 commit into
mainfrom
docs/no-std-implicits

Conversation

@soareschen

@soareschen soareschen commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Overview

[deepseek-v4.1-flash] A #[cgp_fn] or #[cgp_impl] with an #[implicit] name: &str argument now reads any AsRef<str> field, and an Option<&str> argument reads any Option<U> whose U converts to &str, so neither needs an allocator. Every conversion and field read the macros emit is also a fully qualified trait call.

Motivation

The &str implicit argument required a String field, so a crate without an allocator failed with "cannot find type String". The Option<&str> form required an Option<String> field for the same reason. Both bounds tied the field to one concrete type, and the first one made the argument unusable in the no_std build that the previous change added.

Impact

The generated bound for &str changes from Value = String to Value: AsRef<str> + 'static, and the read from .as_str() to .as_ref(). A String field still satisfies it, so existing contexts keep compiling, and a Cow<str> or a Box<str> field now works too.

The generated bound for Option<&str> changes from Value = Option<String> to Value: OptionAsRef<str> + 'static, and the read from .as_deref() to .option_as_ref(). OptionAsRef<T> is a new trait in cgp-field, with a blanket impl for every Option<U> whose U implements AsRef<T>; its ?Sized bound is what lets T be str.

A getter keeps the String field, because its HasField bound is also used by the WithProvider adapter, which expects the field type itself. Applying AsRef<str> there broke chain_deeply_nested with a Value == str mismatch.

Every conversion and field read the macros emit is now a fully qualified trait call — ::core::convert::AsRef::as_ref, ::core::convert::AsMut::as_mut, ::core::clone::Clone::clone, ::core::option::Option::as_ref/as_mut/as_deref_mut, ::cgp::macro_prelude::OptionAsRef::option_as_ref, and ::cgp::macro_prelude::HasField::get_field — and the bounds name ::core::convert::AsRef and ::core::convert::AsMut, so a local trait of the same name cannot capture them. A probe crate that defines its own HasField and AsRef traits compiles, which it did not before.

Three tests cover #[cgp_impl] with a &str and an Option<&str> implicit, and run the provider against a String, a &str, and a Cow<str> field. cgp-no-std-tests uses both implicit forms and still builds for x86_64-unknown-none.

A `#[cgp_fn]` or `#[cgp_impl]` with an `#[implicit] name: &str` argument
required a `String` field, so it failed in a crate without an allocator with
"cannot find type `String`". The argument now requires
`Value: AsRef<str> + 'static` and reads the field with `.as_ref()`, so a
`String`, a `Cow<str>`, or a `Box<str>` field works and none needs an
allocator.

An `Option<&str>` argument required an `Option<String>` field for the same
reason. It now requires `Value: OptionAsRef<str>`, a new helper trait in
`cgp-field` whose blanket impl covers any `Option<U>` with `U: AsRef<T>`.

A getter keeps the `String` field, because its `HasField` bound is also used by
the `WithProvider` adapter, which expects the field type itself.

Every conversion and field read the macros emit is now a fully qualified trait
call, and the bounds name `::core::convert::AsRef` and `::core::convert::AsMut`,
so a local trait of the same name cannot capture them.
@soareschen
soareschen force-pushed the docs/no-std-implicits branch from d827774 to 45059ed Compare November 7, 2026 22:50
@soareschen soareschen changed the title Build the library for a target without std Borrow a &str implicit argument without alloc Nov 7, 2026
@soareschen
soareschen marked this pull request as ready for review November 7, 2026 22:51
@soareschen
soareschen merged commit 60c725f into main Nov 7, 2026
3 checks passed
@soareschen
soareschen deleted the docs/no-std-implicits branch November 7, 2026 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant