Skip to content

Commit 011e79d

Browse files
committed
Generic pointers are coerceable WIP Fixes #1930
1 parent 2f46572 commit 011e79d

File tree

9 files changed

+189
-50
lines changed

9 files changed

+189
-50
lines changed

gcc/rust/backend/rust-compile-expr.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "rust-compile-block.h"
2727
#include "rust-compile-implitem.h"
2828
#include "rust-constexpr.h"
29-
#include "rust-unify.h"
29+
#include "rust-type-util.h"
3030
#include "rust-gcc.h"
3131

3232
#include "fold-const.h"
@@ -2007,10 +2007,9 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
20072007
{
20082008
TyTy::BaseType *infer_impl_call
20092009
= candidate_call->infer_substitions (expr_locus);
2010-
monomorphized = Resolver::UnifyRules::Resolve (
2011-
TyTy::TyWithLocation (infer_impl_call),
2012-
TyTy::TyWithLocation (fntype), expr_locus, true /* commit */,
2013-
true /* emit_errors */);
2010+
monomorphized
2011+
= Resolver::unify_site (ref, TyTy::TyWithLocation (infer_impl_call),
2012+
TyTy::TyWithLocation (fntype), expr_locus);
20142013
}
20152014

20162015
return CompileInherentImplItem::Compile (impl_item, ctx, monomorphized);

gcc/rust/typecheck/rust-coercion.cc

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
#include "rust-hir-type-check-base.h"
2020
#include "rust-coercion.h"
21-
#include "rust-unify.h"
21+
#include "rust-type-util.h"
2222

2323
namespace Rust {
2424
namespace Resolver {
@@ -146,7 +146,7 @@ TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
146146
TyTy::PointerType *expected,
147147
Mutability to_mutbl)
148148
{
149-
rust_debug ("coerce_unsafe_ptr(a={%s}, b={%s})",
149+
rust_debug ("coerce_unsafe_ptr(receiver={%s}, expected={%s})",
150150
receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
151151

152152
Mutability from_mutbl = Mutability::Imm;
@@ -184,13 +184,29 @@ TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
184184
return TypeCoercionRules::CoercionResult::get_error ();
185185
}
186186

187-
TyTy::PointerType *result
187+
expected->get_base ()->debug ();
188+
element->debug ();
189+
190+
rust_debug ("expected->is_concrete: %s",
191+
expected->is_concrete () ? "true" : "false");
192+
rust_debug ("element->is_concrete: %s",
193+
element->is_concrete () ? "true" : "false");
194+
195+
TyTy::PointerType *coerced_mutability
188196
= new TyTy::PointerType (receiver->get_ref (),
189197
TyTy::TyVar (element->get_ref ()), to_mutbl);
190-
if (!result->can_eq (expected, false))
191-
return CoercionResult::get_error ();
192198

193-
return CoercionResult{{}, result};
199+
TyTy::BaseType *result
200+
= unify_site_and (receiver->get_ref (), TyTy::TyWithLocation (expected),
201+
TyTy::TyWithLocation (coerced_mutability),
202+
Location () /*unify_locus*/, false /*emit_errors*/,
203+
true /*commit_if_ok*/, true /*infer*/,
204+
true /*cleanup on error*/);
205+
bool unsafe_ptr_coerceion_ok = result->get_kind () != TyTy::TypeKind::ERROR;
206+
if (unsafe_ptr_coerceion_ok)
207+
return CoercionResult{{}, result};
208+
209+
return TypeCoercionRules::CoercionResult::get_error ();
194210
}
195211

196212
/// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
@@ -220,9 +236,8 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver,
220236
// back to a final unity anyway
221237
rust_debug ("coerce_borrowed_pointer -- unify");
222238
TyTy::BaseType *result
223-
= UnifyRules::Resolve (TyTy::TyWithLocation (receiver),
224-
TyTy::TyWithLocation (expected), locus,
225-
true /* commit */, true /* emit_errors */);
239+
= unify_site (receiver->get_ref (), TyTy::TyWithLocation (receiver),
240+
TyTy::TyWithLocation (expected), locus);
226241
return CoercionResult{{}, result};
227242
}
228243
}

gcc/rust/typecheck/rust-hir-type-check.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class TypeCheckContext
8484
TyTy::BaseType *type);
8585
void insert_implicit_type (TyTy::BaseType *type);
8686
bool lookup_type (HirId id, TyTy::BaseType **type) const;
87+
void clear_type (TyTy::BaseType *ty);
8788

8889
void insert_implicit_type (HirId id, TyTy::BaseType *type);
8990

gcc/rust/typecheck/rust-type-util.cc

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,57 @@ unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
117117
rust_debug ("unify_site id={%u} expected={%s} expr={%s}", id,
118118
expected->debug_str ().c_str (), expr->debug_str ().c_str ());
119119

120+
std::vector<UnifyRules::CommitSite> commits;
121+
std::vector<UnifyRules::InferenceSite> infers;
120122
return UnifyRules::Resolve (lhs, rhs, unify_locus, true /*commit*/,
121-
true /*emit_error*/);
123+
true /*emit_error*/, false /*infer*/, commits,
124+
infers);
125+
}
126+
127+
TyTy::BaseType *
128+
unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
129+
Location unify_locus, bool emit_errors, bool commit_if_ok,
130+
bool implicit_infer_vars, bool cleanup)
131+
{
132+
TypeCheckContext &context = *TypeCheckContext::get ();
133+
134+
TyTy::BaseType *expected = lhs.get_ty ();
135+
TyTy::BaseType *expr = rhs.get_ty ();
136+
137+
rust_debug (
138+
"unify_site_and commit %s infer %s id={%u} expected={%s} expr={%s}",
139+
commit_if_ok ? "true" : "false", implicit_infer_vars ? "true" : "false", id,
140+
expected->debug_str ().c_str (), expr->debug_str ().c_str ());
141+
142+
std::vector<UnifyRules::CommitSite> commits;
143+
std::vector<UnifyRules::InferenceSite> infers;
144+
TyTy::BaseType *result
145+
= UnifyRules::Resolve (lhs, rhs, unify_locus, false /*commit inline*/,
146+
emit_errors, implicit_infer_vars, commits, infers);
147+
bool ok = result->get_kind () != TyTy::TypeKind::ERROR;
148+
if (ok && commit_if_ok)
149+
{
150+
for (auto &c : commits)
151+
{
152+
UnifyRules::commit (c.lhs, c.rhs, c.resolved);
153+
}
154+
}
155+
else if (cleanup)
156+
{
157+
// FIXME
158+
// reset the get_next_hir_id
159+
160+
for (auto &i : infers)
161+
{
162+
i.param->set_ref (i.pref);
163+
i.param->set_ty_ref (i.ptyref);
164+
165+
// remove the inference variable
166+
context.clear_type (i.infer);
167+
delete i.infer;
168+
}
169+
}
170+
return result;
122171
}
123172

124173
TyTy::BaseType *

gcc/rust/typecheck/rust-type-util.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,18 @@ class BaseType;
3030

3131
namespace Resolver {
3232

33-
extern bool
33+
bool
3434
query_type (HirId reference, TyTy::BaseType **result);
3535

3636
TyTy::BaseType *
3737
unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
3838
Location unify_locus);
3939

40+
TyTy::BaseType *
41+
unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
42+
Location unify_locus, bool emit_errors, bool commit_if_ok,
43+
bool implicit_infer_vars, bool cleanup);
44+
4045
TyTy::BaseType *
4146
coercion_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
4247
Location coercion_locus);

gcc/rust/typecheck/rust-typecheck-context.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
108108
return true;
109109
}
110110

111+
void
112+
TypeCheckContext::clear_type (TyTy::BaseType *ty)
113+
{
114+
auto it = resolved.find (ty->get_ref ());
115+
if (it == resolved.end ())
116+
return;
117+
118+
resolved.erase (it);
119+
}
120+
111121
void
112122
TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
113123
{

0 commit comments

Comments
 (0)