usecrate::{
arena::{Arena, Handle, UniqueArena},
common::ForDebugWithTypes,
ir,
};
/// The result of computing an expression's type. /// /// This is the (Rust) type returned by [`ResolveContext::resolve`] to represent /// the (Naga) type it ascribes to some expression. /// /// You might expect such a function to simply return a `Handle<Type>`. However, /// we want type resolution to be a read-only process, and that would limit the /// possible results to types already present in the expression's associated /// `UniqueArena<Type>`. Naga IR does have certain expressions whose types are /// not certain to be present. /// /// So instead, type resolution returns a `TypeResolution` enum: either a /// [`Handle`], referencing some type in the arena, or a [`Value`], holding a /// free-floating [`TypeInner`]. This extends the range to cover anything that /// can be represented with a `TypeInner` referring to the existing arena. /// /// What sorts of expressions can have types not available in the arena? /// /// - An [`Access`] or [`AccessIndex`] expression applied to a [`Vector`] or /// [`Matrix`] must have a [`Scalar`] or [`Vector`] type. But since `Vector` /// and `Matrix` represent their element and column types implicitly, not /// via a handle, there may not be a suitable type in the expression's /// associated arena. Instead, resolving such an expression returns a /// `TypeResolution::Value(TypeInner::X { ... })`, where `X` is `Scalar` or /// `Vector`. /// /// - Similarly, the type of an [`Access`] or [`AccessIndex`] expression /// applied to a *pointer to* a vector or matrix must produce a *pointer to* /// a scalar or vector type. These cannot be represented with a /// [`TypeInner::Pointer`], since the `Pointer`'s `base` must point into the /// arena, and as before, we cannot assume that a suitable scalar or vector /// type is there. So we take things one step further and provide /// [`TypeInner::ValuePointer`], specifically for the case of pointers to /// scalars or vectors. This type fits in a `TypeInner` and is exactly /// equivalent to a `Pointer` to a `Vector` or `Scalar`. /// /// So, for example, the type of an `Access` expression applied to a value of type: /// /// ```ignore /// TypeInner::Matrix { columns, rows, width } /// ``` /// /// might be: /// /// ```ignore /// TypeResolution::Value(TypeInner::Vector { /// size: rows, /// kind: ScalarKind::Float, /// width, /// }) /// ``` /// /// and the type of an access to a pointer of address space `space` to such a /// matrix might be: /// /// ```ignore /// TypeResolution::Value(TypeInner::ValuePointer { /// size: Some(rows), /// kind: ScalarKind::Float, /// width, /// space, /// }) /// ``` /// /// [`Handle`]: TypeResolution::Handle /// [`Value`]: TypeResolution::Value /// /// [`Access`]: crate::Expression::Access /// [`AccessIndex`]: crate::Expression::AccessIndex /// /// [`TypeInner`]: crate::TypeInner /// [`Matrix`]: crate::TypeInner::Matrix /// [`Pointer`]: crate::TypeInner::Pointer /// [`Scalar`]: crate::TypeInner::Scalar /// [`ValuePointer`]: crate::TypeInner::ValuePointer /// [`Vector`]: crate::TypeInner::Vector /// /// [`TypeInner::Pointer`]: crate::TypeInner::Pointer /// [`TypeInner::ValuePointer`]: crate::TypeInner::ValuePointer #[derive(Debug, PartialEq)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] pubenum TypeResolution { /// A type stored in the associated arena.
Handle(Handle<crate::Type>),
/// A free-floating [`TypeInner`], representing a type that may not be /// available in the associated arena. However, the `TypeInner` itself may /// contain `Handle<Type>` values referring to types from the arena. /// /// The inner type must only be one of the following variants: /// - TypeInner::Pointer /// - TypeInner::ValuePointer /// - TypeInner::Matrix (generated by matrix multiplication) /// - TypeInner::Vector /// - TypeInner::Scalar /// /// [`TypeInner`]: crate::TypeInner
Value(crate::TypeInner),
}
// If any argument is not a constant expression, then no // overloads that accept abstract values should be considered. // `OverloadSet::concrete_only` is supposed to help impose this // restriction. However, no `MathFunction` accepts a mix of // abstract and concrete arguments, so we don't need to worry // about that here.
let res_arg = past(arg)?;
overloads = overloads.arg(0, res_arg.inner_with(types), types);
log::debug!( "overloads after arg 0 of type {:?}: {:#?}",
res_arg.for_debug(types),
overloads.for_debug(types)
);
iflet Some(arg1) = arg1 { let res_arg1 = past(arg1)?;
overloads = overloads.arg(1, res_arg1.inner_with(types), types);
log::debug!( "overloads after arg 1 of type {:?}: {:#?}",
res_arg1.for_debug(types),
overloads.for_debug(types)
);
}
if overloads.is_empty() { return Err(ResolveError::BuiltinArgumentsInvalid(format!("{fun:?}")));
}
/// Compare two types. /// /// This is the most general way of comparing two types, as it can distinguish /// two structs with different names but the same members. For other ways, see /// [`TypeInner::non_struct_equivalent`] and [`TypeInner::eq`]. /// /// In Naga code, this is usually called via the like-named methods on [`Module`], /// [`GlobalCtx`], and `BlockContext`. /// /// [`TypeInner::non_struct_equivalent`]: crate::ir::TypeInner::non_struct_equivalent /// [`TypeInner::eq`]: crate::ir::TypeInner /// [`Module`]: crate::ir::Module /// [`GlobalCtx`]: crate::proc::GlobalCtx pubfn compare_types(
lhs: &TypeResolution,
rhs: &TypeResolution,
types: &UniqueArena<crate::Type>,
) -> bool { match lhs {
&TypeResolution::Handle(lhs_handle) if matches!(
types[lhs_handle],
ir::Type {
inner: ir::TypeInner::Struct { .. },
..
}
) =>
{ // Structs can only be in the arena, not in a TypeResolution::Value
rhs.handle()
.is_some_and(|rhs_handle| lhs_handle == rhs_handle)
}
_ => lhs
.inner_with(types)
.non_struct_equivalent(rhs.inner_with(types), types),
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.