From: Philip Herron <herron.phi...@googlemail.com> We need to check if the borrowed value is valid before creating the reference type. Otherwise this will lead to an ICE.
Fixes Rust-GCC#3140 gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): check for error * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): likewise and remove debug error gcc/testsuite/ChangeLog: * rust/compile/issue-3046.rs: remove old error message * rust/compile/nr2/exclude: nr2 cant handle this * rust/compile/issue-3140.rs: New test. Signed-off-by: Philip Herron <herron.phi...@googlemail.com> --- .../typecheck/rust-hir-type-check-expr.cc | 2 ++ gcc/rust/typecheck/rust-tyty-call.cc | 9 ++----- gcc/testsuite/rust/compile/issue-3046.rs | 4 +-- gcc/testsuite/rust/compile/issue-3140.rs | 27 +++++++++++++++++++ gcc/testsuite/rust/compile/nr2/exclude | 1 + 5 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/rust/compile/issue-3140.rs diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 5a96c359d7c..2ea8b4127e6 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -1366,6 +1366,8 @@ void TypeCheckExpr::visit (HIR::BorrowExpr &expr) { TyTy::BaseType *resolved_base = TypeCheckExpr::Resolve (expr.get_expr ()); + if (resolved_base->is<TyTy::ErrorType> ()) + return; // In Rust this is valid because of DST's // diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc index 5fea34de40a..2e0830e4ada 100644 --- a/gcc/rust/typecheck/rust-tyty-call.cc +++ b/gcc/rust/typecheck/rust-tyty-call.cc @@ -140,13 +140,8 @@ TypeCheckCallExpr::visit (FnType &type) { location_t arg_locus = argument->get_locus (); auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (*argument); - if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR) - { - rust_error_at ( - argument->get_locus (), - "failed to resolve type for argument expr in CallExpr"); - return; - } + if (argument_expr_tyty->is<TyTy::ErrorType> ()) + return; // it might be a variadic function if (i < type.num_params ()) diff --git a/gcc/testsuite/rust/compile/issue-3046.rs b/gcc/testsuite/rust/compile/issue-3046.rs index c982cc98f58..f0c72a3cef4 100644 --- a/gcc/testsuite/rust/compile/issue-3046.rs +++ b/gcc/testsuite/rust/compile/issue-3046.rs @@ -12,12 +12,10 @@ fn test(v: LOption) -> Res { return Res::BAD; } - fn main() { // Should be: // test(LOption::Some(2)); - // + // test(LOption(2)); // { dg-error "expected function, tuple struct or tuple variant, found enum" "" { target *-*-* } .-1 } - // { dg-error "failed to resolve type for argument expr in CallExpr" "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/compile/issue-3140.rs b/gcc/testsuite/rust/compile/issue-3140.rs new file mode 100644 index 00000000000..dcf86db5616 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3140.rs @@ -0,0 +1,27 @@ +enum State { + Succeeded, + Failed, +} + +fn print_on_failure(state: &State) { + let mut num = 0; + match *state { + // error: expected unit struct, unit variant or constant, found tuple + // variant `State::Failed` + State::Failed => { + num = 1; + } + State::Succeeded => { + num = 2; + } + _ => (), + } +} + +fn main() { + let b = State::Failed(1); + // { dg-error "expected function, tuple struct or tuple variant, found struct .State." "" { target *-*-* } .-1 } + + print_on_failure(&b); + // { dg-error "cannot find value .b. in this scope" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude index 945a697f677..e7344ed0d59 100644 --- a/gcc/testsuite/rust/compile/nr2/exclude +++ b/gcc/testsuite/rust/compile/nr2/exclude @@ -195,4 +195,5 @@ issue-266.rs additional-trait-bounds2.rs auto_traits2.rs auto_traits3.rs +issue-3140.rs # please don't delete the trailing newline -- 2.45.2