Skip to content

Commit 5cd679c

Browse files
committed
[GR-18163] Ignore internal frames in Kernel#warn (#2046).
PullRequest: truffleruby/1771
2 parents f5de7bb + 0cd6b9e commit 5cd679c

File tree

7 files changed

+33
-3
lines changed

7 files changed

+33
-3
lines changed

lib/mri/rubygems/core_ext/kernel_warn.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
if RUBY_VERSION >= "2.5"
55

66
module Kernel
7-
path = "#{__dir__}/" # Frames to be skipped start with this path.
7+
rubygems_path = "#{__dir__}/" # Frames to be skipped start with this path.
88

99
# Suppress "method redefined" warning
1010
original_warn = instance_method(:warn)
@@ -32,7 +32,8 @@ module Kernel
3232

3333
start += 1
3434

35-
unless loc.path.start_with?(path)
35+
path = loc.path
36+
unless path.start_with?(rubygems_path) or path.start_with?('<internal:')
3637
# Non-rubygems frames
3738
uplevel -= 1
3839
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
warn 'warn-require-warning', uplevel: 1
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Use a different line than just 1
2+
require "#{__dir__}/warn_require"

spec/ruby/core/kernel/warn_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@
101101
-> { w.f4("foo", 3) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f3_call_lineno}: warning: foo|)
102102
end
103103

104+
# Test both explicitly without and with RubyGems as RubyGems overrides Kernel#warn
105+
it "shows the caller of #require and not #require itself without RubyGems" do
106+
file = fixture(__FILE__ , "warn_require_caller.rb")
107+
ruby_exe(file, options: "--disable-gems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n"
108+
end
109+
110+
ruby_version_is "2.6" do
111+
it "shows the caller of #require and not #require itself with RubyGems loaded" do
112+
file = fixture(__FILE__ , "warn_require_caller.rb")
113+
ruby_exe(file, options: "-rrubygems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n"
114+
end
115+
end
116+
104117
it "converts first arg using to_s" do
105118
w = KernelSpecs::WarnInNestedCall.new
106119

spec/tags/core/kernel/warn_tags.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
slow:Kernel#warn :uplevel keyword argument shows the caller of #require and not #require itself without RubyGems
2+
slow:Kernel#warn :uplevel keyword argument shows the caller of #require and not #require itself with RubyGems loaded

spec/truffleruby.mspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ if i = ARGV.index('slow') and ARGV[i-1] == '--excl-tag' and MSpecScript.child_pr
163163
if MSpec.current and state = MSpec.current.state # an example is running
164164
tag = SpecTag.new
165165
tag.tag = 'slow'
166+
tag.comment = nil
166167
tag.description = "#{state.describe} #{state.it}"
167168
if MSpec.write_tag(tag)
168169
STDERR.puts "\nAdded slow tag for #{tag.description}"

src/main/ruby/truffleruby/core/kernel.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,17 @@ def warn(*messages, uplevel: undefined)
641641
uplevel = Primitive.rb_to_int(uplevel)
642642
raise ArgumentError, "negative level (#{uplevel})" unless uplevel >= 0
643643

644-
caller, = Kernel.caller_locations(uplevel + 1, 1)
644+
uplevel += 1 # skip Kernel#warn itself
645+
initial, = Kernel.caller_locations(uplevel, 1)
646+
caller = initial
647+
# MRI would reuse the file:line of the user code caller for methods defined in C.
648+
# Similarly, we skip <internal:* calls, notably to skip Kernel#require calls.
649+
while caller and caller.path.start_with?('<internal:')
650+
uplevel += 1
651+
caller, = Kernel.caller_locations(uplevel, 1)
652+
end
653+
caller = initial unless caller
654+
645655
if caller
646656
"#{caller.path}:#{caller.lineno}: warning: "
647657
else

0 commit comments

Comments
 (0)