aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-04-30 11:48:20 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-04-30 11:57:48 +0100
commitb7d95ea80be40c5ee468a5549d84e058a21fc62c (patch)
tree92dfd62b9f3ebf2d73a0bfcaf2b59c513191aead /gcc/rust
parent91ca22c7b9141364aa4bebc61e46ae1518b793f3 (diff)
downloadgcc-b7d95ea80be40c5ee468a5549d84e058a21fc62c.zip
gcc-b7d95ea80be40c5ee468a5549d84e058a21fc62c.tar.gz
gcc-b7d95ea80be40c5ee468a5549d84e058a21fc62c.tar.bz2
Add initial support for defaults on generic parameters
In the case that the GenericArgs to a type/fn are less than the expected number of required substitutions we need to look for what is the min number of required substitutions which might be zero if each TypeParam has a default. In the event we have less than expected arguments we can substitute the defaults if available as the GenericArgumentMappings. Addresses: #307
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h6
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc18
-rw-r--r--gcc/rust/typecheck/rust-tyty.h20
3 files changed, 43 insertions, 1 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index dbbc743..648999b 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -117,6 +117,12 @@ public:
return type;
}
+ Analysis::NodeMapping get_type_mappings () const
+ {
+ rust_assert (type != nullptr);
+ return type->get_mappings ();
+ }
+
protected:
// Clone function implementation as (not pure) virtual method
TypeParam *clone_generic_param_impl () const override
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index be56dc7..3e9098d 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -233,7 +233,7 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
return SubstitutionArgumentMappings::error ();
}
- if (args.get_type_args ().size () < substitutions.size ())
+ if (args.get_type_args ().size () < min_required_substitutions ())
{
RichLocation r (args.get_locus ());
r.add_range (substitutions.front ().get_param_locus ());
@@ -260,6 +260,22 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
mappings.push_back (std::move (subst_arg));
}
+ // we must need to fill out defaults
+ size_t left_over
+ = num_required_substitutions () - min_required_substitutions ();
+ if (left_over > 0)
+ {
+ for (size_t offs = mappings.size (); offs < substitutions.size (); offs++)
+ {
+ SubstitutionParamMapping &param = substitutions.at (offs);
+ rust_assert (param.param_has_default_ty ());
+
+ BaseType *resolved = param.get_default_ty ();
+ SubstitutionArg subst_arg (&param, resolved);
+ mappings.push_back (std::move (subst_arg));
+ }
+ }
+
return SubstitutionArgumentMappings (mappings, args.get_locus ());
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 5beedda..d6a3aef 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -449,6 +449,12 @@ public:
bool param_has_default_ty () const { return generic.has_type (); }
+ BaseType *get_default_ty () const
+ {
+ TyVar var (generic.get_type_mappings ().get_hirid ());
+ return var.get_tyty ();
+ }
+
private:
const HIR::TypeParam &generic;
ParamType *param;
@@ -643,6 +649,7 @@ public:
return used_arguments;
}
+ // this is the count of type params that are not substituted fuly
size_t num_required_substitutions () const
{
size_t n = 0;
@@ -654,6 +661,19 @@ public:
return n;
}
+ // this is the count of type params that need substituted taking into account
+ // possible defaults
+ size_t min_required_substitutions () const
+ {
+ size_t n = 0;
+ for (auto &p : substitutions)
+ {
+ if (p.needs_substitution () && !p.param_has_default_ty ())
+ n++;
+ }
+ return n;
+ }
+
// We are trying to subst <i32, f32> into Struct Foo<X,Y> {}
// in the case of Foo<i32,f32>{...}
//