pub struct State<'a, 'b> {Show 18 fields
pub root_mod: &'a mut Mod,
pub mod_cursor: Vec<Ident>,
pub cur_trait: Option<Ident>,
pub cur_helper_mod: Option<Ident>,
pub is_helper: bool,
pub bound_vars: &'a mut VecDeque<BoundedTyvar<'b>>,
pub var_offset: usize,
pub origin: Vec<ImportExport<'b>>,
pub cur_needs_vars: Option<&'a mut BTreeSet<u32>>,
pub vars_needs_vars: &'a mut VecDeque<BTreeSet<u32>>,
pub import_param_var: Option<Ident>,
pub self_param_var: Option<TokenStream>,
pub positivity_param: Option<TokenStream>,
pub is_impl: bool,
pub root_component_name: Option<(TokenStream, &'a str)>,
pub is_guest: bool,
pub is_wasmtime_guest: bool,
pub colliding_import_names: HashSet<String>,
}Expand description
A whole grab-bag of useful state to have while emitting Rust
Fields§
§root_mod: &'a mut ModA pointer to a Mod that everything we emit will end up in
mod_cursor: Vec<Ident>A cursor to the current submodule (under State::root_mod),
where decls that we are looking at right now should end up
cur_trait: Option<Ident>If we are currently processing decls that should end up inside a trait (representing an instance or a resource), this names the trait where they should end up.
cur_helper_mod: Option<Ident>We use a “helper module” for auxiliary definitions: for
example, an instance represented by InstanceTrait would end
up with nominal definitions for its nontrivial types in
instance_trait::Type. This keeps track of the name of that
module, if it presently exists.
is_helper: boolWhether the trait/type definition that we are currently emitting is in the helper module or the main module corresponding directly to the wit package. This is important to get references to other types correct.
bound_vars: &'a mut VecDeque<BoundedTyvar<'b>>All the bound variables in the component type that we are currently processing
var_offset: usizeAn offset into bound_vars from which any variable indices we see in the source component type will be resolved; used to deal with the fact that when we recurse down into a type in the Eq bound of a type variable, its variables are offset from ours (since we use de Bruijn indices).
origin: Vec<ImportExport<'b>>A path through instance import/export names from the root
component type to the type we are currently processing. This
is used with crate::etypes::TyvarOrigin to decide whether
a type variable we encounter is “locally defined”, i.e. should
have a type definition emitted for it in this module.
cur_needs_vars: Option<&'a mut BTreeSet<u32>>A set of type variables that we encountered while emitting the type bound for a type variable.
vars_needs_vars: &'a mut VecDeque<BTreeSet<u32>>A map from type variables to the type variables used in their bounds, used to ensure that we are parametrized over the things we need to be
import_param_var: Option<Ident>The Rust type parameter used to represent the type that implements the imports of a component
self_param_var: Option<TokenStream>The Rust type parameter used to represent the current Rust
state type. In particular, this should let one find a Self
which Rust understands to be an impl of the instance trait
that s.origin refers to.
§Note [Origin paths and self parameters in impl codegen for higher-order components]
When extending impl (host.rs/guest.rs, as opposed to
rtypes.rs) codegen to higher-order components, it’s not
entirely clear whether we should have this/the origin path
always refer to the true root component, or just to the
nearest component in which we are currently working. At first
glance, updating the origin path at all during impl codegen
seems like a bad idea, since the impl should be instantiating
the Rust tyvars and can’t generate new ones for
non-locally-defined types the way that rtypes codegen
can. However, it may be the case that referring to a tyvar
that does not follow our local definedness rules at the
granularity of components will be impossible due to the
outer_boundary rules! If this does turn out to be the case,
then updating origin on every instance the way that rtypes
does will still be a bad idea, but we might want to consider
updating it once per /component/.
Whether or not origin gets updated, the trait bounds in
self_param_var need to match this. Currently, code in
host.rs/guest.rs does not update origin, but does update
self_param_var, which will need to be fixed when extending
higher-order component bindings generation to impls.
positivity_param: Option<TokenStream>The Rust type parameter used to represent the type that provides the positivity of the (eventual use of the) current component
is_impl: boolWhether we are emitting an implementation of the component interfaces, or just the types of the interface
root_component_name: Option<(TokenStream, &'a str)>A namespace path and a name representing the Rust trait generated for the root component that we started codegen from
is_guest: boolWhether we are generating code for the Hyperlight host or the Hyperlight guest
is_wasmtime_guest: boolA temporary hack to enable some special cases used by the wasmtime guest emit. When that is refactored to use the host guest emit, this can go away.
colliding_import_names: HashSet<String>Set of interface names that collide across different packages (e.g. “types” appears in both wasi:filesystem/types and wasi:http/types). When a name is in this set, the parent namespace is prepended to disambiguate the trait member name.
Implementations§
Source§impl<'a, 'b> State<'a, 'b>
impl<'a, 'b> State<'a, 'b>
pub fn new( root_mod: &'a mut Mod, bound_vars: &'a mut VecDeque<BoundedTyvar<'b>>, vars_needs_vars: &'a mut VecDeque<BTreeSet<u32>>, is_guest: bool, is_wasmtime_guest: bool, ) -> Self
pub fn clone<'c>(&'c mut self) -> State<'c, 'b>
Sourcepub fn cur_mod<'c>(&'c mut self) -> &'c mut Mod
pub fn cur_mod<'c>(&'c mut self) -> &'c mut Mod
Obtain a reference to the Mod that we are currently
generating code in, creating it if necessary
Sourcepub fn cur_mod_immut<'c>(&'c self) -> &'c Mod
pub fn cur_mod_immut<'c>(&'c self) -> &'c Mod
Obtain an immutable reference to the Mod that we are
currently generating code in.
Precondition: the module must already exist
Sourcepub fn with_cursor<'c>(&'c mut self, cursor: Vec<Ident>) -> State<'c, 'b>
pub fn with_cursor<'c>(&'c mut self, cursor: Vec<Ident>) -> State<'c, 'b>
Copy the state, changing its module cursor to emit code into a different module
Sourcepub fn with_needs_vars<'c>(
&'c mut self,
needs_vars: &'c mut BTreeSet<u32>,
) -> State<'c, 'b>
pub fn with_needs_vars<'c>( &'c mut self, needs_vars: &'c mut BTreeSet<u32>, ) -> State<'c, 'b>
Copy the state, replacing its State::cur_needs_vars reference,
allowing a caller to capture the vars referenced by any emit
run with the resultant state
Sourcepub fn for_var_effects_only<F: for<'c> FnOnce(&mut State<'c, 'b>)>(
&mut self,
f: F,
)
pub fn for_var_effects_only<F: for<'c> FnOnce(&mut State<'c, 'b>)>( &mut self, f: F, )
Copy the state, replacing its State::root_mod reference,
allowing a caller to capture only the effects on
State::cur_needs_vars/State::vars_needs_vars of an
emit run with the resultant state
Sourcepub fn need_noff_var(&mut self, n: u32)
pub fn need_noff_var(&mut self, n: u32)
Record that an emit sequence needed a var, given an absolute
index for the var (i.e. ignoring State::var_offset)
Sourcepub fn record_needs_vars(&mut self, n: u32)
pub fn record_needs_vars(&mut self, n: u32)
Use the State::cur_needs_vars map to populate
State::vars_needs_vars for a var that we presumably just
finished emitting a bound for
Sourcepub fn get_noff_var_refs(&mut self, n: u32) -> BTreeSet<u32>
pub fn get_noff_var_refs(&mut self, n: u32) -> BTreeSet<u32>
Get a list of all the variables needed by a var, given its absolute
index (i.e. ignoring State::var_offset)
Sourcepub fn noff_var_id(&self, n: u32) -> Ident
pub fn noff_var_id(&self, n: u32) -> Ident
Find the exported name which gave rise to a component type
variable, given its absolute index (i.e. ignoring
State::var_offset)
Sourcepub fn helper<'c>(&'c mut self) -> State<'c, 'b>
pub fn helper<'c>(&'c mut self) -> State<'c, 'b>
Copy the state, changing it to emit into the helper module of the current trait
Sourcepub fn root_path(&self) -> TokenStream
pub fn root_path(&self) -> TokenStream
Construct a namespace token stream that can be emitted in the current module to refer to a name in the root module
Sourcepub fn helper_path(&self) -> TokenStream
pub fn helper_path(&self) -> TokenStream
Construct a namespace token stream that can be emitted in the current module to refer to a name in the helper module
Sourcepub fn cur_trait_path(&self) -> TokenStream
pub fn cur_trait_path(&self) -> TokenStream
Emit a namespace token stream that can be emitted in the root module to refer to the current trait
Sourcepub fn add_helper_supertrait(&mut self, r: Ident)
pub fn add_helper_supertrait(&mut self, r: Ident)
Add a supertrait constraint referring to a trait in the helper module; primarily used to add a constraint for the trait representing a resource type.
Sourcepub fn cur_trait<'c>(&'c mut self) -> &'c mut Trait
pub fn cur_trait<'c>(&'c mut self) -> &'c mut Trait
Obtain a reference to the Trait that we are currently
generating code in, creating it if necessary.
Precondition: we are currently generating code in a trait
(i.e. State::cur_trait is not None)
Sourcepub fn cur_trait_immut<'c>(&'c self) -> &'c Trait
pub fn cur_trait_immut<'c>(&'c self) -> &'c Trait
Obtain an immutable reference to the Trait that we are
currently generating code in.
Precondition: we are currently generating code in a trait
(i.e. State::cur_trait is not None), and that trait has
already been created
Sourcepub fn trait<'c>(
&'c mut self,
namespace: &'c [Ident],
name: Ident,
) -> &'c mut Trait
pub fn trait<'c>( &'c mut self, namespace: &'c [Ident], name: Ident, ) -> &'c mut Trait
Obtain a reference to the trait at the given module path and name from the root module, creating it and any named modules if necessary
Sourcepub fn push_origin<'c>(
&'c mut self,
origin_was_export: bool,
name: &'b str,
) -> State<'c, 'b>
pub fn push_origin<'c>( &'c mut self, origin_was_export: bool, name: &'b str, ) -> State<'c, 'b>
Add an import/export to State::origin, reflecting that we are now
looking at code underneath it
origin_was_export does not keep track of whether the item
overall was imported or exported from the root component
(taking into account positivity); it just checks if this
particular extern_decl was imported or exported from its
parent instance (and so e.g. an export of an instance that is
imported by the root component has origin_was_export). Any
decisions that depend on positivity from the root component
should be made part of the
[hyperlight_common::component::Positivity] trait, which
correctly handles the fact that the same interface trait may
be used in both positive and negative positions.
Sourcepub fn is_var_defn(&self, t: &Defined<'b>) -> Option<(u32, TypeBound<'b>)>
pub fn is_var_defn(&self, t: &Defined<'b>) -> Option<(u32, TypeBound<'b>)>
Find out if a Defined type is actually a reference to a
locally defined type variable, returning its index and bound
if it is
Sourcepub fn is_noff_var_local<'c>(
&'c self,
n: u32,
) -> Option<(Vec<ImportExport<'c>>, TypeBound<'a>)>
pub fn is_noff_var_local<'c>( &'c self, n: u32, ) -> Option<(Vec<ImportExport<'c>>, TypeBound<'a>)>
Find out if a variable is locally-defined given its absolute index, returning its origin and bound if it is
Sourcepub fn resolve_trait_immut(&self, absolute: bool, path: &[Ident]) -> &Trait
pub fn resolve_trait_immut(&self, absolute: bool, path: &[Ident]) -> &Trait
Obtain an immutable reference to the trait at the specified
namespace path, either from the root module (if absolute)
is true, or from the current module
Precondition: all named traits/modules must exist
Sourcepub fn adjust_vars(&mut self, n: u32)
pub fn adjust_vars(&mut self, n: u32)
Shift all of the type variable indices over, because we have gone under some binders. Used when we switch from looking at a component’s import types (where type idxs are de Bruijn into the component’s uvar list) to a component’s export types (where type idx are de Bruijn first into the evar list and then the uvar list, as we go under the existential binders).
Sourcepub fn resolve_bound_var(&self, n: u32) -> ResolvedBoundVar<'b>
pub fn resolve_bound_var(&self, n: u32) -> ResolvedBoundVar<'b>
Resolve a type variable as far as possible: either this ends up with a definition, in which case, let’s get that, or it ends up with a resource type, in which case we return the resource index
Distinct from [Ctx::resolve_tv], which is mostly concerned
with free variables, because this is concerned entirely with
bound variables.
Sourcepub fn resource_trait_path(&self, r: Ident) -> Vec<Ident>
pub fn resource_trait_path(&self, r: Ident) -> Vec<Ident>
Construct a namespace path referring to the resource trait for a resource with the given name
Trait Implementations§
Auto Trait Implementations§
impl<'a, 'b> !Send for State<'a, 'b>
impl<'a, 'b> !Sync for State<'a, 'b>
impl<'a, 'b> !UnwindSafe for State<'a, 'b>
impl<'a, 'b> Freeze for State<'a, 'b>
impl<'a, 'b> RefUnwindSafe for State<'a, 'b>
impl<'a, 'b> Unpin for State<'a, 'b>
impl<'a, 'b> UnsafeUnpin for State<'a, 'b>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more