]> git.ipfire.org Git - people/ms/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)
committerPhilip Herron <philip.herron@embecosm.com>
Tue, 28 Feb 2023 20:38:35 +0000 (20:38 +0000)
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 d7945dbf26b5226c082980b3d07a931cad344100..200f3a2a07e4ecc9341e1356f1462e3a2b064122 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 bea40840fbffc028739930a9a89a6be8fd79f10f..fdc8bdd7acb2214db2579906ce0352fb63e97de4 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 6d4b9b8a62f52244cd39a0a63f0292932cfa350f..5c5623a0bf69da6ef461ecde28cc324e935348fb 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 dbd10366fd7257f973d5733a7cdf57d8fea24824..ff7c805c9436c4200115f6123fbe88ecacd2e04a 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 01333d8b984cadfe83cb3fdd327c51e0c50a781f..8ecba738ff44b5b32e6e038eda7868b97fab638c 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 27ff96986dcd4e0549a53f15351ae5828f202f6a..096ce26f1fa1e14a13041bbab328f95c019f7041 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 e96d6b70379b307127f1ffe4832c36f07fc619b9..37ef71ec22e782d97fe5ec4ce50a4b0cbd155bec 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 15672f1dcb949481b2c4a08adf561de085aa61ca..53acf21c7d4c56e4abe6a7b4232aecf97d554a6f 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;
+}