Use this issue to propose an RFC topic and get early alignment.
If accepted, we’ll typically ask for a PR adding an RFC document under docs/RFCs/ based on the RFC template.
RFCs are user-facing only (language features, documentation, CLI/tooling, runtime surface area).
If your proposal is about Rust internals/compiler architecture, please open a bug/chore/feature issue instead.
Area
- Incan Language (syntax/semantics)
- Runtime / Core crates (stdlib/core/derive)
- Documentation
Summary
RFC 099 proposes generic trait-targeted methods: methods declared inside the owning type body may carry method-level type parameters, target a trait instantiation with for Trait[...], and add where constraints that define a checked family of trait adoptions rather than one concrete adoption at a time. The motivating case is numeric and storage-carrier dispatch for APIs such as std.io.BytesIO.write(...), while keeping the authoring model class-body and Python-shaped rather than Rust-shaped impl Trait for Type blocks.
Motivation
RFC 009 made exact-width numeric types first-class, and RFC 056 made binary numeric I/O trait-backed rather than a matrix of width-specific method names. RFC 091 adds constrained integer newtype storage carriers, which makes representation-oriented work want to delegate through a storage carrier without pretending the domain newtype is its carrier type. The missing language surface is a way for an owning class to define one generic method family that satisfies a generic trait target under explicit constraints.
Proposal sketch
Allow class-body methods to put method generics, the trait target, and where constraints together in the method generic header:
class BytesIO:
def write[T with FixedWidthNumeric for BinaryWrite[T]](
mut self,
value: T,
endian: Endian,
) -> Result[None, IoError]:
...
Storage-backed newtypes can delegate through an explicit storage projection without implicit conversion:
type Month = newtype int[ge=1, le=12, storage=u8]
class BytesIO:
def write[
T with StorageBackedInteger
for BinaryWrite[T]
where T.Storage with FixedWidthInteger
where BytesIO with BinaryWrite[T.Storage]
](
mut self,
value: T,
endian: Endian,
) -> Result[None, IoError]:
storage: T.Storage = value.to_storage()
return self.write(storage, endian)
The method lives on the owning class. extends remains class inheritance, and source does not gain Rust-style impl Trait for Type syntax.
Draft RFC file: workspaces/docs-site/docs/RFCs/099_generic_trait_targeted_methods.md.
Alternatives considered
Use external Rust-shaped impl Trait for Type blocks. That maps cleanly to Rust but violates the Incan direction from RFC 043, where users adopt capabilities with with and write behavior in type bodies.
Use external extend Type with Trait blocks. That is more Incan-looking but overloads extend/extends, which should stay class inheritance and behavior reuse terminology.
Repeat concrete adoptions for every numeric width. That avoids new syntax but recreates boilerplate and leaves storage-backed newtypes without a principled representation-delegation path.
Let storage-backed newtypes behave as their storage carrier. That is unsafe for the RFC 091 model: storage is representation metadata, not the source-level type.
Add general method overloading. That is broader than needed; the requested feature is checked trait conformance over a generic family, not runtime-style overload selection by shape.
Impact / compatibility
This is additive. Existing methods and trait adoptions continue to work. The new syntax increases method-header expressiveness and requires overlap diagnostics so it does not accidentally add specialization. int remains the RFC 009 alias for i64, and storage-backed newtypes remain nominal domain types rather than subtypes or implicit conversions to their storage carriers.
Implementation notes (optional)
Likely layers: parser/AST for for TraitExpression and where inside method generic headers, typechecker/symbol resolution for adoption-family metadata and overlap rejection, associated type projection support from RFC 098 for T.Storage, stdlib numeric-family traits, formatter support for multiline headers, LSP diagnostics/hover/completion, and Rust backend emission that can realize the checked adoption family without exposing Rust impl syntax in source.
Checklist
Use this issue to propose an RFC topic and get early alignment.
If accepted, we’ll typically ask for a PR adding an RFC document under
docs/RFCs/based on the RFC template.RFCs are user-facing only (language features, documentation, CLI/tooling, runtime surface area).
If your proposal is about Rust internals/compiler architecture, please open a bug/chore/feature issue instead.
Area
Summary
RFC 099 proposes generic trait-targeted methods: methods declared inside the owning type body may carry method-level type parameters, target a trait instantiation with
for Trait[...], and addwhereconstraints that define a checked family of trait adoptions rather than one concrete adoption at a time. The motivating case is numeric and storage-carrier dispatch for APIs such asstd.io.BytesIO.write(...), while keeping the authoring model class-body and Python-shaped rather than Rust-shapedimpl Trait for Typeblocks.Motivation
RFC 009 made exact-width numeric types first-class, and RFC 056 made binary numeric I/O trait-backed rather than a matrix of width-specific method names. RFC 091 adds constrained integer newtype storage carriers, which makes representation-oriented work want to delegate through a storage carrier without pretending the domain newtype is its carrier type. The missing language surface is a way for an owning class to define one generic method family that satisfies a generic trait target under explicit constraints.
Proposal sketch
Allow class-body methods to put method generics, the trait target, and
whereconstraints together in the method generic header:Storage-backed newtypes can delegate through an explicit storage projection without implicit conversion:
The method lives on the owning class.
extendsremains class inheritance, and source does not gain Rust-styleimpl Trait for Typesyntax.Draft RFC file:
workspaces/docs-site/docs/RFCs/099_generic_trait_targeted_methods.md.Alternatives considered
Use external Rust-shaped
impl Trait for Typeblocks. That maps cleanly to Rust but violates the Incan direction from RFC 043, where users adopt capabilities withwithand write behavior in type bodies.Use external
extend Type with Traitblocks. That is more Incan-looking but overloadsextend/extends, which should stay class inheritance and behavior reuse terminology.Repeat concrete adoptions for every numeric width. That avoids new syntax but recreates boilerplate and leaves storage-backed newtypes without a principled representation-delegation path.
Let storage-backed newtypes behave as their storage carrier. That is unsafe for the RFC 091 model: storage is representation metadata, not the source-level type.
Add general method overloading. That is broader than needed; the requested feature is checked trait conformance over a generic family, not runtime-style overload selection by shape.
Impact / compatibility
This is additive. Existing methods and trait adoptions continue to work. The new syntax increases method-header expressiveness and requires overlap diagnostics so it does not accidentally add specialization.
intremains the RFC 009 alias fori64, and storage-backed newtypes remain nominal domain types rather than subtypes or implicit conversions to their storage carriers.Implementation notes (optional)
Likely layers: parser/AST for
for TraitExpressionandwhereinside method generic headers, typechecker/symbol resolution for adoption-family metadata and overlap rejection, associated type projection support from RFC 098 forT.Storage, stdlib numeric-family traits, formatter support for multiline headers, LSP diagnostics/hover/completion, and Rust backend emission that can realize the checked adoption family without exposing Rustimplsyntax in source.Checklist