# NOTE:
# check here to see if the new type
# is a subtype of the old one
- ($type_constraint->is_subtype_of($self->type_constraint->name))
- || confess "New type constraint setting must be a subtype of inherited one"
- # iff we have a type constraint that is ...
- if $self->has_type_constraint;
+ # or if the old one is a union and the
+ # subtype (or a supertype of it) is included
+ # in the union
+ $type_constraint->is_subtype_of($self->type_constraint->name)
+ || ($self->type_constraint->can('includes_type') && $self->type_constraint->includes_type($type_constraint))
+ || confess "New type constraint setting must be a subtype of inherited one" . ($self->type_constraint->can('includes_type') ? ", or included in the inherited constraint" : '')
+ # iff we have a type constraint that is ...
+ if $self->has_type_constraint;
# then we use it :)
$actual_options{type_constraint} = $type_constraint;
delete $options{isa};
return 0;
}
+sub includes_type {
+ my ($self, $type) = @_;
+
+ my $has_type = sub {
+ my $subtype = shift;
+
+ for my $type (@{ $self->type_constraints }) {
+ return 1 if $subtype->is_a_type_of($type);
+ }
+
+ return 0;
+ };
+
+ if ($type->isa('Moose::Meta::TypeConstraint::Union')) {
+ for my $t (@{ $type->type_constraints }) {
+ return 0 unless $has_type->($t);
+ }
+ }
+ else {
+ return 0 unless $has_type->($type);
+ }
+
+ return 1;
+}
+
1;
__END__
=item B<constraint>
+=item B<includes_type>
+
=back
=head2 Overriden methods