diff --git a/doc/contributing/making_changes_to_stdlibs.md b/doc/contributing/making_changes_to_stdlibs.md index 2156a61e3948a3..2ceb2e60756714 100644 --- a/doc/contributing/making_changes_to_stdlibs.md +++ b/doc/contributing/making_changes_to_stdlibs.md @@ -4,7 +4,7 @@ Everything in the [lib](https://github.com/ruby/ruby/tree/master/lib) directory If you'd like to make contributions to standard libraries, do so in the standalone repositories, and the changes will be automatically mirrored into the Ruby repository. -For example, CSV lives in [a separate repository](https://github.com/ruby/csv) and is mirrored into [Ruby](https://github.com/ruby/ruby/tree/master/lib/csv). +For example, ERB lives in [a separate repository](https://github.com/ruby/erb) and is mirrored into [Ruby](https://github.com/ruby/ruby/tree/master/lib/erb). ## Maintainers diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 62225a352d71fa..9c7c1217fbf8bd 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -447,9 +447,8 @@ def cache D def exec(*args) if ARGV.include?("--no-keep-file-descriptors") - message = "The `--no-keep-file-descriptors` has been deprecated. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to" removed_message = "The `--no-keep-file-descriptors` has been removed. `bundle exec` no longer mess with your file descriptors. Close them in the exec'd script if you need to" - SharedHelpers.major_deprecation(2, message, removed_message: removed_message) + raise InvalidOption, removed_message end require_relative "cli/exec" diff --git a/lib/bundler/cli/config.rb b/lib/bundler/cli/config.rb index d963679085ebb7..6a77e4a65ea386 100644 --- a/lib/bundler/cli/config.rb +++ b/lib/bundler/cli/config.rb @@ -26,8 +26,7 @@ def base(name = nil, *value) end message = "Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead." - removed_message = "Using the `config` command without a subcommand [list, get, set, unset] has been removed. Use `bundle #{new_args.join(" ")}` instead." - SharedHelpers.major_deprecation 4, message, removed_message: removed_message + SharedHelpers.feature_deprecated! message Base.new(options, name, value, self).run end diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb index 4b4ba3c64712be..9cc90acc58536a 100644 --- a/lib/bundler/cli/update.rb +++ b/lib/bundler/cli/update.rb @@ -26,7 +26,7 @@ def run if Bundler.settings[:update_requires_all_flag] raise InvalidOption, "To update everything, pass the `--all` flag." end - SharedHelpers.major_deprecation 4, "Pass --all to `bundle update` to update everything" + SharedHelpers.feature_deprecated! "Pass --all to `bundle update` to update everything" elsif !full_update && options[:all] raise InvalidOption, "Cannot specify --all along with specific options." end diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index cc2394fda60f0a..6cae8964d8145a 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -372,7 +372,7 @@ def lock(file_or_preserve_unknown_sections = false, preserve_unknown_sections_or msg = "`Definition#lock` was passed a target file argument. #{suggestion}" - Bundler::SharedHelpers.major_deprecation 2, msg + Bundler::SharedHelpers.feature_removed! msg end write_lock(target_lockfile, preserve_unknown_sections) diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb index d98dbd4759e922..998a8134f8e12b 100644 --- a/lib/bundler/dsl.rb +++ b/lib/bundler/dsl.rb @@ -483,14 +483,10 @@ def validate_keys(command, opts, valid_keys) def normalize_source(source) case source when :gemcutter, :rubygems, :rubyforge - message = - "The source :#{source} is deprecated because HTTP requests are insecure.\n" \ - "Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not." removed_message = "The source :#{source} is disallowed because HTTP requests are insecure.\n" \ "Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not." - Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message - "http://rubygems.org" + Bundler::SharedHelpers.feature_removed! removed_message when String source else @@ -509,7 +505,7 @@ def check_path_source_safety " gem 'rails'\n" \ " end\n\n" - SharedHelpers.major_deprecation(2, msg.strip) + SharedHelpers.feature_removed! msg.strip end def check_rubygems_source_safety diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index 41b7128d36e18e..987a68afd75326 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -125,28 +125,13 @@ def filesystem_access(path, action = :write, &block) raise GenericSystemCallError.new(e, "There was an error #{[:create, :write].include?(action) ? "creating" : "accessing"} `#{path}`.") end - def major_deprecation(major_version, message, removed_message: nil, print_caller_location: false) - if print_caller_location - caller_location = caller_locations(2, 2).first - suffix = " (called at #{caller_location.path}:#{caller_location.lineno})" - message += suffix - end - - require_relative "../bundler" - - feature_flag = Bundler.feature_flag + def feature_deprecated!(message) + return unless prints_major_deprecations? - if feature_flag.removed_major?(major_version) - feature_removed!(removed_message || message) - end - - return unless feature_flag.deprecated_major?(major_version) && prints_major_deprecations? Bundler.ui.warn("[DEPRECATED] #{message}") end def feature_removed!(message) - require_relative "../bundler" - require_relative "errors" raise RemovedError, "[REMOVED] #{message}" end diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 1d351f8aff9746..ea7b58f20e23a9 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -488,8 +488,6 @@ def platform=(platform) end @platform = @new_platform.to_s - - invalidate_memoized_attributes end ## @@ -1620,14 +1618,14 @@ def build_info_file # spec's cached gem. def cache_dir - @cache_dir ||= File.join base_dir, "cache" + File.join base_dir, "cache" end ## # Returns the full path to the cached gem for this spec. def cache_file - @cache_file ||= File.join cache_dir, "#{full_name}.gem" + File.join cache_dir, "#{full_name}.gem" end ## @@ -1903,10 +1901,6 @@ def for_cache spec end - def full_name - @full_name ||= super - end - ## # Work around old bundler versions removing my methods # Can be removed once RubyGems can no longer install Bundler 2.5 @@ -2044,17 +2038,6 @@ def base_dir end end - ## - # Expire memoized instance variables that can incorrectly generate, replace - # or miss files due changes in certain attributes used to compute them. - - def invalidate_memoized_attributes - @full_name = nil - @cache_file = nil - end - - private :invalidate_memoized_attributes - def inspect # :nodoc: if $DEBUG super @@ -2093,8 +2076,6 @@ def licenses def internal_init # :nodoc: super @bin_dir = nil - @cache_dir = nil - @cache_file = nil @doc_dir = nil @ri_dir = nil @spec_dir = nil @@ -2606,9 +2587,6 @@ def validate_permissions def version=(version) @version = Gem::Version.create(version) - return if @version.nil? - - invalidate_memoized_attributes end def stubbed? diff --git a/spec/bundler/bundler/shared_helpers_spec.rb b/spec/bundler/bundler/shared_helpers_spec.rb index 5b3a9c17a7e8d5..0aacb93c16e2a9 100644 --- a/spec/bundler/bundler/shared_helpers_spec.rb +++ b/spec/bundler/bundler/shared_helpers_spec.rb @@ -515,34 +515,4 @@ end end end - - describe "#major_deprecation" do - before { allow(Bundler).to receive(:feature_flag).and_return(Bundler::FeatureFlag.new(37)) } - before { allow(Bundler.ui).to receive(:warn) } - - it "prints and raises nothing below the deprecated major version" do - subject.major_deprecation(38, "Message") - subject.major_deprecation(39, "Message", removed_message: "Removal", print_caller_location: true) - expect(Bundler.ui).not_to have_received(:warn) - end - - it "prints but does not raise _at_ the deprecated major version" do - subject.major_deprecation(37, "Message") - subject.major_deprecation(37, "Message", removed_message: "Removal") - expect(Bundler.ui).to have_received(:warn).with("[DEPRECATED] Message").twice - - subject.major_deprecation(37, "Message", print_caller_location: true) - expect(Bundler.ui).to have_received(:warn). - with(a_string_matching(/^\[DEPRECATED\] Message \(called at .*:\d+\)$/)) - end - - it "raises the appropriate errors when _past_ the deprecated major version" do - expect { subject.major_deprecation(36, "Message") }. - to raise_error(Bundler::RemovedError, "[REMOVED] Message") - expect { subject.major_deprecation(36, "Message", removed_message: "Removal") }. - to raise_error(Bundler::RemovedError, "[REMOVED] Removal") - expect { subject.major_deprecation(35, "Message", removed_message: "Removal", print_caller_location: true) }. - to raise_error(Bundler::RemovedError, "[REMOVED] Removal") - end - end end diff --git a/zjit/bindgen/src/main.rs b/zjit/bindgen/src/main.rs index b40986c0f6e154..975a2d91570613 100644 --- a/zjit/bindgen/src/main.rs +++ b/zjit/bindgen/src/main.rs @@ -82,7 +82,7 @@ fn main() { .allowlist_type("ruby_rstring_flags") // This function prints info about a value and is useful for debugging - .allowlist_function("rb_obj_info_dump") + .allowlist_function("rb_raw_obj_info") .allowlist_function("ruby_init") .allowlist_function("ruby_init_stack") diff --git a/zjit/src/cruby.rs b/zjit/src/cruby.rs index 1f514787f113d0..1a2dce03eda316 100644 --- a/zjit/src/cruby.rs +++ b/zjit/src/cruby.rs @@ -90,7 +90,7 @@ use std::convert::From; use std::ffi::{c_void, CString, CStr}; -use std::fmt::{Debug, Formatter}; +use std::fmt::{Debug, Display, Formatter}; use std::os::raw::{c_char, c_int, c_uint}; use std::panic::{catch_unwind, UnwindSafe}; @@ -400,10 +400,27 @@ pub enum ClassRelationship { NoRelation, } +/// A print adapator for debug info about a [VALUE]. Includes info +/// the GC knows about the handle. Example: `println!("{}", value.obj_info());`. +pub struct ObjInfoPrinter(VALUE); + +impl Display for ObjInfoPrinter { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + use std::mem::MaybeUninit; + const BUFFER_SIZE: usize = 0x100; + let mut buffer: MaybeUninit<[c_char; BUFFER_SIZE]> = MaybeUninit::uninit(); + let info = unsafe { + rb_raw_obj_info(buffer.as_mut_ptr().cast(), BUFFER_SIZE, self.0); + CStr::from_ptr(buffer.as_ptr().cast()).to_string_lossy() + }; + write!(f, "{info}") + } +} + impl VALUE { - /// Dump info about the value to the console similarly to rp(VALUE) - pub fn dump_info(self) { - unsafe { rb_obj_info_dump(self) } + /// Get a printer for raw debug info from `rb_obj_info()` about the value. + pub fn obj_info(self) -> ObjInfoPrinter { + ObjInfoPrinter(self) } /// Return whether the value is truthy or falsy in Ruby -- only nil and false are falsy. @@ -507,8 +524,11 @@ impl VALUE { pub fn class_of(self) -> VALUE { if !self.special_const_p() { let builtin_type = self.builtin_type(); - assert_ne!(builtin_type, RUBY_T_NONE, "ZJIT should only see live objects"); - assert_ne!(builtin_type, RUBY_T_MOVED, "ZJIT should only see live objects"); + assert!( + builtin_type != RUBY_T_NONE && builtin_type != RUBY_T_MOVED, + "ZJIT saw a dead object. T_type={builtin_type}, {}", + self.obj_info() + ); } unsafe { rb_yarv_class_of(self) } diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index 56b569e064c0b0..f18c0035ee0f67 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -839,7 +839,6 @@ unsafe extern "C" { pub fn rb_ivar_set(obj: VALUE, name: ID, val: VALUE) -> VALUE; pub fn rb_ivar_defined(obj: VALUE, name: ID) -> VALUE; pub fn rb_attr_get(obj: VALUE, name: ID) -> VALUE; - pub fn rb_obj_info_dump(obj: VALUE); pub fn rb_class_allocate_instance(klass: VALUE) -> VALUE; pub fn rb_obj_equal(obj1: VALUE, obj2: VALUE) -> VALUE; pub fn rb_reg_new_ary(ary: VALUE, options: ::std::os::raw::c_int) -> VALUE; @@ -872,6 +871,11 @@ unsafe extern "C" { cfp: *const rb_control_frame_t, ) -> *const rb_callable_method_entry_t; pub fn rb_obj_info(obj: VALUE) -> *const ::std::os::raw::c_char; + pub fn rb_raw_obj_info( + buff: *mut ::std::os::raw::c_char, + buff_size: usize, + obj: VALUE, + ) -> *const ::std::os::raw::c_char; pub fn rb_ec_stack_check(ec: *mut rb_execution_context_struct) -> ::std::os::raw::c_int; pub fn rb_gc_writebarrier_remember(obj: VALUE); pub fn rb_shape_id_offset() -> i32;