Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ comparison would have to be settled, so its two facts are carried by values
instead: `LimitWitness` is what schema validation selected, and
`PositiveLimitWitness` is that selection proven to admit an item. A family says
which ladder its magnitude travels by declaring `EvidenceSelectedLimit`, and
that declaration is the mint's bound — a family that never made it has no road
to a runtime capacity at all. Several families in the machine said
that declaration bounds the base witness type itself and every road consuming
it — a family that never made it cannot name a runtime witness or pass one to a
runtime-capacity road. Several families in the machine said
"evidence-selected" in a doc comment beside their declaration and said it nowhere
a road could read; that sentence is now a fact the compiler carries.

Expand Down
43 changes: 41 additions & 2 deletions src/02_identity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,32 @@ trips `non_snake_case`, which the lint wall denies — no attribute suppresses
anything, and two stamps naming one module in one file collide as a duplicate
definition.

The caller-coordinate re-export is the guard's canonical exported spelling.
The caller's visibility appears there exactly once. The front grammar also
transports the same reach one module into the private generated child: private
and `self` become `super`, `super` gains one `super` segment, and absolute paths
and `pub` keep their coordinate-independent meaning. The type and both methods
carry that transported reach. Code already inside the authorized scope may name
the generated child path, but no generated item is broad enough for a wider
same-coordinate re-export, type alias, or public signature.

The admitted direct-token population is Rust's private and public forms,
`pub(self)`, `pub(super)`, `pub(crate)`, the equivalent `pub(in self)`,
`pub(in super)`, and `pub(in crate)` forms, relative `super` chains, absolute
`crate` paths, and an outer macro's coordinate-invariant `$crate` path. A whole
visibility forwarded as a captured `$vis:vis` is opaque: the stamp refuses it
instead of treating an unknown reach as crate-wide.

Visibility selection does not duplicate the guard. One transcriber owns the
type, private seat, and both methods; the front arms choose only the transported
internal reach and the caller-coordinate re-export.
The `@transcribe` arm follows the root register stamp's internal-arm precedent:
Rust exports the arm, so a direct invocation is hand-authored authority over a
new guard's two visibilities and is outside the front grammar's transport claim.
It still cannot change an existing guard because the module or item name
collides, and it cannot add a constructor or accessor because the shared body
still contains the same private field and complete method set.

The machine's production scope guards are stamped. Nine of them were tuple
structs whose position field was `pub`, which is both a public constructor and a
public accessor — so the road out the stamp refuses to emit was standing open
Expand All @@ -121,8 +147,9 @@ containing dozens of other types*, and it is not answerable without being a
compiler.

Seating the guard in its own module answers it structurally. The set of roads is
the expansion, and nothing else is inside the wall — so `stamped-guards-seal-
their-position` is deleted rather than repaired, and the claim it used to make
the expansion, and nothing else is inside the wall — so
`stamped-guards-seal-their-position` is deleted rather than repaired, and the
claim it used to make
is `E0616`, `E0423` and `E0603` on the two laundering fixtures. That is the
drain running downward: a type that makes the wrong move unrepresentable retires
the law that asserted the move was wrong, and the law goes.
Expand Down Expand Up @@ -167,6 +194,18 @@ obligations:
challenge_kind: compile-law
green: laws.rs identity::a_stamped_scope_guard_matches_its_hand_written_twin
red: testpak/tests/compile-fail/cross-scope-comparison-on-a-stamped-guard.rs
- id: identity.scope-guard-visibility-is-caller-relative
challenge_kind: compile-refusal
green: testpak/tests/scope_guard_visibility.rs
red: testpak/tests/compile-fail/a-scope-guard-reexport-cannot-widen-reach.rs
- id: identity.scope-guard-alias-cannot-widen
challenge_kind: compile-refusal
green: testpak/tests/scope_guard_alias_visibility.rs
red: testpak/tests/compile-fail/a-scope-guard-alias-cannot-widen-reach.rs
- id: identity.scope-guard-signature-cannot-widen
challenge_kind: compile-refusal
green: testpak/tests/scope_guard_signature_visibility.rs
red: testpak/tests/compile-fail/a-scope-guard-signature-cannot-widen-reach.rs
- id: identity.admission-joins-creation-to-class
challenge_kind: compile-refusal
green: laws.rs identity::admission_joins_creation_to_class
Expand Down
193 changes: 181 additions & 12 deletions src/02_identity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,23 @@ pub use types::{
/// that glob unused, which is a denied warning at the call site rather than
/// anything silent.
///
/// Both operations carry the caller's own `$vis`, so the road in and the
/// comparison are reachable exactly as far as the role they serve and never one
/// step further; the re-export carries it too, and it is the single gate on the
/// type. `$vis` must reach at least the invoking module: a guard stamped with no
/// visibility at all would be sealed inside a module nothing can name, so the
/// proof surface's demonstration guard is stamped `pub(crate)`, which is the
/// reach a bare private guard had before the seat moved.
/// The caller's visibility is emitted once on the canonical re-export, at the
/// coordinate where the caller wrote it. The front grammar separately moves
/// that reach one level into the generated child: private and `self` become
/// `super`, `super` gains one `super` segment, and absolute paths and `pub`
/// remain absolute. The type and both methods carry that transported reach.
/// Therefore a generated path can be named only from a scope already allowed
/// by the caller; a same-coordinate re-export, alias, or signature cannot
/// publish the guard farther. The child module itself stays private, so the
/// caller-coordinate re-export remains the canonical exported spelling.
///
/// Direct source tokens cover Rust's private, `pub`, shorthand, relative
/// `pub(in super::...)`, and absolute `pub(in ...)` families. An absolute path
/// produced with an outer macro's `$crate` is preserved unchanged. A whole
/// visibility first captured as `$vis:vis` by another macro is opaque to
/// `macro_rules!`, so this stamp refuses it instead of guessing a reach; the
/// wrapper must author the literal front syntax or explicitly own an internal
/// transcriber call.
///
/// # Where the stamp lives
///
Expand All @@ -113,6 +123,31 @@ pub use types::{
/// about macro namespacing and is not a root admission of a semantic noun — the
/// stamp declares no type of its own and owns no meaning.
///
/// The `@transcribe` rule is the stamp's shared implementation arm, following
/// the root `closed_register!` precedent; it is not the public front grammar.
/// Because `macro_rules!` exports all arms together, Rust does not make that
/// spelling private. A direct caller is hand-authoring both visibilities and
/// therefore owns their relationship; the front grammar's exact-transport
/// guarantee does not apply. The transcriber still owns one body with a private
/// tuple field and exactly two methods, and a direct call cannot alter an
/// existing guard because its generated module or item name collides. Rust also
/// refuses a requested re-export that exceeds the hand-authored internal item.
///
/// A direct arm call that asks the re-export to exceed the internal reach is
/// refused by rustc:
///
/// ```compile_fail
/// # #[derive(Debug, Clone, PartialEq, Eq, Hash)]
/// # pub struct DemoScopeId;
/// threadpak::scope_guard_version! {
/// @transcribe
/// [pub(crate)]
/// [pub]
/// /// No public re-export can widen this crate-confined item.
/// struct TooWideVersion over DemoScopeId, seated in mod too_wide_version;
/// }
/// ```
///
/// # The invocation
///
/// ```
Expand All @@ -133,14 +168,140 @@ pub use types::{
macro_rules! scope_guard_version {
(
$(#[$note:meta])*
$vis:vis struct $name:ident over $scope:ty, seated in mod $home:ident;
pub struct $name:ident over $scope:ty, seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub]
[pub]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
$(#[$note:meta])*
pub(crate) struct $name:ident over $scope:ty, seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub(crate)]
[pub(crate)]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
$(#[$note:meta])*
pub(self) struct $name:ident over $scope:ty, seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub(super)]
[pub(self)]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
$(#[$note:meta])*
pub(super) struct $name:ident over $scope:ty, seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub(in super::super)]
[pub(super)]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
$(#[$note:meta])*
pub(in self $(:: $relative:ident)*) struct $name:ident over $scope:ty,
seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub(in super $(:: $relative)*)]
[pub(in self $(:: $relative)*)]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
$(#[$note:meta])*
pub(in super $(:: $relative:ident)*) struct $name:ident over $scope:ty,
seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub(in super::super $(:: $relative)*)]
[pub(in super $(:: $relative)*)]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
$(#[$note:meta])*
pub(in crate $(:: $absolute:ident)*) struct $name:ident over $scope:ty,
seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub(in crate $(:: $absolute)*)]
[pub(in crate $(:: $absolute)*)]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
$(#[$note:meta])*
pub(in $absolute:path) struct $name:ident over $scope:ty,
seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub(in $absolute)]
[pub(in $absolute)]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
$(#[$note:meta])*
struct $name:ident over $scope:ty, seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@capture_private
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
@capture_private
$(#[$note:meta])*
$caller_vis:vis struct $name:ident over $scope:ty, seated in mod $home:ident;
) => {
$crate::scope_guard_version! {
@transcribe
[pub(super)]
[$caller_vis]
$(#[$note])*
struct $name over $scope, seated in mod $home;
}
};
(
@transcribe
[$internal_vis:vis]
[$caller_vis:vis]
$(#[$note:meta])*
struct $name:ident over $scope:ty, seated in mod $home:ident;
) => {
mod $home {
use super::*;

$(#[$note])*
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
$vis struct $name($crate::identity::AuthorityPosition<$scope>);
$internal_vis struct $name($crate::identity::AuthorityPosition<$scope>);

impl $name {
/// The one road in: read one position under this role.
Expand All @@ -151,7 +312,7 @@ macro_rules! scope_guard_version {
/// that could leave this role could be re-entered under another
/// one, and the role would have stopped being a wall.
#[must_use]
$vis fn positioned(
$internal_vis fn positioned(
position: $crate::identity::AuthorityPosition<$scope>,
) -> Self {
Self(position)
Expand All @@ -165,7 +326,7 @@ macro_rules! scope_guard_version {
///
/// Returns the `OrderComparison` family body when the two
/// positions do not share one scope.
$vis fn try_cmp_same_scope(
$internal_vis fn try_cmp_same_scope(
&self,
other: &Self,
) -> ::core::result::Result<
Expand All @@ -177,6 +338,14 @@ macro_rules! scope_guard_version {
}
}

$vis use $home::$name;
$caller_vis use $home::$name;
};
(
$(#[$note:meta])*
$opaque_visibility:vis struct $name:ident over $scope:ty, seated in mod $home:ident;
) => {
compile_error!(
"scope_guard_version! requires visibility tokens at its public front door; an opaque forwarded `vis` fragment cannot be transported one module deeper"
);
};
}
11 changes: 6 additions & 5 deletions src/13_declaration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ These collections are bounded by a DECLARED finite issue bound, not roster
cardinality — several issues of one kind are lawful at once — so their
magnitudes are selected by the owner's evidence rather than written in the
source. Those three families say so at the type level by declaring
`EvidenceSelectedLimit`, which is the bound on `PositiveLimitWitness`'s mint: the
sentence that used to sit in a doc comment beside each of them is now a fact a
road can read, and a family that never made the declaration has no road to a
runtime capacity. The projection-contract family alone is derivable (5 member
kinds + 5 unstatable claims = 10) and carries the compile-time cap instead.
`EvidenceSelectedLimit`, which bounds the base `LimitWitness` type and every
road consuming it: the sentence that used to sit in a doc comment beside each
of them is now a fact a road can read, and a family that never made the
declaration has no road to a runtime capacity. The projection-contract family
alone is derivable (5 member kinds + 5 unstatable claims = 10) and carries the
compile-time cap instead.

All four bodies carry the one coupled seat — band 00's `AdmittedPrefix`, holding
the issues and the coverage claim the same construction amounts to, read back
Expand Down
4 changes: 2 additions & 2 deletions src/15_execution/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,8 +705,8 @@ pub enum EffectBatchCompositionIssue {
},
}

/// Limit family for composition issues. Its magnitude is selected by the
/// owner's evidence rather than declared here — see
/// Limit family for `EffectBatch` composition issues. Its magnitude is
/// selected by the owner's evidence rather than declared here — see
/// [`crate::types::EvidenceSelectedLimit`].
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EffectBatchIssueLimit;
Expand Down
Loading
Loading