Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions gcc/rust/typecheck/rust-hir-type-check-path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,17 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
infered = new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
return;
}
std::vector<TyTy::Region> regions;
auto regions
= context->regions_from_generic_args (item_seg.get_generic_args ());
if (!regions.has_value ())
{
infered = new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
return;
}

infered = SubstMapper::Resolve (infered, expr.get_locus (),
&item_seg.get_generic_args (),
context->regions_from_generic_args (
item_seg.get_generic_args ()));
regions.value ());
}

// continue on as a path-in-expression
Expand Down Expand Up @@ -366,10 +371,14 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
// turbo-fish segment path::<ty>
if (seg.has_generic_args ())
{
lookup = SubstMapper::Resolve (lookup, expr.get_locus (),
&seg.get_generic_args (),
context->regions_from_generic_args (
seg.get_generic_args ()));
auto regions
= context->regions_from_generic_args (seg.get_generic_args ());
if (!regions.has_value ())
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());

lookup
= SubstMapper::Resolve (lookup, expr.get_locus (),
&seg.get_generic_args (), regions.value ());
if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
Expand Down Expand Up @@ -526,10 +535,14 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
{
rust_debug_loc (seg.get_locus (), "applying segment generics: %s",
tyseg->as_string ().c_str ());
auto regions
= context->regions_from_generic_args (seg.get_generic_args ());
if (!regions.has_value ())
return;

tyseg
= SubstMapper::Resolve (tyseg, expr_locus, &seg.get_generic_args (),
context->regions_from_generic_args (
seg.get_generic_args ()));
regions.value ());
if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
return;
}
Expand Down
33 changes: 24 additions & 9 deletions gcc/rust/typecheck/rust-hir-type-check-type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -301,11 +301,17 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
= new TyTy::ErrorType (path.get_mappings ().get_hirid ());
return;
}
translated
= SubstMapper::Resolve (translated, path.get_locus (),
&generic_seg.get_generic_args (),
context->regions_from_generic_args (
generic_seg.get_generic_args ()));
auto regions = context->regions_from_generic_args (
generic_seg.get_generic_args ());
if (!regions.has_value ())
{
translated
= new TyTy::ErrorType (path.get_mappings ().get_hirid ());
return;
}
translated = SubstMapper::Resolve (translated, path.get_locus (),
&generic_seg.get_generic_args (),
regions.value ());
}
}

Expand Down Expand Up @@ -458,19 +464,22 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,

auto regions = context->regions_from_generic_args (
generic_segment.get_generic_args ());
if (!regions.has_value ())
return new TyTy::ErrorType (seg->get_mappings ().get_hirid ());

lookup = SubstMapper::Resolve (lookup, path.get_locus (),
&generic_segment.get_generic_args (),
regions);
regions.value ());
if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (seg->get_mappings ().get_hirid ());
}
else if (lookup->needs_generic_substitutions ())
{
HIR::GenericArgs empty
= HIR::GenericArgs::create_empty (path.get_locus ());
lookup
= SubstMapper::Resolve (lookup, path.get_locus (), &empty,
context->regions_from_generic_args (empty));
lookup = SubstMapper::Resolve (
lookup, path.get_locus (), &empty,
context->regions_from_generic_args (empty).value ());
}

*offset = *offset + 1;
Expand Down Expand Up @@ -760,6 +769,12 @@ void
TypeCheckType::visit (HIR::ReferenceType &type)
{
TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ());
if (base->is<TyTy::ErrorType> ())
{
translated = new TyTy::ErrorType (type.get_mappings ().get_hirid ());
return;
}

rust_assert (type.has_lifetime ());
auto region = context->lookup_and_resolve_lifetime (type.get_lifetime ());
if (!region.has_value ())
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/typecheck/rust-hir-type-check.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ class TypeCheckContext

void intern_and_insert_lifetime (const HIR::Lifetime &lifetime);

WARN_UNUSED_RESULT std::vector<TyTy::Region>
WARN_UNUSED_RESULT tl::optional<std::vector<TyTy::Region>>
regions_from_generic_args (const HIR::GenericArgs &args) const;

void compute_inference_variables (bool emit_error);
Expand Down
4 changes: 2 additions & 2 deletions gcc/rust/typecheck/rust-typecheck-context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
}

WARN_UNUSED_RESULT std::vector<TyTy::Region>
WARN_UNUSED_RESULT tl::optional<std::vector<TyTy::Region>>
TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
{
std::vector<TyTy::Region> regions;
Expand All @@ -608,7 +608,7 @@ TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
if (!resolved)
{
rust_error_at (lifetime.get_locus (), "unresolved lifetime");
return {};
return tl::nullopt;
}
regions.push_back (*resolved);
}
Expand Down
12 changes: 8 additions & 4 deletions gcc/rust/typecheck/rust-tyty-bounds.cc
Original file line number Diff line number Diff line change
Expand Up @@ -538,10 +538,14 @@ TypeBoundPredicate::apply_generic_arguments (HIR::GenericArgs *generic_args,
}

// now actually perform a substitution
auto args = get_mappings_from_generic_args (
*generic_args,
Resolver::TypeCheckContext::get ()->regions_from_generic_args (
*generic_args));
auto regions = Resolver::TypeCheckContext::get ()->regions_from_generic_args (
*generic_args);
if (!regions.has_value ())
{
error_flag = true;
return;
}
auto args = get_mappings_from_generic_args (*generic_args, regions.value ());

apply_argument_mappings (args, is_super_trait);
}
Expand Down
14 changes: 14 additions & 0 deletions gcc/testsuite/rust/compile/invalid-lifetime-in-generic-arg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![feature(no_core)]
#![no_core]

// Test for segfault when processing enum variant with reference to type
// with unresolved lifetime in generic arguments.
// The compiler should report an error gracefully instead of crashing.

enum ast<'a> {
num(usize),
add(&'a ast<'result>) // { dg-error "failed to resolve type path segment" }
// { dg-error "unresolved lifetime" "" { target *-*-* } .-1 }
}

pub fn main() {}
Loading