]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Generic pointers are coerceable
authorPhilip Herron <herron.philip@googlemail.com>
Sun, 26 Feb 2023 22:08:26 +0000 (22:08 +0000)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:19:00 +0000 (18:19 +0100)
This is a complex type-system change where it begins out journey to get
rid of our can_eq interface. Rust allows:

  let x:*mut T
  let y = x as *mut u8;

Which requires us to consider find a way to infer what T should be so as
to keep unify happy. This means we need to introduce a new unify_and
interface where we can optionally inject inference variables as well as
only commit the inference variable joins when they are sucsessful.

So for this case we can then inject an implicit inference variables for T
that can unify against u8 to make this a valid type-resolution.

Fixes #1930

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::resolve_method_address): update to new inteface
* typecheck/rust-coercion.cc (TypeCoercionRules::coerce_unsafe_ptr): likewise
(TypeCoercionRules::coerce_borrowed_pointer): likewise
* typecheck/rust-hir-type-check.h: likewise
* typecheck/rust-type-util.cc (unify_site_and): new interface to allow for infer and commit
* typecheck/rust-type-util.h (unify_site_and): likewise
* typecheck/rust-typecheck-context.cc (TypeCheckContext::clear_type): new interface
* typecheck/rust-unify.cc (UnifyRules::UnifyRules): update
(UnifyRules::Resolve): new optional flags for commit and infer
(UnifyRules::go): likewise
(UnifyRules::expect_adt): refactor to use new interface
(UnifyRules::expect_reference): likewise
(UnifyRules::expect_pointer): likewise
(UnifyRules::expect_array): likewise
(UnifyRules::expect_slice): likewise
(UnifyRules::expect_fndef): likewise
(UnifyRules::expect_fnptr): likewise
(UnifyRules::expect_tuple): likewise
(UnifyRules::expect_closure): likewise
* typecheck/rust-unify.h: refactor interface

gcc/testsuite/ChangeLog:

* rust/compile/issue-1930.rs: New test.

gcc/rust/backend/rust-compile-expr.cc
gcc/rust/typecheck/rust-coercion.cc
gcc/rust/typecheck/rust-hir-type-check.h
gcc/rust/typecheck/rust-type-util.cc
gcc/rust/typecheck/rust-type-util.h
gcc/rust/typecheck/rust-typecheck-context.cc
gcc/rust/typecheck/rust-unify.cc
gcc/rust/typecheck/rust-unify.h
gcc/testsuite/rust/compile/issue-1930.rs [new file with mode: 0644]

index 731928af7a896c08ea2d63f13eaaac10e4b15c06..1a98f4ac98b18b9533b05290eeb0eeadd29e54b8 100644 (file)
@@ -26,7 +26,7 @@
 #include "rust-compile-block.h"
 #include "rust-compile-implitem.h"
 #include "rust-constexpr.h"
-#include "rust-unify.h"
+#include "rust-type-util.h"
 #include "rust-gcc.h"
 
 #include "fold-const.h"
@@ -2007,10 +2007,9 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
        {
          TyTy::BaseType *infer_impl_call
            = candidate_call->infer_substitions (expr_locus);
-         monomorphized = Resolver::UnifyRules::Resolve (
-           TyTy::TyWithLocation (infer_impl_call),
-           TyTy::TyWithLocation (fntype), expr_locus, true /* commit */,
-           true /* emit_errors */);
+         monomorphized
+           = Resolver::unify_site (ref, TyTy::TyWithLocation (infer_impl_call),
+                                   TyTy::TyWithLocation (fntype), expr_locus);
        }
 
       return CompileInherentImplItem::Compile (impl_item, ctx, monomorphized);
index 3a3f13a679c124feb39d065e583e4bc16e895fdc..24f60d84080a54d3d38591c6331506819baa4f32 100644 (file)
@@ -18,7 +18,7 @@
 
 #include "rust-hir-type-check-base.h"
 #include "rust-coercion.h"
-#include "rust-unify.h"
+#include "rust-type-util.h"
 
 namespace Rust {
 namespace Resolver {
@@ -146,7 +146,7 @@ TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
                                      TyTy::PointerType *expected,
                                      Mutability to_mutbl)
 {
-  rust_debug ("coerce_unsafe_ptr(a={%s}, b={%s})",
+  rust_debug ("coerce_unsafe_ptr(receiver={%s}, expected={%s})",
              receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
 
   Mutability from_mutbl = Mutability::Imm;
@@ -184,13 +184,21 @@ TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
       return TypeCoercionRules::CoercionResult::get_error ();
     }
 
-  TyTy::PointerType *result
+  TyTy::PointerType *coerced_mutability
     = new TyTy::PointerType (receiver->get_ref (),
                             TyTy::TyVar (element->get_ref ()), to_mutbl);
-  if (!result->can_eq (expected, false))
-    return CoercionResult::get_error ();
 
-  return CoercionResult{{}, result};
+  TyTy::BaseType *result
+    = unify_site_and (receiver->get_ref (), TyTy::TyWithLocation (expected),
+                     TyTy::TyWithLocation (coerced_mutability),
+                     Location () /*unify_locus*/, false /*emit_errors*/,
+                     true /*commit_if_ok*/, true /*infer*/,
+                     true /*cleanup on error*/);
+  bool unsafe_ptr_coerceion_ok = result->get_kind () != TyTy::TypeKind::ERROR;
+  if (unsafe_ptr_coerceion_ok)
+    return CoercionResult{{}, result};
+
+  return TypeCoercionRules::CoercionResult::get_error ();
 }
 
 /// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
@@ -220,9 +228,8 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver,
        // back to a final unity anyway
        rust_debug ("coerce_borrowed_pointer -- unify");
        TyTy::BaseType *result
-         = UnifyRules::Resolve (TyTy::TyWithLocation (receiver),
-                                TyTy::TyWithLocation (expected), locus,
-                                true /* commit */, true /* emit_errors */);
+         = unify_site (receiver->get_ref (), TyTy::TyWithLocation (receiver),
+                       TyTy::TyWithLocation (expected), locus);
        return CoercionResult{{}, result};
       }
     }
index 5fec7d53165e02dc8b59d27ab0202049203cac3e..2cd58988a75f07f7aab90cbea213d223e7b6dc18 100644 (file)
@@ -84,6 +84,7 @@ public:
                    TyTy::BaseType *type);
   void insert_implicit_type (TyTy::BaseType *type);
   bool lookup_type (HirId id, TyTy::BaseType **type) const;
+  void clear_type (TyTy::BaseType *ty);
 
   void insert_implicit_type (HirId id, TyTy::BaseType *type);
 
index 0c688351fe98c827c8026b8fd193a8a6ddf7af66..4d6b026c36537b4a69e34323d25d81649e3f1485 100644 (file)
@@ -117,8 +117,57 @@ unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
   rust_debug ("unify_site id={%u} expected={%s} expr={%s}", id,
              expected->debug_str ().c_str (), expr->debug_str ().c_str ());
 
+  std::vector<UnifyRules::CommitSite> commits;
+  std::vector<UnifyRules::InferenceSite> infers;
   return UnifyRules::Resolve (lhs, rhs, unify_locus, true /*commit*/,
-                             true /*emit_error*/);
+                             true /*emit_error*/, false /*infer*/, commits,
+                             infers);
+}
+
+TyTy::BaseType *
+unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
+               Location unify_locus, bool emit_errors, bool commit_if_ok,
+               bool implicit_infer_vars, bool cleanup)
+{
+  TypeCheckContext &context = *TypeCheckContext::get ();
+
+  TyTy::BaseType *expected = lhs.get_ty ();
+  TyTy::BaseType *expr = rhs.get_ty ();
+
+  rust_debug (
+    "unify_site_and commit %s infer %s id={%u} expected={%s} expr={%s}",
+    commit_if_ok ? "true" : "false", implicit_infer_vars ? "true" : "false", id,
+    expected->debug_str ().c_str (), expr->debug_str ().c_str ());
+
+  std::vector<UnifyRules::CommitSite> commits;
+  std::vector<UnifyRules::InferenceSite> infers;
+  TyTy::BaseType *result
+    = UnifyRules::Resolve (lhs, rhs, unify_locus, false /*commit inline*/,
+                          emit_errors, implicit_infer_vars, commits, infers);
+  bool ok = result->get_kind () != TyTy::TypeKind::ERROR;
+  if (ok && commit_if_ok)
+    {
+      for (auto &c : commits)
+       {
+         UnifyRules::commit (c.lhs, c.rhs, c.resolved);
+       }
+    }
+  else if (cleanup)
+    {
+      // FIXME
+      // reset the get_next_hir_id
+
+      for (auto &i : infers)
+       {
+         i.param->set_ref (i.pref);
+         i.param->set_ty_ref (i.ptyref);
+
+         // remove the inference variable
+         context.clear_type (i.infer);
+         delete i.infer;
+       }
+    }
+  return result;
 }
 
 TyTy::BaseType *
index 4fac34a45a28a4be6f859efc973e9844cee69bad..d2523fc442085487ad9b4594c895e991544be070 100644 (file)
@@ -30,13 +30,18 @@ class BaseType;
 
 namespace Resolver {
 
-extern bool
+bool
 query_type (HirId reference, TyTy::BaseType **result);
 
 TyTy::BaseType *
 unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
            Location unify_locus);
 
+TyTy::BaseType *
+unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
+               Location unify_locus, bool emit_errors, bool commit_if_ok,
+               bool implicit_infer_vars, bool cleanup);
+
 TyTy::BaseType *
 coercion_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
               Location coercion_locus);
index 030c82630e2cf4cec89eac7325ba77d1f61ee9fa..04135e7115d1f84139da0f87f4c2dc9968d1da43 100644 (file)
@@ -108,6 +108,16 @@ TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
   return true;
 }
 
+void
+TypeCheckContext::clear_type (TyTy::BaseType *ty)
+{
+  auto it = resolved.find (ty->get_ref ());
+  if (it == resolved.end ())
+    return;
+
+  resolved.erase (it);
+}
+
 void
 TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
 {
index d2d8ef5ce64dd880d45d3f3a2349d961c4fc9c3c..4a9290c27371ac5e95103dcb8ddb4c8af7f10c38 100644 (file)
@@ -22,19 +22,26 @@ namespace Rust {
 namespace Resolver {
 
 UnifyRules::UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
-                       Location locus, bool commit_flag, bool emit_error)
+                       Location locus, bool commit_flag, bool emit_error,
+                       bool infer, std::vector<CommitSite> &commits,
+                       std::vector<InferenceSite> &infers)
   : lhs (lhs), rhs (rhs), locus (locus), commit_flag (commit_flag),
-    emit_error (emit_error), mappings (*Analysis::Mappings::get ()),
+    emit_error (emit_error), infer_flag (infer), commits (commits),
+    infers (infers), mappings (*Analysis::Mappings::get ()),
     context (*TypeCheckContext::get ())
 {}
 
 TyTy::BaseType *
 UnifyRules::Resolve (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
-                    Location locus, bool commit_flag, bool emit_error)
+                    Location locus, bool commit_flag, bool emit_error,
+                    bool infer, std::vector<CommitSite> &commits,
+                    std::vector<InferenceSite> &infers)
 {
-  UnifyRules r (lhs, rhs, locus, commit_flag, emit_error);
-  TyTy::BaseType *result = r.go ();
+  UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, commits,
+               infers);
 
+  TyTy::BaseType *result = r.go ();
+  commits.push_back ({lhs.get_ty (), rhs.get_ty (), result});
   if (r.commit_flag)
     UnifyRules::commit (lhs.get_ty (), rhs.get_ty (), result);
 
@@ -142,6 +149,28 @@ UnifyRules::go ()
        }
     }
 
+  // inject inference vars if required
+  bool got_param = rtype->get_kind () == TyTy::TypeKind::PARAM;
+  bool lhs_is_infer_var = ltype->get_kind () == TyTy::TypeKind::INFER;
+  bool expected_is_concrete = ltype->is_concrete () && !lhs_is_infer_var;
+  bool needs_infer = expected_is_concrete && got_param;
+  if (infer_flag && needs_infer)
+    {
+      TyTy::ParamType *p = static_cast<TyTy::ParamType *> (rtype);
+      TyTy::TyVar iv = TyTy::TyVar::get_implicit_infer_var (rhs.get_locus ());
+      rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER);
+      TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ());
+
+      infers.push_back ({p->get_ref (), p->get_ty_ref (), p, i});
+
+      // FIXME
+      // this is hacky to set the implicit param lets make this a function
+      p->set_ty_ref (i->get_ref ());
+
+      // set the rtype now to the new inference var
+      rtype = i;
+    }
+
   switch (ltype->get_kind ())
     {
     case TyTy::INFER:
@@ -367,7 +396,8 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
                  = UnifyRules::Resolve (TyTy::TyWithLocation (this_field_ty),
                                         TyTy::TyWithLocation (other_field_ty),
                                         locus, commit_flag,
-                                        false /* emit_error */);
+                                        false /* emit_error */, infer_flag,
+                                        commits, infers);
                if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
                  {
                    return new TyTy::ErrorType (0);
@@ -392,7 +422,8 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
                auto res
                  = UnifyRules::Resolve (TyTy::TyWithLocation (pa),
                                         TyTy::TyWithLocation (pb), locus,
-                                        commit_flag, false /* emit_error */);
+                                        commit_flag, false /* emit_error */,
+                                        infer_flag, commits, infers);
                if (res->get_kind () == TyTy::TypeKind::ERROR)
                  {
                    return new TyTy::ErrorType (0);
@@ -497,7 +528,8 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
        TyTy::BaseType *base_resolved
          = UnifyRules::Resolve (TyTy::TyWithLocation (base_type),
                                 TyTy::TyWithLocation (other_base_type), locus,
-                                commit_flag, false /* emit_error */);
+                                commit_flag, false /* emit_error */,
+                                infer_flag, commits, infers);
        if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
          {
            return new TyTy::ErrorType (0);
@@ -566,7 +598,8 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
        TyTy::BaseType *base_resolved
          = UnifyRules::Resolve (TyTy::TyWithLocation (base_type),
                                 TyTy::TyWithLocation (other_base_type), locus,
-                                commit_flag, false /* emit_error */);
+                                commit_flag, false /* emit_error */,
+                                infer_flag, commits, infers);
        if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
          {
            return new TyTy::ErrorType (0);
@@ -693,7 +726,7 @@ UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
        TyTy::BaseType *element_unify = UnifyRules::Resolve (
          TyTy::TyWithLocation (ltype->get_element_type ()),
          TyTy::TyWithLocation (type.get_element_type ()), locus, commit_flag,
-         false /* emit_error*/);
+         false /* emit_error*/, infer_flag, commits, infers);
 
        if (element_unify->get_kind () != TyTy::TypeKind::ERROR)
          {
@@ -752,7 +785,7 @@ UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
        TyTy::BaseType *element_unify = UnifyRules::Resolve (
          TyTy::TyWithLocation (ltype->get_element_type ()),
          TyTy::TyWithLocation (type.get_element_type ()), locus, commit_flag,
-         false /* emit_error*/);
+         false /* emit_error*/, infer_flag, commits, infers);
 
        if (element_unify->get_kind () != TyTy::TypeKind::ERROR)
          {
@@ -820,18 +853,18 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
            auto unified_param
              = UnifyRules::Resolve (TyTy::TyWithLocation (a),
                                     TyTy::TyWithLocation (b), locus,
-                                    commit_flag, false /* emit_errors */);
+                                    commit_flag, false /* emit_errors */,
+                                    infer_flag, commits, infers);
            if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
              {
                return new TyTy::ErrorType (0);
              }
          }
 
-       auto unified_return
-         = UnifyRules::Resolve (TyTy::TyWithLocation (
-                                  ltype->get_return_type ()),
-                                TyTy::TyWithLocation (type.get_return_type ()),
-                                locus, commit_flag, false /* emit_errors */);
+       auto unified_return = UnifyRules::Resolve (
+         TyTy::TyWithLocation (ltype->get_return_type ()),
+         TyTy::TyWithLocation (type.get_return_type ()), locus, commit_flag,
+         false /* emit_errors */, infer_flag, commits, infers);
        if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
          {
            return new TyTy::ErrorType (0);
@@ -897,18 +930,18 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
            auto unified_param
              = UnifyRules::Resolve (TyTy::TyWithLocation (a),
                                     TyTy::TyWithLocation (b), locus,
-                                    commit_flag, false /* emit_errors */);
+                                    commit_flag, false /* emit_errors */,
+                                    infer_flag, commits, infers);
            if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
              {
                return new TyTy::ErrorType (0);
              }
          }
 
-       auto unified_return
-         = UnifyRules::Resolve (TyTy::TyWithLocation (
-                                  ltype->get_return_type ()),
-                                TyTy::TyWithLocation (type.get_return_type ()),
-                                locus, commit_flag, false /* emit_errors */);
+       auto unified_return = UnifyRules::Resolve (
+         TyTy::TyWithLocation (ltype->get_return_type ()),
+         TyTy::TyWithLocation (type.get_return_type ()), locus, commit_flag,
+         false /* emit_errors */, infer_flag, commits, infers);
        if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
          {
            return new TyTy::ErrorType (0);
@@ -926,7 +959,8 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
        auto unified_result
          = UnifyRules::Resolve (TyTy::TyWithLocation (this_ret_type),
                                 TyTy::TyWithLocation (other_ret_type), locus,
-                                commit_flag, false /*emit_errors*/);
+                                commit_flag, false /*emit_errors*/, infer_flag,
+                                commits, infers);
        if (unified_result->get_kind () == TyTy::TypeKind::ERROR)
          {
            return new TyTy::ErrorType (0);
@@ -945,7 +979,8 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
            auto unified_param
              = UnifyRules::Resolve (TyTy::TyWithLocation (this_param),
                                     TyTy::TyWithLocation (other_param), locus,
-                                    commit_flag, false /* emit_errors */);
+                                    commit_flag, false /* emit_errors */,
+                                    infer_flag, commits, infers);
            if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
              {
                return new TyTy::ErrorType (0);
@@ -1012,7 +1047,8 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
            TyTy::BaseType *unified_ty
              = UnifyRules::Resolve (TyTy::TyWithLocation (bo),
                                     TyTy::TyWithLocation (fo), locus,
-                                    commit_flag, false /* emit_errors */);
+                                    commit_flag, false /* emit_errors */,
+                                    infer_flag, commits, infers);
            if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
              return new TyTy::ErrorType (0);
 
@@ -1604,11 +1640,10 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
            return new TyTy::ErrorType (0);
          }
 
-       TyTy::BaseType *args_res
-         = UnifyRules::Resolve (TyTy::TyWithLocation (
-                                  &ltype->get_parameters ()),
-                                TyTy::TyWithLocation (&type.get_parameters ()),
-                                locus, commit_flag, false /* emit_error */);
+       TyTy::BaseType *args_res = UnifyRules::Resolve (
+         TyTy::TyWithLocation (&ltype->get_parameters ()),
+         TyTy::TyWithLocation (&type.get_parameters ()), locus, commit_flag,
+         false /* emit_error */, infer_flag, commits, infers);
        if (args_res->get_kind () == TyTy::TypeKind::ERROR)
          {
            return new TyTy::ErrorType (0);
@@ -1617,7 +1652,7 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
        TyTy::BaseType *res = UnifyRules::Resolve (
          TyTy::TyWithLocation (&ltype->get_result_type ()),
          TyTy::TyWithLocation (&type.get_result_type ()), locus, commit_flag,
-         false /* emit_error */);
+         false /* emit_error */, infer_flag, commits, infers);
        if (res == nullptr || res->get_kind () == TyTy::TypeKind::ERROR)
          {
            return new TyTy::ErrorType (0);
index dcd15839d5b5bdc135ee942f9ebb6e599d25ba5d..fecb21ec1e7ca81f054feb98225104cd29512f58 100644 (file)
@@ -28,9 +28,25 @@ namespace Resolver {
 class UnifyRules
 {
 public:
+  struct InferenceSite
+  {
+    HirId pref;
+    HirId ptyref;
+    TyTy::ParamType *param;
+    TyTy::InferType *infer;
+  };
+  struct CommitSite
+  {
+    TyTy::BaseType *lhs;
+    TyTy::BaseType *rhs;
+    TyTy::BaseType *resolved;
+  };
+
   static TyTy::BaseType *Resolve (TyTy::TyWithLocation lhs,
                                  TyTy::TyWithLocation rhs, Location locus,
-                                 bool commit_flag, bool emit_error);
+                                 bool commit_flag, bool emit_error, bool infer,
+                                 std::vector<CommitSite> &commits,
+                                 std::vector<InferenceSite> &infers);
 
   static void commit (TyTy::BaseType *base, TyTy::BaseType *other,
                      TyTy::BaseType *resolved);
@@ -69,7 +85,9 @@ protected:
 
 private:
   UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
-             Location locus, bool commit_flag, bool emit_error);
+             Location locus, bool commit_flag, bool emit_error, bool infer,
+             std::vector<CommitSite> &commits,
+             std::vector<InferenceSite> &infers);
 
   void emit_type_mismatch () const;
 
@@ -83,6 +101,9 @@ private:
   Location locus;
   bool commit_flag;
   bool emit_error;
+  bool infer_flag;
+  std::vector<CommitSite> &commits;
+  std::vector<InferenceSite> &infers;
 
   Analysis::Mappings &mappings;
   TypeCheckContext &context;
diff --git a/gcc/testsuite/rust/compile/issue-1930.rs b/gcc/testsuite/rust/compile/issue-1930.rs
new file mode 100644 (file)
index 0000000..ab30ccc
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-options "-w" }
+fn test<T>(x: *mut T) {
+    let x = x as *mut u8;
+}