aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-27 14:39:54 +0000
committerGitHub <noreply@github.com>2021-04-27 14:39:54 +0000
commit6647bc65b1a2d3ba581674a9ca22d4ef7a959914 (patch)
tree73d105263d6fbf23eea1ea94a97af950eaf9bb03 /gcc/rust
parenta24a14371b16c316a815a9440b1d960cd3f885dd (diff)
parent3df65d5b4ec06c7ac1ec39d8d1a1c268b024531c (diff)
downloadgcc-6647bc65b1a2d3ba581674a9ca22d4ef7a959914.zip
gcc-6647bc65b1a2d3ba581674a9ca22d4ef7a959914.tar.gz
gcc-6647bc65b1a2d3ba581674a9ca22d4ef7a959914.tar.bz2
Merge #394
394: Partial substitions of generic data types r=philberty a=philberty Handle the case where we have a generic type: ```rust struct Foo<A,B>(A,B); impl<T> Foo<i32, T> { ... } ``` In this case the impl block only defines 1 type parameter but the generic datatype has two type parameters. Fixes #386 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h11
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h4
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc35
-rw-r--r--gcc/rust/typecheck/rust-tyty.h22
4 files changed, 58 insertions, 14 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 5643ad6..5dafd64 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -811,8 +811,15 @@ public:
else if (expr.get_num_segments () == 1)
{
Location locus = expr.get_segments ().back ().get_locus ();
- if (tyseg->needs_generic_substitutions ())
- tyseg = SubstMapper::InferSubst (tyseg, locus);
+
+ bool is_big_self
+ = expr.get_segments ().front ().get_segment ().as_string ().compare (
+ "Self")
+ == 0;
+ if (!is_big_self && tyseg->needs_generic_substitutions ())
+ {
+ tyseg = SubstMapper::InferSubst (tyseg, locus);
+ }
infered = tyseg;
return;
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index 37a82c4..d022019 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -133,6 +133,8 @@ public:
{
TyTy::SubstitutionArgumentMappings adjusted
= type.adjust_mappings_for_this (mappings);
+ if (adjusted.is_error ())
+ return;
TyTy::BaseType *concrete = type.handle_substitions (adjusted);
if (concrete != nullptr)
@@ -143,6 +145,8 @@ public:
{
TyTy::SubstitutionArgumentMappings adjusted
= type.adjust_mappings_for_this (mappings);
+ if (adjusted.is_error ())
+ return;
TyTy::BaseType *concrete = type.handle_substitions (adjusted);
if (concrete != nullptr)
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index baa997b..8cc9089 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -242,15 +242,6 @@ SubstitutionArgumentMappings
SubstitutionRef::adjust_mappings_for_this (
SubstitutionArgumentMappings &mappings)
{
- if (substitutions.size () > mappings.size ())
- {
- rust_error_at (mappings.get_locus (),
- "not enough type arguments: subs %s vs mappings %s",
- subst_as_string ().c_str (),
- mappings.as_string ().c_str ());
- return SubstitutionArgumentMappings::error ();
- }
-
Analysis::Mappings *mappings_table = Analysis::Mappings::get ();
std::vector<SubstitutionArg> resolved_mappings;
@@ -259,13 +250,33 @@ SubstitutionRef::adjust_mappings_for_this (
auto &subst = substitutions.at (i);
SubstitutionArg arg = SubstitutionArg::error ();
- bool ok = mappings.get_argument_at (0, &arg);
+ if (mappings.size () == substitutions.size ())
+ {
+ mappings.get_argument_at (i, &arg);
+ }
+ else
+ {
+ if (subst.needs_substitution ())
+ {
+ // get from passed in mappings
+ mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
+ }
+ else
+ {
+ // we should already have this somewhere
+ used_arguments.get_argument_for_symbol (subst.get_param_ty (),
+ &arg);
+ }
+ }
+
+ bool ok = !arg.is_error ();
if (!ok)
{
rust_error_at (mappings_table->lookup_location (
subst.get_param_ty ()->get_ref ()),
- "failed to find parameter type: %s",
- subst.get_param_ty ()->as_string ().c_str ());
+ "failed to find parameter type: %s vs mappings [%s]",
+ subst.get_param_ty ()->as_string ().c_str (),
+ mappings.as_string ().c_str ());
return SubstitutionArgumentMappings::error ();
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index bc4c9c4..f3ff609 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -408,6 +408,15 @@ public:
void override_context ();
+ bool needs_substitution () const
+ {
+ auto p = get_param_ty ();
+ if (!p->can_resolve ())
+ return true;
+
+ return p->resolve ()->get_kind () == TypeKind::PARAM;
+ }
+
private:
std::unique_ptr<HIR::GenericParam> &generic;
ParamType *param;
@@ -437,6 +446,8 @@ public:
static SubstitutionArg error () { return SubstitutionArg (nullptr, nullptr); }
+ bool is_error () const { return param == nullptr || argument == nullptr; }
+
bool is_conrete () const
{
return argument != nullptr && argument->get_kind () != TyTy::TypeKind::ERROR
@@ -600,6 +611,17 @@ public:
return used_arguments;
}
+ size_t num_required_substitutions () const
+ {
+ size_t n = 0;
+ for (auto &p : substitutions)
+ {
+ if (p.needs_substitution ())
+ n++;
+ }
+ return n;
+ }
+
// We are trying to subst <i32, f32> into Struct Foo<X,Y> {}
// in the case of Foo<i32,f32>{...}
//