From: Dave Rolsky Date: Thu, 4 Dec 2008 22:39:05 +0000 (+0000) Subject: The last checkin was broken in the case where class B inherited from X-Git-Tag: 0.62_02~16 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=12875d6ef6cb1dd09c49b0d22660906486aa23d7;p=gitmo%2FMoose.git The last checkin was broken in the case where class B inherited from class A, and class A had made itself immutable. In that case, MMMC thought that the inlined constructor for A meant it couldn't inline for B. This checkin fixes it to be much smarter. If any parent is inlined, it checks to see if the inlined constructor's class in the parent matches the constructor class that's trying to do inlining. If they match, it goes ahead and inlines, otherwise it doesn't. --- diff --git a/lib/Moose/Meta/Method/Constructor.pm b/lib/Moose/Meta/Method/Constructor.pm index 83347ba..4873c8b 100644 --- a/lib/Moose/Meta/Method/Constructor.pm +++ b/lib/Moose/Meta/Method/Constructor.pm @@ -51,6 +51,20 @@ sub can_be_inlined { my $self = shift; my $metaclass = $self->associated_metaclass; + # If any of our parents have been made immutable, we are okay to + # inline our own method as long as the parent's constructor class + # is the same as $self. + for my $meta ( grep { $_->is_immutable } + map { ( ref $metaclass )->initialize($_) } + $metaclass->linearized_isa ) { + my $transformer = $meta->get_immutable_transformer; + + my $constructor = $transformer->inlined_constructor + or next; + + return ref $constructor eq ref $self; + } + if ( my $constructor = $metaclass->find_method_by_name( $self->name ) ) { my $expected_class = $self->_expected_constructor_class; diff --git a/t/300_immutable/010_constructor_is_not_moose.t b/t/300_immutable/010_constructor_is_not_moose.t index 948c35f..2a03b24 100644 --- a/t/300_immutable/010_constructor_is_not_moose.t +++ b/t/300_immutable/010_constructor_is_not_moose.t @@ -8,7 +8,7 @@ use Test::More; eval "use Test::Output"; plan skip_all => "Test::Output is required for this test" if $@; -plan tests => 4; +plan tests => 5; { package NotMoose; @@ -57,3 +57,23 @@ isnt( Moose::Object->can('new'), 'Bar->new is not inherited from NotMoose because it was inlined' ); + +{ + package Baz; + use Moose; + + Baz->meta->make_immutable; +} + +{ + package Quux; + use Moose; + + extends 'Baz'; + + ::stderr_is( + sub { Quux->meta->make_immutable }, + q{}, + 'no warning when inheriting from a class that has already made itself immutable' + ); +}