Struct naga::front::wgsl::lower::ExpressionContext

source ·
pub struct ExpressionContext<'source, 'temp, 'out> {
    ast_expressions: &'temp Arena<Expression<'source>>,
    types: &'temp Arena<Type<'source>>,
    globals: &'temp mut FastHashMap<&'source str, LoweredGlobalDecl>,
    module: &'out mut Module,
    const_typifier: &'temp mut Typifier,
    global_expression_kind_tracker: &'temp mut ExpressionKindTracker,
    expr_type: ExpressionContextType<'temp, 'out>,
}
Expand description

State for lowering an ast::Expression to Naga IR.

ExpressionContexts come in two kinds, distinguished by the value of the expr_type field:

ExpressionContexts are constructed in restricted ways:

Not to be confused with wgsl::parse::ExpressionContext, which is for parsing the ast::Expression in the first place.

Fields§

§ast_expressions: &'temp Arena<Expression<'source>>§types: &'temp Arena<Type<'source>>§globals: &'temp mut FastHashMap<&'source str, LoweredGlobalDecl>

The map from the names of module-scope declarations to the Naga IR Handles we have built for them, owned by Lowerer::lower.

§module: &'out mut Module

The IR Module we’re constructing.

§const_typifier: &'temp mut Typifier

Type judgments for module::global_expressions.

§global_expression_kind_tracker: &'temp mut ExpressionKindTracker§expr_type: ExpressionContextType<'temp, 'out>

Whether we are lowering a constant expression or a general runtime expression, and the data needed in each case.

Implementations§

source§

impl<'source> ExpressionContext<'source, '_, '_>

source

pub fn try_automatic_conversions( &mut self, expr: Handle<Expression>, goal_ty: &TypeResolution, goal_span: Span, ) -> Result<Handle<Expression>, Error<'source>>

Try to use WGSL’s automatic conversions to convert expr to goal_ty.

If no conversions are necessary, return expr unchanged.

If automatic conversions cannot convert expr to goal_ty, return an AutoConversion error.

Although the Load Rule is one of the automatic conversions, this function assumes it has already been applied if appropriate, as indicated by the fact that the Rust type of expr is not Typed<_>.

source

pub fn try_automatic_conversion_for_leaf_scalar( &mut self, expr: Handle<Expression>, goal_scalar: Scalar, goal_span: Span, ) -> Result<Handle<Expression>, Error<'source>>

Try to convert expr’s leaf scalar to goal using automatic conversions.

If no conversions are necessary, return expr unchanged.

If automatic conversions cannot convert expr to goal_scalar, return an AutoConversionLeafScalar error.

Although the Load Rule is one of the automatic conversions, this function assumes it has already been applied if appropriate, as indicated by the fact that the Rust type of expr is not Typed<_>.

source

fn convert_leaf_scalar( &mut self, expr: Handle<Expression>, expr_span: Span, goal_scalar: Scalar, ) -> Result<Handle<Expression>, Error<'source>>

source

pub fn try_automatic_conversions_slice( &mut self, exprs: &mut [Handle<Expression>], goal_ty: &TypeResolution, goal_span: Span, ) -> Result<(), Error<'source>>

Try to convert exprs to goal_ty using WGSL’s automatic conversions.

source

pub fn try_automatic_conversions_for_vector( &mut self, exprs: &mut [Handle<Expression>], goal_scalar: Scalar, goal_span: Span, ) -> Result<(), Error<'source>>

Apply WGSL’s automatic conversions to a vector constructor’s arguments.

When calling a vector constructor like vec3<f32>(...), the parameters can be a mix of scalars and vectors, with the latter being spread out to contribute each of their components as a component of the new value. When the element type is explicit, as with <f32> in the example above, WGSL’s automatic conversions should convert abstract scalar and vector parameters to the constructor’s required scalar type.

source

pub fn convert_to_leaf_scalar( &mut self, expr: &mut Handle<Expression>, goal: Scalar, ) -> Result<(), Error<'source>>

Convert expr to the leaf scalar type scalar.

source

pub fn convert_slice_to_common_leaf_scalar( &mut self, exprs: &mut [Handle<Expression>], goal: Scalar, ) -> Result<(), Error<'source>>

Convert all expressions in exprs to a common scalar type.

Note that the caller is responsible for making sure these conversions are actually justified. This function simply generates As expressions, regardless of whether they are permitted WGSL automatic conversions. Callers intending to implement automatic conversions need to determine for themselves whether the casts we we generate are justified, perhaps by calling TypeInner::automatically_converts_to or Scalar::automatic_conversion_combine.

source

pub fn concretize( &mut self, expr: Handle<Expression>, ) -> Result<Handle<Expression>, Error<'source>>

Return an expression for the concretized value of expr.

If expr is already concrete, return it unchanged.

source

pub fn automatic_conversion_consensus<'handle, I>( &self, components: I, ) -> Result<Scalar, usize>
where I: IntoIterator<Item = &'handle Handle<Expression>>, I::IntoIter: Clone,

Find the consensus scalar of components under WGSL’s automatic conversions.

If components can all be converted to any common scalar via WGSL’s automatic conversions, return the best such scalar.

The components slice must not be empty. All elements’ types must have been resolved.

If components are definitely not acceptable as arguments to such constructors, return Err(i), where i is the index in components of some problematic argument.

This function doesn’t fully type-check the arguments - it only considers their leaf scalar types. This means it may return Ok even when the Naga validator will reject the resulting construction expression later.

source§

impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out>

source

fn as_const(&mut self) -> ExpressionContext<'source, '_, '_>

source

fn as_global(&mut self) -> GlobalContext<'source, '_, '_>

source

fn as_const_evaluator(&mut self) -> ConstantEvaluator<'_>

source

fn append_expression( &mut self, expr: Expression, span: Span, ) -> Result<Handle<Expression>, Error<'source>>

source

fn const_access(&self, handle: Handle<Expression>) -> Option<u32>

source

fn get_expression_span(&self, handle: Handle<Expression>) -> Span

source

fn typifier(&self) -> &Typifier

source

fn local( &mut self, local: &Handle<Local>, span: Span, ) -> Result<Typed<Handle<Expression>>, Error<'source>>

source

fn runtime_expression_ctx( &mut self, span: Span, ) -> Result<&mut LocalExpressionContext<'temp, 'out>, Error<'source>>

source

fn gather_component( &mut self, expr: Handle<Expression>, component_span: Span, gather_span: Span, ) -> Result<SwizzleComponent, Error<'source>>

source

fn register_type( &mut self, handle: Handle<Expression>, ) -> Result<Handle<Type>, Error<'source>>

Determine the type of handle, and add it to the module’s arena.

If you just need a TypeInner for handle’s type, use the resolve_inner! macro instead. This function should only be used when the type of handle needs to appear in the module’s final Arena<Type>, for example, if you’re creating a LocalVariable whose type is inferred from its initializer.

source

fn grow_types( &mut self, handle: Handle<Expression>, ) -> Result<&mut Self, Error<'source>>

Resolve the types of all expressions up through handle.

Ensure that self.typifier has a TypeResolution for every expression in [self.function.expressions].

This does not add types to any arena. The Typifier documentation explains the steps we take to avoid filling arenas with intermediate types.

This function takes &mut self, so it can’t conveniently return a shared reference to the resulting TypeResolution: the shared reference would extend the mutable borrow, and you wouldn’t be able to use self for anything else. Instead, you should use register_type or one of resolve!, resolve_inner! or resolve_inner_binary!.

source

fn image_data( &mut self, image: Handle<Expression>, span: Span, ) -> Result<(ImageClass, bool), Error<'source>>

source

fn prepare_args<'b>( &mut self, args: &'b [Handle<Expression<'source>>], min_args: u32, span: Span, ) -> ArgumentContext<'b, 'source>

source

fn binary_op_splat( &mut self, op: BinaryOperator, left: &mut Handle<Expression>, right: &mut Handle<Expression>, ) -> Result<(), Error<'source>>

Insert splats, if needed by the non-‘*’ operations.

See the “Binary arithmetic expressions with mixed scalar and vector operands” table in the WebGPU Shading Language specification for relevant operators.

Multiply is not handled here as backends are expected to handle vec*scalar operations, so inserting splats into the IR increases size needlessly.

source

fn interrupt_emitter( &mut self, expression: Expression, span: Span, ) -> Result<Handle<Expression>, Error<'source>>

Add a single expression to the expression table that is not covered by self.emitter.

This is useful for CallResult and AtomicResult expressions, which should not be covered by Emit statements.

source

fn apply_load_rule( &mut self, expr: Typed<Handle<Expression>>, ) -> Result<Handle<Expression>, Error<'source>>

Apply the WGSL Load Rule to expr.

If expr is has type ref<SC, T, A>, perform a load to produce a value of type T. Otherwise, return expr unchanged.

source

fn ensure_type_exists(&mut self, inner: TypeInner) -> Handle<Type>

Auto Trait Implementations§

§

impl<'source, 'temp, 'out> Freeze for ExpressionContext<'source, 'temp, 'out>

§

impl<'source, 'temp, 'out> RefUnwindSafe for ExpressionContext<'source, 'temp, 'out>

§

impl<'source, 'temp, 'out> Send for ExpressionContext<'source, 'temp, 'out>

§

impl<'source, 'temp, 'out> Sync for ExpressionContext<'source, 'temp, 'out>

§

impl<'source, 'temp, 'out> Unpin for ExpressionContext<'source, 'temp, 'out>

§

impl<'source, 'temp, 'out> !UnwindSafe for ExpressionContext<'source, 'temp, 'out>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.