aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc38
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h29
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc49
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h8
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h9
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc2
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-808.rs23
9 files changed, 140 insertions, 22 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index f3302c2e..f0e9bc3 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -86,6 +86,7 @@ GRS_OBJS = \
rust/rust-hir-const-fold.o \
rust/rust-hir-type-check-type.o \
rust/rust-hir-type-check-struct.o \
+ rust/rust-substitution-mapper.o \
rust/rust-lint-marklive.o \
rust/rust-hir-type-check-path.o \
rust/rust-compile-intrinsic.o \
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 838d173..2bcf79d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -101,6 +101,7 @@ protected:
using Rust::Resolver::ResolverBase::visit;
public:
+ // FIXME this should really only take AST::TypeNoBounds&
static CanonicalPath resolve (AST::Type &type,
bool include_generic_args = true,
bool type_resolve_generic_args = true)
@@ -121,6 +122,8 @@ public:
}
}
+ void visit (AST::ReferenceType &ref) override;
+
void visit (AST::TypePathSegmentGeneric &seg) override;
void visit (AST::TypePathSegment &seg) override;
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 921b77c..9a0d349 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -439,8 +439,10 @@ ResolveTypeToCanonicalPath::visit (AST::TypePathSegmentGeneric &seg)
if (!seg.has_generic_args ())
{
- result = CanonicalPath::new_seg (seg.get_node_id (),
- seg.get_ident_segment ().as_string ());
+ auto ident_segment
+ = CanonicalPath::new_seg (seg.get_node_id (),
+ seg.get_ident_segment ().as_string ());
+ result = result.append (ident_segment);
return;
}
@@ -454,14 +456,18 @@ ResolveTypeToCanonicalPath::visit (AST::TypePathSegmentGeneric &seg)
{
std::string generics
= canonicalize_generic_args (seg.get_generic_args ());
- result = CanonicalPath::new_seg (seg.get_node_id (),
- seg.get_ident_segment ().as_string ()
- + "::" + generics);
+ auto generic_segment
+ = CanonicalPath::new_seg (seg.get_node_id (),
+ seg.get_ident_segment ().as_string ()
+ + "::" + generics);
+ result = result.append (generic_segment);
return;
}
- result = CanonicalPath::new_seg (seg.get_node_id (),
- seg.get_ident_segment ().as_string ());
+ auto ident_segment
+ = CanonicalPath::new_seg (seg.get_node_id (),
+ seg.get_ident_segment ().as_string ());
+ result = result.append (ident_segment);
}
void
@@ -481,6 +487,24 @@ ResolveTypeToCanonicalPath::visit (AST::TypePathSegment &seg)
result = result.append (ident_seg);
}
+void
+ResolveTypeToCanonicalPath::visit (AST::ReferenceType &ref)
+{
+ auto inner_type
+ = ResolveTypeToCanonicalPath::resolve (*ref.get_type_referenced ().get (),
+ include_generic_args_flag,
+ type_resolve_generic_args_flag);
+
+ std::string segment_string ("&");
+ if (ref.get_has_mut ())
+ segment_string += "mut ";
+
+ segment_string += inner_type.get ();
+
+ auto ident_seg = CanonicalPath::new_seg (ref.get_node_id (), segment_string);
+ result = result.append (ident_seg);
+}
+
// rust-ast-resolve-expr.h
void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index daef15b..9eef755 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -265,15 +265,29 @@ public:
bool probe_impls = !receiver_is_generic;
bool ignore_mandatory_trait_items = !receiver_is_generic;
+ auto probe_type = probe_impls ? receiver_tyty : root;
auto candidates
- = PathProbeType::Probe (root, expr.get_method_name ().get_segment (),
+ = PathProbeType::Probe (probe_type,
+ expr.get_method_name ().get_segment (),
probe_impls, probe_bounds,
ignore_mandatory_trait_items);
if (candidates.empty ())
{
- rust_error_at (expr.get_locus (),
- "failed to resolve the PathExprSegment to any item");
- return;
+ if (probe_impls)
+ {
+ candidates
+ = PathProbeType::Probe (root,
+ expr.get_method_name ().get_segment (),
+ probe_impls, probe_bounds,
+ ignore_mandatory_trait_items);
+ }
+
+ if (candidates.empty ())
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to resolve the PathExprSegment to any item");
+ return;
+ }
}
std::vector<Adjustment> adjustments;
@@ -295,6 +309,10 @@ public:
return;
}
+ // Get the adjusted self
+ Adjuster adj (receiver_tyty);
+ TyTy::BaseType *adjusted_self = adj.adjust_type (adjustments);
+
// store the adjustments for code-generation to know what to do
context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (),
std::move (adjustments));
@@ -401,7 +419,8 @@ public:
}
TyTy::BaseType *function_ret_tyty
- = TyTy::TypeCheckMethodCallExpr::go (lookup, expr, context);
+ = TyTy::TypeCheckMethodCallExpr::go (lookup, expr, adjusted_self,
+ context);
if (function_ret_tyty == nullptr
|| function_ret_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
new file mode 100644
index 0000000..a439416
--- /dev/null
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -0,0 +1,49 @@
+// Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-substitution-mapper.h"
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver {
+
+TyTy::BaseType *
+SubstMapperInternal::Resolve (TyTy::BaseType *base,
+ TyTy::SubstitutionArgumentMappings &mappings)
+{
+ SubstMapperInternal mapper (base->get_ref (), mappings);
+ base->accept_vis (mapper);
+ rust_assert (mapper.resolved != nullptr);
+
+ // insert these new implict types into the context
+ bool is_fn = mapper.resolved->get_kind () == TyTy::TypeKind::FNDEF;
+ bool is_adt = mapper.resolved->get_kind () == TyTy::TypeKind::ADT;
+ bool is_param = mapper.resolved->get_kind () == TyTy::TypeKind::PARAM;
+ if (!is_fn && !is_adt && !is_param)
+ {
+ auto context = TypeCheckContext::get ();
+ context->insert_type (
+ Analysis::NodeMapping (0, 0, mapper.resolved->get_ty_ref (), 0),
+ mapper.resolved);
+ }
+
+ return mapper.resolved;
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index 0b3ec3b..0932038 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -154,13 +154,7 @@ class SubstMapperInternal : public TyTy::TyVisitor
{
public:
static TyTy::BaseType *Resolve (TyTy::BaseType *base,
- TyTy::SubstitutionArgumentMappings &mappings)
- {
- SubstMapperInternal mapper (base->get_ref (), mappings);
- base->accept_vis (mapper);
- rust_assert (mapper.resolved != nullptr);
- return mapper.resolved;
- }
+ TyTy::SubstitutionArgumentMappings &mappings);
void visit (TyTy::FnType &type) override
{
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index c11fd4d..3080427 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -88,9 +88,10 @@ class TypeCheckMethodCallExpr : private TyVisitor
public:
// Resolve the Method parameters and return back the return type
static BaseType *go (BaseType *ref, HIR::MethodCallExpr &call,
+ TyTy::BaseType *adjusted_self,
Resolver::TypeCheckContext *context)
{
- TypeCheckMethodCallExpr checker (call, context);
+ TypeCheckMethodCallExpr checker (call, adjusted_self, context);
ref->accept_vis (checker);
return checker.resolved;
}
@@ -125,13 +126,15 @@ public:
private:
TypeCheckMethodCallExpr (HIR::MethodCallExpr &c,
+ TyTy::BaseType *adjusted_self,
Resolver::TypeCheckContext *context)
- : resolved (nullptr), call (c), context (context),
- mappings (Analysis::Mappings::get ())
+ : resolved (nullptr), call (c), adjusted_self (adjusted_self),
+ context (context), mappings (Analysis::Mappings::get ())
{}
BaseType *resolved;
HIR::MethodCallExpr &call;
+ TyTy::BaseType *adjusted_self;
Resolver::TypeCheckContext *context;
Analysis::Mappings *mappings;
};
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 378416f..add4dbe 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2786,6 +2786,8 @@ TypeCheckCallExpr::visit (FnPtr &type)
void
TypeCheckMethodCallExpr::visit (FnType &type)
{
+ adjusted_self->unify (type.get_self_type ());
+
// +1 for the receiver self
size_t num_args_to_call = call.num_params () + 1;
if (num_args_to_call != type.num_params ())
diff --git a/gcc/testsuite/rust/compile/torture/issue-808.rs b/gcc/testsuite/rust/compile/torture/issue-808.rs
new file mode 100644
index 0000000..bfbf774
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-808.rs
@@ -0,0 +1,23 @@
+pub trait Foo {
+ type Target;
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+ fn bar(&self) -> &Self::Target;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .Foo::bar." "" { target *-*-* } .-2 }
+}
+
+impl<T> Foo for &T {
+ type Target = T;
+
+ fn bar(&self) -> &T {
+ *self
+ }
+}
+
+pub fn main() {
+ let a: i32 = 123;
+ let b: &i32 = &a;
+
+ b.bar();
+}