Skip to content

Commit

Permalink
Resolve types at fragment-combine time (#1060)
Browse files Browse the repository at this point in the history
Signed-off-by: Craig Disselkoen <cdiss@amazon.com>
Co-authored-by: John Kastner <130772734+john-h-kastner-aws@users.noreply.github.com>
  • Loading branch information
cdisselkoen and john-h-kastner-aws committed Aug 2, 2024
1 parent 5b3d3f5 commit 67bd388
Show file tree
Hide file tree
Showing 30 changed files with 4,969 additions and 1,344 deletions.
1 change: 1 addition & 0 deletions cedar-policy-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ lalrpop-util = { version = "0.20.0", features = ["lexer"] }
lazy_static = "1.4"
either = "1.8"
itertools = "0.13"
ref-cast = "1.0"
rustc_lexer = "0.1"
thiserror = "1.0"
smol_str = { version = "0.2", features = ["serde"] }
Expand Down
17 changes: 12 additions & 5 deletions cedar-policy-core/src/ast/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::transitive_closure::TCNode;
use crate::FromNormalizedStr;
use itertools::Itertools;
use miette::Diagnostic;
use ref_cast::RefCast;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, TryFromInto};
use smol_str::SmolStr;
Expand All @@ -35,9 +36,10 @@ use thiserror::Error;
pub static ACTION_ENTITY_TYPE: &str = "Action";

/// Entity type names are just [`Name`]s, but we have some operations on them specific to entity types.
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Hash, PartialOrd, Ord)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Hash, PartialOrd, Ord, RefCast)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[serde(transparent)]
#[repr(transparent)]
pub struct EntityType(Name);

impl EntityType {
Expand All @@ -59,15 +61,14 @@ impl EntityType {
self.0.as_ref().loc()
}

/// Calls [`Name::qualify_with`] on the underlying [`Name`]
/// Calls [`Name::qualify_with_name`] on the underlying [`Name`]
pub fn qualify_with(&self, namespace: Option<&Name>) -> Self {
Self(self.0.qualify_with(namespace))
Self(self.0.qualify_with_name(namespace))
}

/// Wraps [`Name::from_normalized_str`]
pub fn from_normalized_str(src: &str) -> Result<Self, ParseErrors> {
UncheckedName::from_normalized_str(src)
.and_then(|n| n.try_into().map(Self).map_err(ParseErrors::singleton))
Name::from_normalized_str(src).map(Into::into)
}
}

Expand All @@ -77,6 +78,12 @@ impl From<Name> for EntityType {
}
}

impl From<EntityType> for Name {
fn from(ty: EntityType) -> Name {
ty.0
}
}

impl AsRef<Name> for EntityType {
fn as_ref(&self) -> &Name {
&self.0
Expand Down
11 changes: 11 additions & 0 deletions cedar-policy-core/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,16 @@ impl From<Var> for Id {
}
}

// PANIC SAFETY Tested by `test::all_vars_are_ids`. Never panics.
#[allow(clippy::fallible_impl_from)]
impl From<Var> for UnreservedId {
fn from(var: Var) -> Self {
// PANIC SAFETY: `Var` is a simple enum and all vars are formatted as valid `UnreservedId`. Tested by `test::all_vars_are_ids`
#[allow(clippy::unwrap_used)]
Id::from(var).try_into().unwrap()
}
}

impl std::fmt::Display for Var {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expand All @@ -1487,6 +1497,7 @@ mod test {
fn all_vars_are_ids() {
for var in all_vars() {
let _id: Id = var.into();
let _id: UnreservedId = var.into();
}
}

Expand Down
10 changes: 8 additions & 2 deletions cedar-policy-core/src/ast/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use smol_str::SmolStr;

use crate::{parser::err::ParseErrors, FromNormalizedStr};

use super::{ReservedNameError, UncheckedName};
use super::{InternalName, ReservedNameError};

const RESERVED_ID: &str = "__cedar";

Expand Down Expand Up @@ -106,13 +106,19 @@ impl TryFrom<Id> for UnreservedId {
type Error = ReservedNameError;
fn try_from(value: Id) -> Result<Self, Self::Error> {
if value.is_reserved() {
Err(ReservedNameError(UncheckedName::unqualified_name(value)))
Err(ReservedNameError(InternalName::unqualified_name(value)))
} else {
Ok(Self(value))
}
}
}

impl AsRef<Id> for UnreservedId {
fn as_ref(&self) -> &Id {
&self.0
}
}

impl AsRef<str> for UnreservedId {
fn as_ref(&self) -> &str {
self.0.as_ref()
Expand Down
Loading

0 comments on commit 67bd388

Please sign in to comment.