aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.h2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h7
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc106
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc9
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h5
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc31
-rw-r--r--gcc/rust/typecheck/rust-tyty.h15
-rw-r--r--gcc/testsuite/rust/compile/issue-1173.rs20
9 files changed, 96 insertions, 107 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index 84096ce..aa3e29a 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -262,6 +262,8 @@ public:
std::vector<PathExprSegment> &get_segments () { return segments; }
+ const std::vector<PathExprSegment> &get_segments () const { return segments; }
+
PathExprSegment &get_root_seg () { return segments.at (0); }
PathExprSegment get_final_segment () const { return segments.back (); }
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 4920e2b..7284633 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -169,13 +169,8 @@ public:
return CanonicalPath::create_empty ();
}
- std::string generics
- = ResolveTypeToCanonicalPath::canonicalize_generic_args (
- seg.get_generic_args ());
-
return CanonicalPath::new_seg (seg.get_node_id (),
- seg.get_ident_segment ().as_string ()
- + "::" + generics);
+ seg.get_ident_segment ().as_string ());
}
};
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 630eb60..5633751 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -221,13 +221,6 @@ public:
infered
= TyTy::TypeCheckCallExpr::go (function_tyty, expr, variant, context);
- if (infered == nullptr)
- {
- rust_error_at (expr.get_locus (), "failed to lookup type to CallExpr");
- return;
- }
-
- infered->set_ref (expr.get_mappings ().get_hirid ());
}
void visit (HIR::MethodCallExpr &expr) override
@@ -1076,7 +1069,6 @@ private:
: TypeCheckBase (), infered (nullptr), inside_loop (inside_loop)
{}
- // Beware: currently returns Tyty::ErrorType or nullptr in case of error.
TyTy::BaseType *resolve_root_path (HIR::PathInExpression &expr,
size_t *offset,
NodeId *root_resolved_node_id);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 530f630..9960e76 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -138,27 +138,17 @@ void
TypeCheckExpr::visit (HIR::PathInExpression &expr)
{
NodeId resolved_node_id = UNKNOWN_NODEID;
-
size_t offset = -1;
TyTy::BaseType *tyseg = resolve_root_path (expr, &offset, &resolved_node_id);
- rust_assert (tyseg != nullptr);
-
if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
return;
- if (expr.get_num_segments () == 1)
- {
- Location locus = expr.get_segments ().back ().get_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);
- }
+ if (tyseg->needs_generic_substitutions ())
+ tyseg = SubstMapper::InferSubst (tyseg, expr.get_locus ());
+ bool fully_resolved = offset == expr.get_segments ().size ();
+ if (fully_resolved)
+ {
infered = tyseg;
return;
}
@@ -171,14 +161,11 @@ TyTy::BaseType *
TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
NodeId *root_resolved_node_id)
{
- TyTy::BaseType *root_tyty = nullptr;
*offset = 0;
for (size_t i = 0; i < expr.get_num_segments (); i++)
{
HIR::PathExprSegment &seg = expr.get_segments ().at (i);
-
bool have_more_segments = (expr.get_num_segments () - 1 != i);
- bool is_root = *offset == 0 || root_tyty == nullptr;
NodeId ast_node_id = seg.get_mappings ().get_nodeid ();
// then lookup the reference_node_id
@@ -205,13 +192,9 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
// ref_node_id is the NodeId that the segments refers to.
if (ref_node_id == UNKNOWN_NODEID)
{
- if (is_root)
- {
- rust_error_at (seg.get_locus (),
- "failed to type resolve root segment");
- return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
- }
- return root_tyty;
+ rust_error_at (seg.get_locus (),
+ "failed to type resolve root segment");
+ return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
// node back to HIR
@@ -219,26 +202,20 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
ref_node_id, &ref))
{
- if (is_root)
- {
- rust_error_at (seg.get_locus (), "456 reverse lookup failure");
- rust_debug_loc (
- seg.get_locus (),
- "failure with [%s] mappings [%s] ref_node_id [%u]",
- seg.as_string ().c_str (),
- seg.get_mappings ().as_string ().c_str (), ref_node_id);
+ rust_error_at (seg.get_locus (), "456 reverse lookup failure");
+ rust_debug_loc (seg.get_locus (),
+ "failure with [%s] mappings [%s] ref_node_id [%u]",
+ seg.as_string ().c_str (),
+ seg.get_mappings ().as_string ().c_str (),
+ ref_node_id);
- return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
- }
-
- return root_tyty;
+ return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
auto seg_is_module
= (nullptr
!= mappings->lookup_module (expr.get_mappings ().get_crate_num (),
ref));
-
if (seg_is_module)
{
// A::B::C::this_is_a_module::D::E::F
@@ -261,33 +238,8 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
TyTy::BaseType *lookup = nullptr;
if (!context->lookup_type (ref, &lookup))
{
- if (is_root)
- {
- rust_error_at (seg.get_locus (),
- "failed to resolve root segment");
- return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
- }
- return root_tyty;
- }
-
- // if we have a previous segment type
- if (root_tyty != nullptr)
- {
- // if this next segment needs substitution we must apply the
- // previous type arguments
- //
- // such as: GenericStruct::<_>::new(123, 456)
- if (lookup->needs_generic_substitutions ())
- {
- if (!root_tyty->needs_generic_substitutions ())
- {
- auto used_args_in_prev_segment
- = GetUsedSubstArgs::From (root_tyty);
- lookup
- = SubstMapperInternal::Resolve (lookup,
- used_args_in_prev_segment);
- }
- }
+ rust_error_at (seg.get_locus (), "failed to resolve root segment");
+ return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
// turbo-fish segment path::<ty>
@@ -300,16 +252,16 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
lookup->as_string ().c_str ());
return new TyTy::ErrorType (lookup->get_ref ());
}
- lookup = SubstMapper::Resolve (lookup, expr.get_locus (),
+ lookup = SubstMapper::Resolve (lookup, seg.get_locus (),
&seg.get_generic_args ());
}
*root_resolved_node_id = ref_node_id;
*offset = *offset + 1;
- root_tyty = lookup;
+ return lookup;
}
- return root_tyty;
+ return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
void
@@ -424,19 +376,11 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
bool ok = context->lookup_type (impl_ty_id, &impl_block_ty);
rust_assert (ok);
- if (prev_segment->needs_generic_substitutions ())
- {
- if (!impl_block_ty->needs_generic_substitutions ())
- {
- prev_segment = impl_block_ty;
- }
- else
- {
- HIR::PathExprSegment &pseg = segments.at (i - 1);
- Location locus = pseg.get_locus ();
- prev_segment = SubstMapper::InferSubst (prev_segment, locus);
- }
- }
+ if (impl_block_ty->needs_generic_substitutions ())
+ impl_block_ty
+ = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+
+ prev_segment = prev_segment->unify (impl_block_ty);
}
if (tyseg->needs_generic_substitutions ())
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index b09ffc7..ee66638 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -54,18 +54,11 @@ TypeResolution::Resolve (HIR::Crate &crate)
// default inference variables if possible
context->iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
- if (ty->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (mappings->lookup_location (id),
- "failure in type resolution for %u", id);
- return false;
- }
-
// nothing to do
if (ty->get_kind () != TyTy::TypeKind::INFER)
return true;
- TyTy::InferType *infer_var = (TyTy::InferType *) ty;
+ TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
TyTy::BaseType *default_type;
bool ok = infer_var->default_type (&default_type);
if (!ok)
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index f95e7bf..1dd0112 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -89,6 +89,11 @@ public:
for (auto ref : other->get_combined_refs ())
resolved->append_reference (ref);
+ other->append_reference (resolved->get_ref ());
+ other->append_reference (get_base ()->get_ref ());
+ get_base ()->append_reference (resolved->get_ref ());
+ get_base ()->append_reference (other->get_ref ());
+
bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER;
bool results_is_non_general_infer_var
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index d9a4243..847ca88 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -263,6 +263,7 @@ TyVar::get_implicit_infer_var (Location locus)
infer);
mappings->insert_location (mappings->get_current_crate (), infer->get_ref (),
locus);
+
return TyVar (infer->get_ref ());
}
@@ -341,8 +342,34 @@ InferType::cast (BaseType *other)
BaseType *
InferType::clone () const
{
- return new InferType (get_ref (), get_ty_ref (), get_infer_kind (),
- get_ident ().locus, get_combined_refs ());
+ // clones for inference variables are special in that they _must_ exist within
+ // the type check context and we must ensure we don't loose the chain
+ // otherwise we will end up in the missing type annotations case
+ //
+ // This means we cannot simply take over the same reference we must generate a
+ // new ref just like the get_implicit_infer_var code then we can setup the
+ // chain of references accordingly to ensure we don't loose the ability to
+ // update the inference variables when we solve the type
+
+ auto mappings = Analysis::Mappings::get ();
+ auto context = Resolver::TypeCheckContext::get ();
+
+ InferType *clone
+ = new InferType (mappings->get_next_hir_id (), get_infer_kind (),
+ get_ident ().locus, get_combined_refs ());
+
+ context->insert_type (Analysis::NodeMapping (mappings->get_current_crate (),
+ UNKNOWN_NODEID,
+ clone->get_ref (),
+ UNKNOWN_LOCAL_DEFID),
+ clone);
+ mappings->insert_location (mappings->get_current_crate (), clone->get_ref (),
+ mappings->lookup_location (get_ref ()));
+
+ // setup the chain to reference this
+ clone->append_reference (get_ref ());
+
+ return clone;
}
bool
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 1f157c8..271ce2c 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -955,12 +955,23 @@ public:
BaseType *infer_substitions (Location locus)
{
std::vector<SubstitutionArg> args;
+ std::map<std::string, BaseType *> argument_mappings;
for (auto &p : get_substs ())
{
if (p.needs_substitution ())
{
- TyVar infer_var = TyVar::get_implicit_infer_var (locus);
- args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
+ const std::string &symbol = p.get_param_ty ()->get_symbol ();
+ auto it = argument_mappings.find (symbol);
+ if (it == argument_mappings.end ())
+ {
+ TyVar infer_var = TyVar::get_implicit_infer_var (locus);
+ args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
+ argument_mappings[symbol] = infer_var.get_tyty ();
+ }
+ else
+ {
+ args.push_back (SubstitutionArg (&p, it->second));
+ }
}
else
{
diff --git a/gcc/testsuite/rust/compile/issue-1173.rs b/gcc/testsuite/rust/compile/issue-1173.rs
new file mode 100644
index 0000000..b08d720
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1173.rs
@@ -0,0 +1,20 @@
+// { dg-additional-options "-w" }
+mod mem {
+ extern "rust-intrinsic" {
+ fn transmute<U, V>(_: U) -> V;
+ }
+}
+
+pub trait Hasher {
+ fn write(&mut self, bytes: &[u8]);
+ fn write_u16(&mut self, i: u16) {
+ self.write(&mem::transmute::<_, [u8; 2]>(i))
+ }
+}
+
+pub struct SipHasher;
+
+impl Hasher for SipHasher {
+ #[inline]
+ fn write(&mut self, msg: &[u8]) {}
+}