1919use std:: { collections:: BTreeSet , fmt:: Display } ;
2020
2121use cedar_policy_core:: {
22- ast:: { CallStyle , EntityUID , Expr , ExprKind , Var } ,
22+ ast:: { CallStyle , EntityUID , Expr , ExprKind , Name , Var } ,
2323 parser:: SourceInfo ,
2424} ;
2525
@@ -96,19 +96,6 @@ impl TypeError {
9696 }
9797 }
9898
99- pub ( crate ) fn types_must_match < T > (
100- on_expr : Expr < T > ,
101- types : impl IntoIterator < Item = Type > ,
102- ) -> Self {
103- Self {
104- on_expr : None ,
105- source_location : on_expr. into_source_info ( ) ,
106- kind : TypeErrorKind :: TypesMustMatch ( TypesMustMatch {
107- types : types. into_iter ( ) . collect :: < BTreeSet < _ > > ( ) ,
108- } ) ,
109- }
110- }
111-
11299 pub ( crate ) fn unsafe_attribute_access (
113100 on_expr : Expr ,
114101 attribute_access : AttributeAccess ,
@@ -196,6 +183,18 @@ impl TypeError {
196183 kind : TypeErrorKind :: NonLitExtConstructor ,
197184 }
198185 }
186+
187+ pub ( crate ) fn hierarchy_not_respected < T > (
188+ on_expr : Expr < T > ,
189+ in_lhs : Option < Name > ,
190+ in_rhs : Option < Name > ,
191+ ) -> Self {
192+ Self {
193+ on_expr : None ,
194+ source_location : on_expr. into_source_info ( ) ,
195+ kind : TypeErrorKind :: HierarchyNotRespected ( HierarchyNotRespected { in_lhs, in_rhs } ) ,
196+ }
197+ }
199198}
200199
201200impl Display for TypeError {
@@ -264,12 +263,19 @@ pub enum TypeErrorKind {
264263 /// Error returned by custom extension function argument validation
265264 #[ error( "Error during extension function argument validation: {}" , . 0 . msg) ]
266265 FunctionArgumentValidationError ( FunctionArgumentValidationError ) ,
267- #[ error( "Types of operands in this expression are not equal: [{}]" , . 0 . types. iter( ) . join( "," ) ) ]
268- TypesMustMatch ( TypesMustMatch ) ,
269266 #[ error( "empty set literals are forbidden in policies" ) ]
270267 EmptySetForbidden ,
271268 #[ error( "extension constructors may not be called with non-literal expressions" ) ]
272269 NonLitExtConstructor ,
270+ /// To pass strict validation a policy cannot contain an `in` expression
271+ /// where the entity type on the left might not be able to be a member of
272+ /// the entity type on the right.
273+ #[ error( "operands to `in` do not respect the entity hierarchy{}" ,
274+ match ( & . 0 . in_lhs, & . 0 . in_rhs) {
275+ ( Some ( in_lhs) , Some ( in_rhs) ) => format!( ". `{}` is not a descendant of `{}`" , in_lhs, in_rhs) ,
276+ _ => "" . to_string( ) ,
277+ } ) ]
278+ HierarchyNotRespected ( HierarchyNotRespected ) ,
273279}
274280
275281/// Structure containing details about an unexpected type error.
@@ -282,12 +288,6 @@ pub struct UnexpectedType {
282288/// Structure containing details about an incompatible type error.
283289#[ derive( Debug , Hash , Eq , PartialEq ) ]
284290pub struct IncompatibleTypes {
285- types : BTreeSet < Type > ,
286- }
287-
288- /// Structure containing details about types must match error.
289- #[ derive( Debug , Hash , Eq , PartialEq ) ]
290- pub struct TypesMustMatch {
291291 pub ( crate ) types : BTreeSet < Type > ,
292292}
293293
@@ -339,6 +339,13 @@ pub struct FunctionArgumentValidationError {
339339 msg : String ,
340340}
341341
342+ /// Structure containing details about a hierarchy not respected error
343+ #[ derive( Debug , Hash , Eq , PartialEq ) ]
344+ pub struct HierarchyNotRespected {
345+ in_lhs : Option < Name > ,
346+ in_rhs : Option < Name > ,
347+ }
348+
342349/// Contains more detailed information about an attribute access when it occurs
343350/// on an entity type expression or on the `context` variable. Track a `Vec` of
344351/// attributes rather than a single attribute so that on `principal.foo.bar` can
0 commit comments