Skip to content

Commit

Permalink
Merge branch 'master' into nobody/sanitize-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
nobodywasishere authored May 30, 2024
2 parents 8a01443 + 28fd0dc commit 57d652b
Show file tree
Hide file tree
Showing 74 changed files with 612 additions and 774 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ parameters:
distribution-scripts-version:
description: "Git ref for version of https://github.com/crystal-lang/distribution-scripts/"
type: string
default: "8c3a9f6bf64499f1e3d1838d2ae9b967d5e7f796"
default: "a9e0c6c12987b8b01b17e71c38f489e45937e1bf"
previous_crystal_base_url:
description: "Prefix for URLs to Crystal bootstrap compiler"
type: string
Expand Down
7 changes: 7 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ We're only listing the most relevant changes here that could have a relevant imp
The [changelog](./CHANGELOG.md) contains more information about all changes in
a specific release.

## Crystal 1.13

* `CRYSTAL_LIBRARY_RPATH` and the `preview_win32_delay_load` feature flag have
been removed. Individual DLLs can be explicitly delay-loaded with the MSVC
toolchain by using `/DELAYLOAD` as a linker flag. Similarly RPATH can be added
with GCC or Clang toolchains by adding `-Wl,-rpath`.

## Crystal 1.9

* The implementation of the comparison operator `#<=>` between `Big*` (`BigDecimal`,
Expand Down
2 changes: 0 additions & 2 deletions bin/crystal.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,6 @@ function Exec-Process {
$hnd = $Process.Handle
Wait-Process -Id $Process.Id

# and return it properly too: https://stackoverflow.com/a/50202663
$host.SetShouldExit($Process.ExitCode)
Exit $Process.ExitCode
}

Expand Down
69 changes: 7 additions & 62 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ let
};

pkgs = if musl then nixpkgs.pkgsMusl else nixpkgs;
llvmPackages = pkgs."llvmPackages_${toString llvm}";

genericBinary = { url, sha256 }:
pkgs.stdenv.mkDerivation rec {
Expand Down Expand Up @@ -67,84 +68,28 @@ let
};
}.${pkgs.stdenv.system});

pkgconfig = pkgs.pkgconfig;

llvm_suite = ({
llvm_16 = {
llvm = pkgs.llvm_16;
extra = [ pkgs.llvmPackages_16.bintools pkgs.lldb_16 ];
};
llvm_15 = {
llvm = pkgs.llvm_15;
extra = [ pkgs.llvmPackages_15.bintools pkgs.lldb_15 ];
};
llvm_14 = {
llvm = pkgs.llvm_14;
extra = [ pkgs.llvmPackages_14.bintools pkgs.lldb_14 ];
};
llvm_13 = {
llvm = pkgs.llvm_13;
extra = [ pkgs.llvmPackages_13.bintools pkgs.lldb_13 ];
};
llvm_12 = {
llvm = pkgs.llvm_12;
extra = [ pkgs.llvmPackages_12.bintools pkgs.lldb_12 ];
};
llvm_11 = {
llvm = pkgs.llvm_11;
extra = [ pkgs.llvmPackages_11.bintools pkgs.lldb_11 ];
};
llvm_10 = {
llvm = pkgs.llvm_10;
extra = [ pkgs.llvmPackages_10.bintools ]; # lldb marked as broken
};
llvm_9 = {
llvm = pkgs.llvm_9;
extra = [ pkgs.llvmPackages_9.bintools ]; # lldb marked as broken
};
llvm_8 = {
llvm = pkgs.llvm_8;
extra = [ pkgs.llvmPackages_8.bintools ]; # lldb marked as broken
};
}."llvm_${toString llvm}");

boehmgc = pkgs.stdenv.mkDerivation rec {
pname = "boehm-gc";
version = "8.2.4";

src = builtins.fetchTarball {
url = "https://github.com/ivmai/bdwgc/releases/download/v${version}/gc-${version}.tar.gz";
sha256 = "0primpxl7hykfbmszf7ppbv7k1nj41f1r5m56n96q92mmzqlwybm";
};

configureFlags = [
"--disable-debug"
"--disable-dependency-tracking"
"--disable-shared"
"--enable-large-config"
];

enableParallelBuilding = true;
boehmgc = pkgs.boehmgc.override {
enableLargeConfig = true;
};

stdLibDeps = with pkgs; [
boehmgc gmp libevent libiconv libxml2 libyaml openssl pcre2 zlib
] ++ lib.optionals stdenv.isDarwin [ libiconv ];

tools = [ pkgs.hostname pkgs.git llvm_suite.extra ];
tools = [ pkgs.hostname pkgs.git llvmPackages.bintools ] ++ pkgs.lib.optional (!llvmPackages.lldb.meta.broken) llvmPackages.lldb;
in

pkgs.stdenv.mkDerivation rec {
name = "crystal-dev";

buildInputs = tools ++ stdLibDeps ++ [
latestCrystalBinary
pkgconfig
llvm_suite.llvm
pkgs.pkg-config
llvmPackages.libllvm
pkgs.libffi
];

LLVM_CONFIG = "${llvm_suite.llvm.dev}/bin/llvm-config";
LLVM_CONFIG = "${llvmPackages.libllvm.dev}/bin/llvm-config";

MACOSX_DEPLOYMENT_TARGET = "10.11";
}
13 changes: 13 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2875,6 +2875,19 @@ module Crystal
end
end

describe Select do
it "executes whens" do
assert_macro %({{x.whens}}), "[when foo\n 1\n]", {x: Select.new([When.new("foo".call, 1.int32)])}
assert_macro %({{x.whens}}), "[when x = y\n 1\n, when bar\n]", {x: Select.new([When.new(Assign.new("x".var, "y".var), 1.int32), When.new("bar".call)])}
end

it "executes else" do
assert_macro %({{x.else}}), "", {x: Select.new([When.new("foo".call)])}
assert_macro %({{x.else}}), "1", {x: Select.new([When.new("foo".call)], 1.int32)}
assert_macro %({{x.else}}), "nil", {x: Select.new([When.new("foo".call)], NilLiteral.new)}
end
end

describe "if methods" do
if_node = If.new(1.int32, 2.int32, 3.int32)

Expand Down
6 changes: 3 additions & 3 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1460,9 +1460,9 @@ module Crystal

it_parses "case 1; when 2 then /foo/; end", Case.new(1.int32, [When.new([2.int32] of ASTNode, RegexLiteral.new("foo".string))], else: nil, exhaustive: false)

it_parses "select\nwhen foo\n2\nend", Select.new([Select::When.new("foo".call, 2.int32)])
it_parses "select\nwhen foo\n2\nwhen bar\n4\nend", Select.new([Select::When.new("foo".call, 2.int32), Select::When.new("bar".call, 4.int32)])
it_parses "select\nwhen foo\n2\nelse\n3\nend", Select.new([Select::When.new("foo".call, 2.int32)], 3.int32)
it_parses "select\nwhen foo\n2\nend", Select.new([When.new("foo".call, 2.int32)])
it_parses "select\nwhen foo\n2\nwhen bar\n4\nend", Select.new([When.new("foo".call, 2.int32), When.new("bar".call, 4.int32)])
it_parses "select\nwhen foo\n2\nelse\n3\nend", Select.new([When.new("foo".call, 2.int32)], 3.int32)

assert_syntax_error "select\nwhen 1\n2\nend", "invalid select when expression: must be an assignment or call"

Expand Down
9 changes: 7 additions & 2 deletions spec/compiler/parser/to_s_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ describe "ASTNode#to_s" do
expect_to_s %(if (1 + 2\n3)\n 4\nend)
expect_to_s "%x(whoami)", "`whoami`"
expect_to_s %(begin\n ()\nend)
expect_to_s %(begin\n (1)\nend)
expect_to_s %(begin\n (@x = x).is_a?(Foo)\nend)
expect_to_s %(begin\n (1)\n 2\nend)
expect_to_s %(if 1\n begin\n 2\n end\nelse\n begin\n 3\n end\nend)
expect_to_s %(foo do\n begin\n bar\n end\nend)
expect_to_s %q("\e\0\""), %q("\e\u0000\"")
Expand Down Expand Up @@ -256,8 +259,10 @@ describe "ASTNode#to_s" do
expect_to_s "offsetof(Foo, @bar)"
expect_to_s "def foo(**options, &block)\nend"
expect_to_s "macro foo\n 123\nend"
expect_to_s "if true\n( 1)\nend"
expect_to_s "begin\n( 1)\nrescue\nend"
expect_to_s "if true\n (1)\nend"
expect_to_s "if true\n (1)\n 2\nend"
expect_to_s "begin\n (1)\nrescue\nend"
expect_to_s "begin\n (1)\n 2\nrescue\nend"
expect_to_s %[他.说("你好")]
expect_to_s %[他.说 = "你好"]
expect_to_s %[あ.い, う.え.お = 1, 2]
Expand Down
8 changes: 8 additions & 0 deletions spec/std/big/big_rational_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,14 @@ describe BigRational do
describe "#inspect" do
it { 123.to_big_r.inspect.should eq("123") }
end

it "#format" do
br(100, 3).format.should eq("100/3")
br(1234567, 890123).format.should eq("1,234,567/890,123")
br(1234567, 890123).format(".", " ").should eq("1 234 567/890 123")
br(1234567, 890123).format(".", " ", group: 2).should eq("1 23 45 67/89 01 23")
br(1234567, 890123).format(",", ".", group: 4).should eq("123.4567/89.0123")
end
end

describe "BigRational Math" do
Expand Down
24 changes: 12 additions & 12 deletions spec/std/crystal/system_spec.cr
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
require "../spec_helper"

private def print_error_to_s(format, *args)
private def printf_to_s(format, *args)
io = IO::Memory.new
Crystal::System.print_error(format, *args) do |bytes|
Crystal::System.printf(format, *args) do |bytes|
io.write_string(bytes)
end
io.to_s
end

describe "Crystal::System" do
describe ".print_error" do
describe ".printf" do
it "works" do
print_error_to_s("abcde").should eq("abcde")
printf_to_s("abcde").should eq("abcde")
end

it "supports %d" do
print_error_to_s("%d,%d,%d,%d,%d", 0, 1234, Int32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,2147483647,-2147483648,-1")
printf_to_s("%d,%d,%d,%d,%d", 0, 1234, Int32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,2147483647,-2147483648,-1")
end

it "supports %u" do
print_error_to_s("%u,%u,%u,%u,%u", 0, 1234, UInt32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,4294967295,2147483648,4294967295")
printf_to_s("%u,%u,%u,%u,%u", 0, 1234, UInt32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,4294967295,2147483648,4294967295")
end

it "supports %x" do
print_error_to_s("%x,%x,%x,%x,%x", 0, 0x1234, UInt32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,ffffffff,80000000,ffffffff")
printf_to_s("%x,%x,%x,%x,%x", 0, 0x1234, UInt32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,ffffffff,80000000,ffffffff")
end

# TODO: investigate why this prints `(???)`
pending_interpreted "supports %p" do
print_error_to_s("%p,%p,%p", Pointer(Void).new(0x0), Pointer(Void).new(0x1234), Pointer(Void).new(UInt64::MAX)).should eq("0x0,0x1234,0xffffffffffffffff")
printf_to_s("%p,%p,%p", Pointer(Void).new(0x0), Pointer(Void).new(0x1234), Pointer(Void).new(UInt64::MAX)).should eq("0x0,0x1234,0xffffffffffffffff")
end

it "supports %s" do
print_error_to_s("%s,%s,%s", "abc\0def", "ghi".to_unsafe, Pointer(UInt8).null).should eq("abc\0def,ghi,(null)")
printf_to_s("%s,%s,%s", "abc\0def", "ghi".to_unsafe, Pointer(UInt8).null).should eq("abc\0def,ghi,(null)")
end

# BUG: missing downcast_distinct from Tuple(Int64 | UInt64, Int64 | UInt64, Int64 | UInt64, Int64 | UInt64) to Tuple(Int64, Int64, Int64, Int64)
pending_interpreted "supports %l width" do
values = {LibC::Long::MIN, LibC::Long::MAX, LibC::LongLong::MIN, LibC::LongLong::MAX}
print_error_to_s("%ld,%ld,%lld,%lld", *values).should eq(values.join(','))
printf_to_s("%ld,%ld,%lld,%lld", *values).should eq(values.join(','))

values = {LibC::ULong::MIN, LibC::ULong::MAX, LibC::ULongLong::MIN, LibC::ULongLong::MAX}
print_error_to_s("%lu,%lu,%llu,%llu", *values).should eq(values.join(','))
print_error_to_s("%lx,%lx,%llx,%llx", *values).should eq(values.join(',', &.to_s(16)))
printf_to_s("%lu,%lu,%llu,%llu", *values).should eq(values.join(','))
printf_to_s("%lx,%lx,%llx,%llx", *values).should eq(values.join(',', &.to_s(16)))
end
end
end
7 changes: 6 additions & 1 deletion spec/std/json/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ require "spec"
require "json"

private def it_parses(string, expected_value, file = __FILE__, line = __LINE__)
it "parses #{string}", file, line do
it "parses #{string} from String", file, line do
JSON.parse(string).raw.should eq(expected_value)
end

it "parses #{string} from IO", file, line do
JSON.parse(IO::Memory.new(string)).raw.should eq(expected_value)
end
end

private def it_raises_on_parse(string, file = __FILE__, line = __LINE__)
Expand All @@ -31,6 +35,7 @@ describe JSON::Parser do
it_parses "[true]", [true]
it_parses "[false]", [false]
it_parses %(["hello"]), ["hello"]
it_parses %(["hello", 1]), ["hello", 1]
it_parses "[0]", [0]
it_parses " [ 0 ] ", [0]

Expand Down
4 changes: 2 additions & 2 deletions spec/std/json/pull_parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ class JSON::PullParser
end
end

private def assert_pull_parse(string)
it "parses #{string}" do
private def assert_pull_parse(string, file = __FILE__, line = __LINE__)
it "parses #{string}", file, line do
parser = JSON::PullParser.new string
parser.assert JSON.parse(string).raw
parser.kind.should eq(JSON::PullParser::Kind::EOF)
Expand Down
28 changes: 21 additions & 7 deletions spec/std/regex_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -449,15 +449,29 @@ describe "Regex" do
end

describe "#inspect" do
it "with options" do
/foo/.inspect.should eq("/foo/")
/foo/im.inspect.should eq("/foo/im")
/foo/imx.inspect.should eq("/foo/imx")
context "with literal-compatible options" do
it "prints flags" do
/foo/.inspect.should eq("/foo/")
/foo/im.inspect.should eq("/foo/im")
/foo/imx.inspect.should eq("/foo/imx")
end

it "escapes" do
%r(/).inspect.should eq("/\\//")
%r(\/).inspect.should eq("/\\//")
end
end

it "escapes" do
%r(/).inspect.should eq("/\\//")
%r(\/).inspect.should eq("/\\//")
context "with non-literal-compatible options" do
it "prints flags" do
Regex.new("foo", :anchored).inspect.should eq %(Regex.new("foo", Regex::Options::ANCHORED))
Regex.new("foo", :no_utf_check).inspect.should eq %(Regex.new("foo", Regex::Options::NO_UTF8_CHECK))
Regex.new("foo", Regex::CompileOptions[IGNORE_CASE, ANCHORED]).inspect.should eq %(Regex.new("foo", Regex::Options[IGNORE_CASE, ANCHORED]))
end

it "escapes" do
Regex.new(%("), :anchored).inspect.should eq %(Regex.new("\\"", Regex::Options::ANCHORED))
end
end
end

Expand Down
7 changes: 7 additions & 0 deletions spec/std/socket/socket_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,11 @@ describe Socket, tags: "network" do
end
end
end

{% unless flag?(:win32) %}
it "closes on exec by default" do
socket = Socket.new(Socket::Family::INET, Socket::Type::STREAM, Socket::Protocol::TCP)
socket.close_on_exec?.should be_true
end
{% end %}
end
7 changes: 3 additions & 4 deletions spec/std/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,9 @@ def compile_file(source_file, *, bin_name = "executable_file", flags = %w(), fil
args = ["build"] + flags + ["-o", executable_file, source_file]
output = IO::Memory.new
status = Process.run(compiler, args, env: {
"CRYSTAL_PATH" => Crystal::PATH,
"CRYSTAL_LIBRARY_PATH" => Crystal::LIBRARY_PATH,
"CRYSTAL_LIBRARY_RPATH" => Crystal::LIBRARY_RPATH,
"CRYSTAL_CACHE_DIR" => Crystal::CACHE_DIR,
"CRYSTAL_PATH" => Crystal::PATH,
"CRYSTAL_LIBRARY_PATH" => Crystal::LIBRARY_PATH,
"CRYSTAL_CACHE_DIR" => Crystal::CACHE_DIR,
}, output: output, error: output)

unless status.success?
Expand Down
7 changes: 7 additions & 0 deletions src/big/big_rational.cr
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,13 @@ struct BigRational < Number
to_s io
end

# :inherit:
def format(io : IO, separator = '.', delimiter = ',', decimal_places : Int? = nil, *, group : Int = 3, only_significant : Bool = false) : Nil
numerator.format(io, separator, delimiter, decimal_places, group: group, only_significant: only_significant)
io << '/'
denominator.format(io, separator, delimiter, decimal_places, group: group, only_significant: only_significant)
end

def clone
self
end
Expand Down
Loading

0 comments on commit 57d652b

Please sign in to comment.