diff --git a/complex.c b/complex.c index 12dec4d23b04c8..eab6bde85ab82b 100644 --- a/complex.c +++ b/complex.c @@ -799,9 +799,9 @@ rb_complex_imag(VALUE self) /* * call-seq: - * -complex -> new_complex + * -self -> complex * - * Returns the negation of +self+, which is the negation of each of its parts: + * Returns +self+, negated, which is the negation of each of its parts: * * -Complex.rect(1, 2) # => (-1-2i) * -Complex.rect(-1, -2) # => (1+2i) @@ -861,9 +861,9 @@ rb_complex_plus(VALUE self, VALUE other) /* * call-seq: - * complex - numeric -> new_complex + * self - other -> complex * - * Returns the difference of +self+ and +numeric+: + * Returns the difference of +self+ and +other+: * * Complex.rect(2, 3) - Complex.rect(2, 3) # => (0+0i) * Complex.rect(900) - Complex.rect(1) # => (899+0i) @@ -1122,9 +1122,9 @@ complex_pow_for_special_angle(VALUE self, VALUE other) /* * call-seq: - * complex ** numeric -> new_complex + * self ** exponent -> complex * - * Returns +self+ raised to power +numeric+: + * Returns +self+ raised to the power +exponent+: * * Complex.rect(0, 1) ** 2 # => (-1+0i) * Complex.rect(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i) diff --git a/doc/jit/zjit.md b/doc/jit/zjit.md index c66235269bd265..b5a2f05604983f 100644 --- a/doc/jit/zjit.md +++ b/doc/jit/zjit.md @@ -11,6 +11,38 @@ This project is open source and falls under the same license as CRuby. ZJIT may not be suitable for certain applications. It currently only supports macOS, Linux and BSD on x86-64 and arm64/aarch64 CPUs. ZJIT will use more memory than the Ruby interpreter because the JIT compiler needs to generate machine code in memory and maintain additional state information. You can change how much executable memory is allocated using [ZJIT's command-line options](rdoc-ref:@Command-Line+Options). +## Contributing + +We welcome open source contributions. Feel free to open new issues to report +bugs or just to ask questions. Suggestions on how to make this document more +helpful for new contributors are most welcome. + +Bug fixes and bug reports are very valuable to us. If you find a bug in ZJIT, +it's very possible that nobody has reported it before, or that we don't have +a good reproduction for it, so please open a ticket on [the official Ruby bug +tracker][rubybugs] (or, if you don't want to make an account, [on +Shopify/ruby][shopifyruby]) and provide as much information as you can about +your configuration and a description of how you encountered the problem. List +the commands you used to run ZJIT so that we can easily reproduce the issue on +our end and investigate it. If you are able to produce a small program +reproducing the error to help us track it down, that is very much appreciated +as well. + +[rubybugs]: https://bugs.ruby-lang.org/projects/ruby-master +[shopifyruby]: https://github.com/Shopify/ruby/issues + +If you would like to contribute a large patch to ZJIT, we suggest [chatting on +Zulip][zulip] for a casual chat and then opening an issue on the [Shopify/ruby +repository][shopifyruby] so that we can have a technical discussion. A common +problem is that sometimes people submit large pull requests to open source +projects without prior communication, and we have to reject them because the +work they implemented does not fit within the design of the project. We want to +save you time and frustration, so please reach out so we can have a productive +discussion as to how you can contribute patches we will want to merge into +ZJIT. + +[zulip]: https://zjit.zulipchat.com/ + ## Build Instructions Refer to [Building Ruby](rdoc-ref:contributing/building_ruby.md) for general build prerequists. diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb index e62311ae12d177..475444e589d1ca 100644 --- a/ext/psych/lib/psych/visitors/to_ruby.rb +++ b/ext/psych/lib/psych/visitors/to_ruby.rb @@ -12,6 +12,10 @@ module Visitors ### # This class walks a YAML AST, converting each node to Ruby class ToRuby < Psych::Visitors::Visitor + unless RUBY_VERSION < "3.2" + DATA_INITIALIZE = Data.instance_method(:initialize) + end + def self.create(symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true) class_loader = ClassLoader.new scanner = ScalarScanner.new class_loader, strict_integer: strict_integer, parse_symbols: parse_symbols @@ -219,8 +223,7 @@ def visit_Psych_Nodes_Mapping o revive_data_members(members, o) end data ||= allocate_anon_data(o, members) - values = data.members.map { |m| members[m] } - init_data(data, values) + DATA_INITIALIZE.bind_call(data, **members) data.freeze data diff --git a/ext/psych/psych_to_ruby.c b/ext/psych/psych_to_ruby.c index 0132b2c94e28c7..3ab0138b52417c 100644 --- a/ext/psych/psych_to_ruby.c +++ b/ext/psych/psych_to_ruby.c @@ -28,12 +28,6 @@ static VALUE path2class(VALUE self, VALUE path) return rb_path_to_class(path); } -static VALUE init_data(VALUE self, VALUE data, VALUE values) -{ - rb_struct_initialize(data, values); - return data; -} - void Init_psych_to_ruby(void) { VALUE psych = rb_define_module("Psych"); @@ -43,7 +37,6 @@ void Init_psych_to_ruby(void) VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor); - rb_define_private_method(cPsychVisitorsToRuby, "init_data", init_data, 2); rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2); rb_define_private_method(class_loader, "path2class", path2class, 1); } diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index dae1c16760a550..9862c92c0b6591 100644 --- a/ext/socket/lib/socket.rb +++ b/ext/socket/lib/socket.rb @@ -917,8 +917,7 @@ def self.tcp_with_fast_fallback(host, port, local_host = nil, local_port = nil, end ensure hostname_resolution_threads.each do |thread| - thread.kill - thread.join + thread.exit end hostname_resolution_result&.close diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb index ba1cef8434e63c..67feba84bdb06e 100644 --- a/lib/bundler/cli/install.rb +++ b/lib/bundler/cli/install.rb @@ -90,7 +90,7 @@ def dependencies_count_for(definition) end def gems_installed_for(definition) - count = definition.specs.count + count = definition.specs.count {|spec| spec.name != "bundler" } "#{count} #{count == 1 ? "gem" : "gems"} now installed" end diff --git a/lib/bundler/cli/pristine.rb b/lib/bundler/cli/pristine.rb index cfd4a995a31faa..b8545fe4c9c3eb 100644 --- a/lib/bundler/cli/pristine.rb +++ b/lib/bundler/cli/pristine.rb @@ -11,6 +11,7 @@ def run definition = Bundler.definition definition.validate_runtime! installer = Bundler::Installer.new(Bundler.root, definition) + git_sources = [] ProcessLock.lock do installed_specs = definition.specs.reject do |spec| @@ -41,6 +42,9 @@ def run end FileUtils.rm_rf spec.extension_dir FileUtils.rm_rf spec.full_gem_path + + next if git_sources.include?(source) + git_sources << source else Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.") next diff --git a/numeric.c b/numeric.c index f96535cd2461d2..4e105baa81532b 100644 --- a/numeric.c +++ b/numeric.c @@ -576,7 +576,7 @@ num_imaginary(VALUE num) * call-seq: * -self -> numeric * - * Unary Minus---Returns the receiver, negated. + * Returns +self+, negated. */ static VALUE @@ -1089,7 +1089,7 @@ rb_float_plus(VALUE x, VALUE y) * call-seq: * self - other -> numeric * - * Returns a new \Float which is the difference of +self+ and +other+: + * Returns the difference of +self+ and +other+: * * f = 3.14 * f - 1 # => 2.14 @@ -1390,9 +1390,9 @@ flo_divmod(VALUE x, VALUE y) /* * call-seq: - * self ** other -> numeric + * self ** exponent -> numeric * - * Raises +self+ to the power of +other+: + * Returns +self+ raised to the power +exponent+: * * f = 3.14 * f ** 2 # => 9.8596 @@ -4197,9 +4197,9 @@ fix_minus(VALUE x, VALUE y) /* * call-seq: - * self - numeric -> numeric_result + * self - other -> numeric * - * Performs subtraction: + * Returns the difference of +self+ and +other+: * * 4 - 2 # => 2 * -4 - 2 # => -6 @@ -4623,9 +4623,9 @@ rb_int_divmod(VALUE x, VALUE y) /* * call-seq: - * self ** numeric -> numeric_result + * self ** exponent -> numeric * - * Raises +self+ to the power of +numeric+: + * Returns +self+ raised to the power +exponent+: * * 2 ** 3 # => 8 * 2 ** -3 # => (1/8) @@ -4748,8 +4748,7 @@ fix_pow(VALUE x, VALUE y) * call-seq: * self ** exponent -> numeric * - * Returns the value of base +self+ raised to the power +exponent+; - * see {Exponentiation}[https://en.wikipedia.org/wiki/Exponentiation]: + * Returns +self+ raised to the power +exponent+: * * # Result for non-negative Integer exponent is Integer. * 2 ** 0 # => 1 diff --git a/numeric.rb b/numeric.rb index 552a3dd687aedc..306561943d5029 100644 --- a/numeric.rb +++ b/numeric.rb @@ -93,9 +93,14 @@ def +@ class Integer # call-seq: - # -int -> integer + # -self -> integer + # + # Returns +self+, negated: + # + # -1 # => -1 + # -(-1) # => 1 + # -0 # => 0 # - # Returns +self+, negated. def -@ Primitive.attr! :leaf Primitive.cexpr! 'rb_int_uminus(self)' @@ -373,9 +378,13 @@ def abs alias magnitude abs # call-seq: - # -float -> float + # -self -> float + # + # Returns +self+, negated: # - # Returns +self+, negated. + # -3.14 # => -3.14 + # -(-3.14) # => 3.14 + # -0.0 # => -0.0 # def -@ Primitive.attr! :leaf diff --git a/rational.c b/rational.c index 7c2bd0b1eb7f00..05dc3540c09442 100644 --- a/rational.c +++ b/rational.c @@ -609,9 +609,13 @@ nurat_denominator(VALUE self) /* * call-seq: - * -rat -> rational + * -self -> rational + * + * Returns +self+, negated: + * + * -(1/3r) # => (-1/3) + * -(-1/3r) # => (1/3) * - * Negates +rat+. */ VALUE rb_rational_uminus(VALUE self) @@ -768,9 +772,9 @@ rb_rational_plus(VALUE self, VALUE other) /* * call-seq: - * rat - numeric -> numeric + * self - other -> numeric * - * Performs subtraction. + * Returns the difference of +self+ and +other+: * * Rational(2, 3) - Rational(2, 3) #=> (0/1) * Rational(900) - Rational(1) #=> (899/1) @@ -984,9 +988,9 @@ nurat_fdiv(VALUE self, VALUE other) /* * call-seq: - * rat ** numeric -> numeric + * self ** exponent -> numeric * - * Performs exponentiation. + * Returns +self+ raised to the power +exponent+: * * Rational(2) ** Rational(3) #=> (8/1) * Rational(10) ** -2 #=> (1/100) diff --git a/set.c b/set.c index 0c657cf66d8118..6d200b5dfa1495 100644 --- a/set.c +++ b/set.c @@ -1988,13 +1988,6 @@ rb_set_size(VALUE set) /* * Document-class: Set * - * Copyright (c) 2002-2024 Akinori MUSHA - * - * Documentation by Akinori MUSHA and Gavin Sinclair. - * - * All rights reserved. You can redistribute and/or modify it under the same - * terms as Ruby. - * * The Set class implements a collection of unordered values with no * duplicates. It is a hybrid of Array's intuitive inter-operation * facilities and Hash's fast lookup. diff --git a/spec/bundler/commands/post_bundle_message_spec.rb b/spec/bundler/commands/post_bundle_message_spec.rb index 257443526089ad..9eecff593f7e33 100644 --- a/spec/bundler/commands/post_bundle_message_spec.rb +++ b/spec/bundler/commands/post_bundle_message_spec.rb @@ -18,7 +18,7 @@ let(:bundle_show_path_message) { "Bundled gems are installed into `#{bundle_path}`" } let(:bundle_complete_message) { "Bundle complete!" } let(:bundle_updated_message) { "Bundle updated!" } - let(:installed_gems_stats) { "4 Gemfile dependencies, 5 gems now installed." } + let(:installed_gems_stats) { "4 Gemfile dependencies, 4 gems now installed." } describe "when installing to system gems" do before do @@ -44,14 +44,14 @@ expect(out).to include(bundle_show_system_message) expect(out).to include("Gems in the groups 'emo' and 'test' were not installed") expect(out).to include(bundle_complete_message) - expect(out).to include("4 Gemfile dependencies, 3 gems now installed.") + expect(out).to include("4 Gemfile dependencies, 2 gems now installed.") bundle "config set --local without emo obama test" bundle :install expect(out).to include(bundle_show_system_message) expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed") expect(out).to include(bundle_complete_message) - expect(out).to include("4 Gemfile dependencies, 2 gems now installed.") + expect(out).to include("4 Gemfile dependencies, 1 gem now installed.") end describe "for second bundle install run" do diff --git a/spec/bundler/commands/pristine_spec.rb b/spec/bundler/commands/pristine_spec.rb index da61dc819920fb..daeafea43bf87e 100644 --- a/spec/bundler/commands/pristine_spec.rb +++ b/spec/bundler/commands/pristine_spec.rb @@ -89,6 +89,66 @@ expect(changes_txt).to be_file expect(err).to include("Cannot pristine #{spec.name} (#{spec.version}#{spec.git_version}). Gem is locally overridden.") end + + it "doesn't run multiple git processes for the same repository" do + nested_gems = [ + "actioncable", + "actionmailer", + "actionpack", + "actionview", + "activejob", + "activemodel", + "activerecord", + "activestorage", + "activesupport", + "railties", + ] + + build_repo2 do + nested_gems.each do |gem| + build_lib gem, path: lib_path("rails/#{gem}") + end + + build_git "rails", path: lib_path("rails") do |s| + nested_gems.each do |gem| + s.add_dependency gem + end + end + end + + install_gemfile <<-G + source 'https://rubygems.org' + + git "#{lib_path("rails")}" do + gem "rails" + gem "actioncable" + gem "actionmailer" + gem "actionpack" + gem "actionview" + gem "activejob" + gem "activemodel" + gem "activerecord" + gem "activestorage" + gem "activesupport" + gem "railties" + end + G + + changed_files = [] + diff = "#Pristine spec changes" + + nested_gems.each do |gem| + spec = find_spec(gem) + changed_files << Pathname.new(spec.full_gem_path).join("lib/#{gem}.rb") + File.open(changed_files.last, "a") {|f| f.puts diff } + end + + bundle "pristine" + + changed_files.each do |changed_file| + expect(File.read(changed_file)).to_not include(diff) + end + end end context "when sourced from gemspec" do diff --git a/test/psych/test_data.rb b/test/psych/test_data.rb index a67a037b9e4af5..57c3478193a526 100644 --- a/test/psych/test_data.rb +++ b/test/psych/test_data.rb @@ -64,6 +64,31 @@ def test_load assert_equal "hello", obj.bar assert_equal "bar", obj.foo end + + def test_members_must_be_identical + TestData.const_set :D, Data.define(:a, :b) + d = Psych.dump(TestData::D.new(1, 2)) + + # more members + TestData.send :remove_const, :D + TestData.const_set :D, Data.define(:a, :b, :c) + e = assert_raise(ArgumentError) { Psych.unsafe_load d } + assert_equal 'missing keyword: :c', e.message + + # less members + TestData.send :remove_const, :D + TestData.const_set :D, Data.define(:a) + e = assert_raise(ArgumentError) { Psych.unsafe_load d } + assert_equal 'unknown keyword: :b', e.message + + # completely different members + TestData.send :remove_const, :D + TestData.const_set :D, Data.define(:foo, :bar) + e = assert_raise(ArgumentError) { Psych.unsafe_load d } + assert_equal 'unknown keywords: :a, :b', e.message + ensure + TestData.send :remove_const, :D + end end end