<commit_before>class Perl6::Metamodel::ParametricRoleHOW
    does Perl6::Metamodel::Naming
    does Perl6::Metamodel::Versioning
    does Perl6::Metamodel::MethodContainer
    does Perl6::Metamodel::MultiMethodContainer
    does Perl6::Metamodel::AttributeContainer
    does Perl6::Metamodel::RoleContainer
    does Perl6::Metamodel::MultipleInheritance
    does Perl6::Metamodel::Stashing
    does Perl6::Metamodel::NonGeneric
{
    my $concrete := Perl6::Metamodel::ConcreteRoleHOW;
    has $!composed;
    has $!body_block;

    method new_type(:$name = '<anon>', :$ver, :$auth, :$repr) {
        my $metarole := self.new(:name($name), :ver($ver), :auth($auth));
        self.add_stash(pir::repr_type_object_for__PPS($metarole, 'Uninstantiable'));
    }
    
    method set_body_block($obj, $block) {
        $!body_block := $block
    }
    
    method compose($obj) {
        $!composed := 1;
        $obj
    }
    
    method curry($obj, *@pos_args, *%named_args) {
        # XXX We really want to keep a cache here of previously
        # seen curryings.
        Perl6::Metamodel::CurriedRoleHOW.new_type(:curried_role($obj),
            :pos_args(@pos_args), |named_args(%named_args))
    }
    
    method specialize($obj, *@pos_args, *%named_args) {
        # Run the body block to get the type environment.
        my $type_env;
        my $error;
        try {
            $type_env := $!body_block(|@pos_args, |%named_args);
            CATCH {
                $error := $!
            }
        }
        if $error {
            pir::die("Could not instantiate role '" ~ self.name($obj) ~ "'\n$error")
        }
        
        # Create a concrete role.
        my $conc := $concrete.new_type(:name(self.name($obj)));
        
        # Go through attributes, reifying as needed and adding to
        # the concrete role.
        for self.attributes($obj, :local(1)) {
            $conc.HOW.add_attribute($conc,
                $_.is_generic ?? $_.instantiate_generic($type_env) !! $_);
        }
        
        # Go through methods and instantiate them; we always do this
        # unconditionally, since we need the clone anyway.
        for self.methods($obj, :local(1)) {
            $conc.HOW.add_method($conc, $_.name, $_.instantiate_generic($type_env))
        }
        
        # XXX More to copy/instantiate
        
        $conc.HOW.compose($conc);
        return $conc;
    }
}
<commit_msg>Try and make it clearer that line 2 of an error message is actually an explanation for line 1.<commit_after>class Perl6::Metamodel::ParametricRoleHOW
    does Perl6::Metamodel::Naming
    does Perl6::Metamodel::Versioning
    does Perl6::Metamodel::MethodContainer
    does Perl6::Metamodel::MultiMethodContainer
    does Perl6::Metamodel::AttributeContainer
    does Perl6::Metamodel::RoleContainer
    does Perl6::Metamodel::MultipleInheritance
    does Perl6::Metamodel::Stashing
    does Perl6::Metamodel::NonGeneric
{
    my $concrete := Perl6::Metamodel::ConcreteRoleHOW;
    has $!composed;
    has $!body_block;

    method new_type(:$name = '<anon>', :$ver, :$auth, :$repr) {
        my $metarole := self.new(:name($name), :ver($ver), :auth($auth));
        self.add_stash(pir::repr_type_object_for__PPS($metarole, 'Uninstantiable'));
    }
    
    method set_body_block($obj, $block) {
        $!body_block := $block
    }
    
    method compose($obj) {
        $!composed := 1;
        $obj
    }
    
    method curry($obj, *@pos_args, *%named_args) {
        # XXX We really want to keep a cache here of previously
        # seen curryings.
        Perl6::Metamodel::CurriedRoleHOW.new_type(:curried_role($obj),
            :pos_args(@pos_args), |named_args(%named_args))
    }
    
    method specialize($obj, *@pos_args, *%named_args) {
        # Run the body block to get the type environment.
        my $type_env;
        my $error;
        try {
            $type_env := $!body_block(|@pos_args, |%named_args);
            CATCH {
                $error := $!
            }
        }
        if $error {
            pir::die("Could not instantiate role '" ~ self.name($obj) ~ "':\n$error")
        }
        
        # Create a concrete role.
        my $conc := $concrete.new_type(:name(self.name($obj)));
        
        # Go through attributes, reifying as needed and adding to
        # the concrete role.
        for self.attributes($obj, :local(1)) {
            $conc.HOW.add_attribute($conc,
                $_.is_generic ?? $_.instantiate_generic($type_env) !! $_);
        }
        
        # Go through methods and instantiate them; we always do this
        # unconditionally, since we need the clone anyway.
        for self.methods($obj, :local(1)) {
            $conc.HOW.add_method($conc, $_.name, $_.instantiate_generic($type_env))
        }
        
        # XXX More to copy/instantiate
        
        $conc.HOW.compose($conc);
        return $conc;
    }
}

{'fraction_non_alphanumeric': 0.13119415109666938, 'fraction_numerical': 0.006498781478472786, 'mean_word_length': 2.368673050615595, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3093072', 'n_tokens_mistral': 1617, 'n_tokens_neox': 1539, 'n_words': 330}