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
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ pub(crate) fn runtime_singletons_can_be_cloned_if_needed<'a>(
match type_ {
Type::ScalarPrimitive(_)
| Type::Reference(_)
| Type::Slice(_) => {
| Type::Slice(_)
| Type::Array(_)
| Type::RawPointer(_) => {
return None;
}
Type::Path(_) | Type::Tuple(_) => {}
Expand Down
12 changes: 12 additions & 0 deletions compiler/pavexc/src/compiler/analyses/application_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,18 @@ fn _field_name_candidate(ty_: &Type, strategy: NamingStrategy, candidate: &mut S
// Same reasoning as for references.
_field_name_candidate(&slice.element_type, strategy, candidate);
}
Type::Array(array) => {
// Same reasoning as for slices.
_field_name_candidate(&array.element_type, strategy, candidate);
}
Type::RawPointer(raw_pointer) => {
if raw_pointer.is_mutable {
candidate.push_str("mut_ptr_");
} else {
candidate.push_str("const_ptr_");
}
_field_name_candidate(&raw_pointer.inner, strategy, candidate);
}
Type::Generic(generic) => {
// We don't have unassigned generics in the application state, so this should never happen.
// But, should it happen, there's really no other way to name it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,11 @@ impl CodegenedRequestHandlerPipeline {
}
}
Type::Slice(_)
| Type::Array(_)
| Type::Path(_)
| Type::Tuple(_)
| Type::ScalarPrimitive(_) => type_,
| Type::ScalarPrimitive(_)
| Type::RawPointer(_) => type_,
Type::Generic(_) => {
unreachable!("Generic types should have been resolved by now")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,13 +509,18 @@ impl RequestHandlerPipeline {
}
}
Type::Path(_) |
Type::Tuple(_) => {
Type::Tuple(_) |
Type::Array(_) => {
type2info.entry(ty.clone()).or_default().consumed_by.push(ConsumerInfo { middleware_index: index, component_id });
}
// Scalars are trivially `Copy`, this analysis doesn't concern them.
Type::ScalarPrimitive(_) => {
continue;
}
// Raw pointers are trivially `Copy`, this analysis doesn't concern them.
Type::RawPointer(_) => {
continue;
}
// We'd never encounter a raw slice as input type.
Type::Slice(_) |
// All types are concrete at this stage.
Expand Down
6 changes: 6 additions & 0 deletions compiler/pavexc/src/compiler/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,12 @@ fn collect_type_package_ids(package_ids: &mut IndexSet<PackageId>, t: &Type) {
Type::Slice(s) => {
collect_type_package_ids(package_ids, &s.element_type);
}
Type::Array(a) => {
collect_type_package_ids(package_ids, &a.element_type);
}
Type::RawPointer(r) => {
collect_type_package_ids(package_ids, &r.inner);
}
Type::Generic(_) | Type::ScalarPrimitive(_) => {}
}
}
4 changes: 3 additions & 1 deletion compiler/pavexc/src/compiler/codegen/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,11 @@ pub(super) fn get_application_state_new(
}
}
Type::Slice(_)
| Type::Array(_)
| Type::Path(_)
| Type::Tuple(_)
| Type::ScalarPrimitive(_) => type_,
| Type::ScalarPrimitive(_)
| Type::RawPointer(_) => type_,
Type::Generic(_) => {
unreachable!("Generic types should have been resolved by now")
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/pavexc/src/compiler/path_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ fn must_be_a_plain_struct(
Type::Tuple(t) => format!("`{t:?}` is a tuple"),
Type::ScalarPrimitive(s) => format!("`{s:?}` is a primitive"),
Type::Slice(s) => format!("`{s:?}` is a slice"),
Type::Array(a) => format!("`{a:?}` is an array"),
Type::RawPointer(r) => format!("`{r:?}` is a raw pointer"),
Type::Generic(_) => {
unreachable!()
}
Expand Down
62 changes: 52 additions & 10 deletions compiler/pavexc/src/compiler/resolvers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use rustdoc_types::{GenericArg, GenericArgs, GenericParamDefKind, ItemEnum, Type
use tracing_log_error::log_error;

use crate::language::{
Callable, CallableItem, FQGenericArgument, FQPath, FQPathSegment, FQPathType, Generic,
Array, Callable, CallableItem, FQGenericArgument, FQPath, FQPathSegment, FQPathType, Generic,
GenericArgument, GenericLifetimeParameter, InvocationStyle, PathType,
Type, Slice, Tuple, TypeReference, UnknownPath, UnknownPrimitive,
RawPointer, Type, Slice, Tuple, TypeReference, UnknownPath, UnknownPrimitive,
};
use crate::rustdoc::{CannotGetCrateData, CrateCollection, ResolvedItem};
use rustdoc_ext::RustdocKindExt;
Expand Down Expand Up @@ -83,6 +83,13 @@ impl std::fmt::Display for TypeResolutionError {
unsupported_type_kind.kind
)
}
TypeResolutionErrorDetails::UnsupportedArrayLength(unsupported_array_length) => {
write!(
f,
"It uses an array with a non-literal length (`{}`), which isn't currently supported.",
unsupported_array_length.len
)
}
TypeResolutionErrorDetails::GenericKindMismatch(generic_kind_mismatch) => {
write!(
f,
Expand Down Expand Up @@ -121,6 +128,7 @@ pub enum TypeResolutionErrorDetails {
UnsupportedFnPointer(UnsupportedFnPointer),
UnsupportedReturnTypeNotation,
UnsupportedTypeKind(UnsupportedTypeKind),
UnsupportedArrayLength(UnsupportedArrayLength),
UnknownPrimitive(UnknownPrimitive),
GenericKindMismatch(GenericKindMismatch),
ItemResolutionError(anyhow::Error),
Expand Down Expand Up @@ -151,6 +159,11 @@ pub struct UnsupportedTypeKind {
pub kind: &'static str,
}

#[derive(Debug)]
pub struct UnsupportedArrayLength {
pub len: String,
}

#[derive(Debug)]
pub struct GenericKindMismatch {
pub parameter_name: String,
Expand Down Expand Up @@ -573,9 +586,27 @@ pub(crate) fn _resolve_type(
element_type: Box::new(inner),
}))
}
RustdocType::Array { .. } => Err(TypeResolutionErrorDetails::UnsupportedTypeKind(
UnsupportedTypeKind { kind: "array" },
)),
RustdocType::Array { type_, len } => {
let len: usize = len.parse().map_err(|_| {
TypeResolutionErrorDetails::UnsupportedArrayLength(UnsupportedArrayLength {
len: len.clone(),
})
})?;
let resolved =
resolve_type(type_, used_by_package_id, krate_collection, generic_bindings)
.map_err(|source| {
TypeResolutionErrorDetails::TypePartResolutionError(Box::new(
TypePartResolutionError {
role: "array element type".into(),
source,
},
))
})?;
Ok(Type::Array(Array {
element_type: Box::new(resolved),
len,
}))
}
RustdocType::DynTrait(_) => Err(TypeResolutionErrorDetails::UnsupportedTypeKind(
UnsupportedTypeKind { kind: "dyn trait" },
)),
Expand All @@ -595,11 +626,22 @@ pub(crate) fn _resolve_type(
kind: "inferred type",
},
)),
RustdocType::RawPointer { .. } => Err(TypeResolutionErrorDetails::UnsupportedTypeKind(
UnsupportedTypeKind {
kind: "raw pointer",
},
)),
RustdocType::RawPointer { is_mutable, type_ } => {
let resolved =
resolve_type(type_, used_by_package_id, krate_collection, generic_bindings)
.map_err(|source| {
TypeResolutionErrorDetails::TypePartResolutionError(Box::new(
TypePartResolutionError {
role: "pointee type".into(),
source,
},
))
})?;
Ok(Type::RawPointer(RawPointer {
is_mutable: *is_mutable,
inner: Box::new(resolved),
}))
}
RustdocType::QualifiedPath { .. } => Err(TypeResolutionErrorDetails::UnsupportedTypeKind(
UnsupportedTypeKind {
kind: "qualified path",
Expand Down
36 changes: 36 additions & 0 deletions compiler/pavexc/src/compiler/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,29 @@ pub(crate) fn implements_trait(
}
// TODO: handle Unpin + other traits
}
Type::Array(a) => {
// Arrays implement Send/Sync/Copy/Clone/Unpin if their element type does.
if (expected_trait.base_type == SEND_TRAIT_PATH
|| expected_trait.base_type == SYNC_TRAIT_PATH
|| expected_trait.base_type == COPY_TRAIT_PATH
|| expected_trait.base_type == CLONE_TRAIT_PATH
|| expected_trait.base_type == UNPIN_TRAIT_PATH)
&& implements_trait(krate_collection, &a.element_type, expected_trait)?
{
return Ok(true);
}
// TODO: handle other traits
}
Type::RawPointer(_) => {
// Raw pointers are `Copy` and `Clone`, but not `Send` or `Sync`.
if expected_trait.base_type == COPY_TRAIT_PATH
|| expected_trait.base_type == CLONE_TRAIT_PATH
|| expected_trait.base_type == UNPIN_TRAIT_PATH
{
return Ok(true);
}
// TODO: handle other traits
}
Type::Generic(_) => {
// TODO: handle blanket implementations. As a first approximation,
// we assume that if the type is generic, it implements all traits.
Expand Down Expand Up @@ -361,6 +384,19 @@ fn is_equivalent(
);
}
}
RustdocType::Array { type_, len } => {
if let Type::Array(our_array) = our_type
&& let Ok(parsed_len) = len.parse::<usize>()
{
return parsed_len == our_array.len
&& is_equivalent(
type_,
&our_array.element_type,
krate_collection,
used_by_package_id,
);
}
}
n => {
tracing::trace!("We don't handle {:?} yet", n);
}
Expand Down
Loading
Loading