From f4f3f842ccd5977b56d10c74e648ebb731783b64 Mon Sep 17 00:00:00 2001 From: Jake Zimmerman Date: Tue, 26 Jan 2021 14:22:58 -0800 Subject: [PATCH] Fix crash in pinning autocorrect (#3924) * Add ENFORCE that would have made error more obvious * Add failing test Fails with this backtrace: Exception::raise(): core/Loc.cc:270 enforced condition exists() has failed: Can't take source of Loc that doesn't exist Backtrace: #3 0x1725725 sorbet::core::Loc::source() #4 0x120e0e1 sorbet::infer::Environment::processBinding() #5 0x11fae5b sorbet::infer::Inference::run() #6 0xed1a88 sorbet::realmain::pipeline::CFGCollectorAndTyper::preTransformMethodDef() #7 0xed185b sorbet::ast::CALL_MEMBER_impl_preTransformMethodDef<>::call<>() #8 0xecf90c sorbet::ast::TreeMapper<>::mapMethodDef() #9 0xece3ff sorbet::ast::TreeMapper<>::mapIt() #10 0xecf81f sorbet::ast::TreeMapper<>::mapClassDef() #11 0xece37a sorbet::ast::TreeMapper<>::mapIt() #12 0xed1409 sorbet::ast::TreeMapper<>::mapInsSeq() #13 0xecef9f sorbet::ast::TreeMapper<>::mapIt() #14 0xebc5d9 sorbet::ast::TreeMap::apply<>() #15 0xea2971 sorbet::realmain::pipeline::typecheckOne() #16 0xeb3dc6 sorbet::realmain::pipeline::typecheck()::$_4::operator()() #17 0xeb3acd std::__1::__invoke<>() #18 0xeb3a7d std::__1::__invoke_void_return_wrapper<>::__call<>() #19 0xeb3a4d std::__1::__function::__alloc_func<>::operator()() #20 0xeb2bee std::__1::__function::__func<>::operator()() #21 0x177e015 std::__1::__function::__value_func<>::operator()() #22 0x177ddb5 std::__1::function<>::operator()() #23 0x17fc90e sorbet::WorkerPoolImpl::multiplexJob() #24 0xea5633 sorbet::realmain::pipeline::typecheck() #25 0xafb232 sorbet::realmain::realmain() #26 0xaf70f2 main #27 0x7fba7de990b3 __libc_start_main #28 0xaf702e _start * Fix failing test --- core/Loc.cc | 1 + infer/environment.cc | 2 +- test/testdata/infer/suggest_t_let_self.rb | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 test/testdata/infer/suggest_t_let_self.rb diff --git a/core/Loc.cc b/core/Loc.cc index 983c3a9d97b..933345a42a9 100644 --- a/core/Loc.cc +++ b/core/Loc.cc @@ -273,6 +273,7 @@ string Loc::filePosToString(const GlobalState &gs, bool showFull) const { } string Loc::source(const GlobalState &gs) const { + ENFORCE(exists(), "Can't take source of Loc that doesn't exist"); auto source = this->file().data(gs).source(); return string(source.substr(beginPos(), endPos() - beginPos())); } diff --git a/infer/environment.cc b/infer/environment.cc index 612e0a1da0e..f5bb9c9413f 100644 --- a/infer/environment.cc +++ b/infer/environment.cc @@ -1388,7 +1388,7 @@ core::TypePtr Environment::processBinding(core::Context ctx, const cfg::CFG &inW e.addErrorSection(core::ErrorSection(core::ErrorColors::format( "Attempting to change type to: `{}`\n", tp.type.show(ctx)))); - if (cur.origins.size() == 1) { + if (cur.origins.size() == 1 && cur.origins[0].exists()) { // NOTE(nelhage): We assume that if there is // a single definition location, that // corresponds to an initial diff --git a/test/testdata/infer/suggest_t_let_self.rb b/test/testdata/infer/suggest_t_let_self.rb new file mode 100644 index 00000000000..d122c155a46 --- /dev/null +++ b/test/testdata/infer/suggest_t_let_self.rb @@ -0,0 +1,7 @@ +# typed: true + +x = self + +1.times do + x = 10 # error: Changing the type of a variable in a loop is not permitted +end