Commits

Toby Inkster committed f149054

to_TypeTiny($coderef) wraps calls to the coderef in an eval and another layer of sub; this prevented Type::Tiny from spotting Sub::Quote quoted subs. to_TypeTiny can now handle quoted subs explicitly, inlining the eval.

Comments (0)

Files changed (2)

lib/Types/TypeTiny.pm

 	return $new;
 }
 
+my $QFS;
 sub _TypeTinyFromCodeRef
 {
 	my $t = $_[0];
 			return sprintf('%s did not pass type constraint', Type::Tiny::_dd($_));
 		},
 	);
+	
+	if ($QFS ||= "Sub::Quote"->can("quoted_from_sub"))
+	{
+		my (undef, $perlstring, $captures) = @{ $QFS->($t) || [] };
+		$perlstring = "!!eval{ $perlstring }";
+		$opts{inlined} = sub
+		{
+			my $var = $_[1];
+			Sub::Quote::inlinify(
+				$perlstring,
+				$var,
+				$var eq q($_) ? '' : "local \$_ = $var;",
+				1,
+			);
+		} if $perlstring && !$captures;
+	}
 
 	require Type::Tiny;
 	my $new = "Type::Tiny"->new(%opts);

t/30-integration/Sub-Quote/basic.t

 
 use Sub::Quote;
 use Type::Tiny;
-use Types::Standard qw(Int);
+use Types::Standard qw( ArrayRef Int );
 
 my $Type1 = "Type::Tiny"->new(
 	name       => "Type1",
 should_fail(44.4, $Type6);
 ok(!$Type6->can_be_inlined, 'constraint built using quote_sub and non-inlinable parent cannot be inlined');
 
+my $Type7 = ArrayRef([Int]) & quote_sub q{ @$_ > 1 and @$_ < 4 };
+
+should_pass([1,2,3], $Type7);
+should_fail([1,2.1,3], $Type7);
+should_fail([1], $Type7);
+should_fail([1,2,3,4], $Type7);
+ok($Type7->can_be_inlined, 'constraint built as an intersection of an inlinable type constraint and a quoted sub can be inlined');
+
+note($Type7->inline_check('$VAR'));
+
 done_testing;