Skip to content

Commit 67bd388

Browse files
Resolve types at fragment-combine time (#1060)
Signed-off-by: Craig Disselkoen <[email protected]> Co-authored-by: John Kastner <[email protected]>
1 parent 5b3d3f5 commit 67bd388

File tree

30 files changed

+4969
-1344
lines changed

30 files changed

+4969
-1344
lines changed

cedar-policy-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lalrpop-util = { version = "0.20.0", features = ["lexer"] }
2020
lazy_static = "1.4"
2121
either = "1.8"
2222
itertools = "0.13"
23+
ref-cast = "1.0"
2324
rustc_lexer = "0.1"
2425
thiserror = "1.0"
2526
smol_str = { version = "0.2", features = ["serde"] }

cedar-policy-core/src/ast/entity.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::transitive_closure::TCNode;
2424
use crate::FromNormalizedStr;
2525
use itertools::Itertools;
2626
use miette::Diagnostic;
27+
use ref_cast::RefCast;
2728
use serde::{Deserialize, Serialize};
2829
use serde_with::{serde_as, TryFromInto};
2930
use smol_str::SmolStr;
@@ -35,9 +36,10 @@ use thiserror::Error;
3536
pub static ACTION_ENTITY_TYPE: &str = "Action";
3637

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

4345
impl EntityType {
@@ -59,15 +61,14 @@ impl EntityType {
5961
self.0.as_ref().loc()
6062
}
6163

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

6769
/// Wraps [`Name::from_normalized_str`]
6870
pub fn from_normalized_str(src: &str) -> Result<Self, ParseErrors> {
69-
UncheckedName::from_normalized_str(src)
70-
.and_then(|n| n.try_into().map(Self).map_err(ParseErrors::singleton))
71+
Name::from_normalized_str(src).map(Into::into)
7172
}
7273
}
7374

@@ -77,6 +78,12 @@ impl From<Name> for EntityType {
7778
}
7879
}
7980

81+
impl From<EntityType> for Name {
82+
fn from(ty: EntityType) -> Name {
83+
ty.0
84+
}
85+
}
86+
8087
impl AsRef<Name> for EntityType {
8188
fn as_ref(&self) -> &Name {
8289
&self.0

cedar-policy-core/src/ast/expr.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,16 @@ impl From<Var> for Id {
14631463
}
14641464
}
14651465

1466+
// PANIC SAFETY Tested by `test::all_vars_are_ids`. Never panics.
1467+
#[allow(clippy::fallible_impl_from)]
1468+
impl From<Var> for UnreservedId {
1469+
fn from(var: Var) -> Self {
1470+
// PANIC SAFETY: `Var` is a simple enum and all vars are formatted as valid `UnreservedId`. Tested by `test::all_vars_are_ids`
1471+
#[allow(clippy::unwrap_used)]
1472+
Id::from(var).try_into().unwrap()
1473+
}
1474+
}
1475+
14661476
impl std::fmt::Display for Var {
14671477
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14681478
match self {
@@ -1487,6 +1497,7 @@ mod test {
14871497
fn all_vars_are_ids() {
14881498
for var in all_vars() {
14891499
let _id: Id = var.into();
1500+
let _id: UnreservedId = var.into();
14901501
}
14911502
}
14921503

cedar-policy-core/src/ast/id.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use smol_str::SmolStr;
1919

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

22-
use super::{ReservedNameError, UncheckedName};
22+
use super::{InternalName, ReservedNameError};
2323

2424
const RESERVED_ID: &str = "__cedar";
2525

@@ -106,13 +106,19 @@ impl TryFrom<Id> for UnreservedId {
106106
type Error = ReservedNameError;
107107
fn try_from(value: Id) -> Result<Self, Self::Error> {
108108
if value.is_reserved() {
109-
Err(ReservedNameError(UncheckedName::unqualified_name(value)))
109+
Err(ReservedNameError(InternalName::unqualified_name(value)))
110110
} else {
111111
Ok(Self(value))
112112
}
113113
}
114114
}
115115

116+
impl AsRef<Id> for UnreservedId {
117+
fn as_ref(&self) -> &Id {
118+
&self.0
119+
}
120+
}
121+
116122
impl AsRef<str> for UnreservedId {
117123
fn as_ref(&self) -> &str {
118124
self.0.as_ref()

0 commit comments

Comments
 (0)