Skip to content

Commit

Permalink
Merge branch 'crystal-lang:master' into nobody/sanitize-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
nobodywasishere authored May 13, 2024
2 parents 382f7c7 + 8661e70 commit fe54ddd
Show file tree
Hide file tree
Showing 44 changed files with 422 additions and 136 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: "46c295d14e4dc3f6b7d9598c0b4dd89e93232def"
default: "8c3a9f6bf64499f1e3d1838d2ae9b967d5e7f796"
previous_crystal_base_url:
description: "Prefix for URLs to Crystal bootstrap compiler"
type: string
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/llvm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
llvm_ubuntu_version: "22.04"
- llvm_version: "17.0.6"
llvm_ubuntu_version: "22.04"
- llvm_version: "18.1.4"
llvm_ubuntu_version: "18.04"
name: "LLVM ${{ matrix.llvm_version }}"
steps:
- name: Checkout Crystal source
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ SPEC_FLAGS := $(if $(verbose),-v )$(if $(junit_output),--junit_output $(junit_ou
CRYSTAL_CONFIG_LIBRARY_PATH := '$$ORIGIN/../lib/crystal'
CRYSTAL_CONFIG_BUILD_COMMIT ?= $(shell git rev-parse --short HEAD 2> /dev/null)
CRYSTAL_CONFIG_PATH := '$$ORIGIN/../share/crystal/src'
SOURCE_DATE_EPOCH ?= $(shell (git show -s --format=%ct HEAD || stat -c "%Y" Makefile || stat -f "%m" Makefile) 2> /dev/null)
CRYSTAL_VERSION ?= $(shell cat src/VERSION)
SOURCE_DATE_EPOCH ?= $(shell (cat src/SOURCE_DATE_EPOCH || (git show -s --format=%ct HEAD || stat -c "%Y" Makefile || stat -f "%m" Makefile)) 2> /dev/null)
ifeq ($(shell command -v ld.lld >/dev/null && uname -s),Linux)
EXPORT_CC ?= CC="$(CC) -fuse-ld=lld"
endif
Expand All @@ -63,7 +64,6 @@ LLVM_VERSION := $(if $(LLVM_CONFIG),$(shell $(LLVM_CONFIG) --version 2> /dev/nul
LLVM_EXT_DIR = src/llvm/ext
LLVM_EXT_OBJ = $(LLVM_EXT_DIR)/llvm_ext.o
CXXFLAGS += $(if $(debug),-g -O0)
CRYSTAL_VERSION ?= $(shell cat src/VERSION)

DESTDIR ?=
PREFIX ?= /usr/local
Expand Down
4 changes: 2 additions & 2 deletions Makefile.win
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ SPEC_FLAGS := $(if $(verbose),-v )$(if $(junit_output),--junit_output $(junit_ou
CRYSTAL_CONFIG_LIBRARY_PATH := $$ORIGIN\lib
CRYSTAL_CONFIG_BUILD_COMMIT := $(shell git rev-parse --short HEAD)
CRYSTAL_CONFIG_PATH := $$ORIGIN\src
SOURCE_DATE_EPOCH := $(shell git show -s --format=%ct HEAD)
CRYSTAL_VERSION ?= $(shell type src\VERSION)
SOURCE_DATE_EPOCH ?= $(shell type src/SOURCE_DATE_EPOCH || git show -s --format=%ct HEAD)
export_vars = $(eval export CRYSTAL_CONFIG_BUILD_COMMIT CRYSTAL_CONFIG_PATH SOURCE_DATE_EPOCH)
export_build_vars = $(eval export CRYSTAL_CONFIG_LIBRARY_PATH)
LLVM_CONFIG ?=
LLVM_VERSION := $(if $(LLVM_CONFIG),$(shell $(LLVM_CONFIG) --version))
LLVM_EXT_DIR = src\llvm\ext
LLVM_EXT_OBJ = $(LLVM_EXT_DIR)\llvm_ext.obj
CXXFLAGS += $(if $(static),$(if $(debug),/MTd /Od ,/MT ),$(if $(debug),/MDd /Od ,/MD ))
CRYSTAL_VERSION ?= $(shell type src\VERSION)

prefix ?= $(or $(ProgramW6432),$(ProgramFiles))\crystal
BINDIR ?= $(prefix)
Expand Down
8 changes: 8 additions & 0 deletions scripts/release-update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ set -eu

CRYSTAL_VERSION=$1

# Write dev version for next minor release into src/VERSION
minor_branch="${CRYSTAL_VERSION%.*}"
next_minor="$((${minor_branch#*.} + 1))"
echo "${CRYSTAL_VERSION%%.*}.${next_minor}.0-dev" > src/VERSION

# Remove SOURCE_DATE_EPOCH (only used in source tree of a release)
rm -f src/SOURCE_DATE_EPOCH

# Edit PREVIOUS_CRYSTAL_BASE_URL in .circleci/config.yml
sed -i -E "s|[0-9.]+/crystal-[0-9.]+-[0-9]|$CRYSTAL_VERSION/crystal-$CRYSTAL_VERSION-1|g" .circleci/config.yml

Expand Down
9 changes: 9 additions & 0 deletions scripts/update-changelog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ scripts/github-changelog.cr $VERSION > $current_changelog
echo "Switching to branch $branch"
git switch $branch 2>/dev/null || git switch -c $branch;

# Write release version into src/VERSION
echo "${VERSION}" > src/VERSION
git add src/VERSION

# Write release date into src/SOURCE_DATE_EPOCH
release_date=$(head -n1 $current_changelog | grep -o -P '(?<=\()[^)]+')
echo "$(date --utc --date="${release_date}" +%s)" > src/SOURCE_DATE_EPOCH
git add src/SOURCE_DATE_EPOCH

if grep --silent -E "^## \[$VERSION\]" CHANGELOG.md; then
echo "Replacing section in CHANGELOG"

Expand Down
18 changes: 9 additions & 9 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -72,39 +72,39 @@ let
llvm_suite = ({
llvm_16 = {
llvm = pkgs.llvm_16;
extra = [ pkgs.lld_16 pkgs.lldb_16 ];
extra = [ pkgs.llvmPackages_16.bintools pkgs.lldb_16 ];
};
llvm_15 = {
llvm = pkgs.llvm_15;
extra = [ pkgs.lld_15 pkgs.lldb_15 ];
extra = [ pkgs.llvmPackages_15.bintools pkgs.lldb_15 ];
};
llvm_14 = {
llvm = pkgs.llvm_14;
extra = [ pkgs.lld_14 pkgs.lldb_14 ];
extra = [ pkgs.llvmPackages_14.bintools pkgs.lldb_14 ];
};
llvm_13 = {
llvm = pkgs.llvm_13;
extra = [ pkgs.lld_13 pkgs.lldb_13 ];
extra = [ pkgs.llvmPackages_13.bintools pkgs.lldb_13 ];
};
llvm_12 = {
llvm = pkgs.llvm_12;
extra = [ pkgs.lld_12 pkgs.lldb_12 ];
extra = [ pkgs.llvmPackages_12.bintools pkgs.lldb_12 ];
};
llvm_11 = {
llvm = pkgs.llvm_11;
extra = [ pkgs.lld_11 pkgs.lldb_11 ];
extra = [ pkgs.llvmPackages_11.bintools pkgs.lldb_11 ];
};
llvm_10 = {
llvm = pkgs.llvm_10;
extra = [ pkgs.lld_10 ]; # lldb marked as broken
extra = [ pkgs.llvmPackages_10.bintools ]; # lldb marked as broken
};
llvm_9 = {
llvm = pkgs.llvm_9;
extra = [ pkgs.lld_9 ]; # lldb marked as broken
extra = [ pkgs.llvmPackages_9.bintools ]; # lldb marked as broken
};
llvm_8 = {
llvm = pkgs.llvm_8;
extra = [ pkgs.lld_8 ]; # lldb marked as broken
extra = [ pkgs.llvmPackages_8.bintools ]; # lldb marked as broken
};
}."llvm_${toString llvm}");

Expand Down
160 changes: 160 additions & 0 deletions spec/compiler/codegen/exception_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1319,4 +1319,164 @@ describe "Code gen: exception" do
end
))
end

it "handles rescuing module type" do
run(%(
require "prelude"
module Foo; end
class Ex1 < Exception
include Foo
end
x = 0
begin
raise Ex1.new
rescue Foo
x = 1
end
x
)).to_i.should eq(1)
end

it "handles rescuing union between module type and class type" do
run(%(
require "prelude"
module Foo; end
abstract class BaseError < Exception; end
class Ex2 < BaseError; end
class Ex1 < BaseError
include Foo
end
x = 0
begin
raise Ex1.new
rescue Foo | BaseError
x = 1
end
x
)).to_i.should eq(1)
end

it "handles rescuing union between module types" do
run(%(
require "prelude"
module Foo; end
module Bar; end
class Ex1 < Exception
include Foo
end
class Ex2 < Exception
include Bar
end
x = 0
begin
raise Ex1.new
rescue Foo | Bar
x = 1
end
x
)).to_i.should eq(1)
end

it "does not rescue just any module" do
run(%(
require "prelude"
module Foo; end
module Bar; end
class Ex < Exception
include Foo
end
x = 0
begin
begin
raise Ex.new("oh no")
rescue Bar
x = 1
end
rescue ex
x = 2
end
x
)).to_i.should eq(2)
end

it "rescues a valid union" do
run(%(
require "prelude"
module Foo; end
module Bar; end
class Ex < Exception
include Foo
end
x = 0
begin
raise Ex.new("oh no")
rescue Union(Foo, Bar)
x = 1
end
x
)).to_i.should eq(1)
end

it "rescues a valid nested union" do
run(%(
require "prelude"
module Foo; end
module Bar; end
module Baz; end
class Ex < Exception
include Foo
end
x = 0
begin
raise Ex.new("oh no")
rescue Union(Baz, Union(Foo, Bar))
x = 1
end
x
)).to_i.should eq(1)
end

it "does not rescue just any union" do
run(%(
require "prelude"
module Foo; end
module Bar; end
module Baz; end
class Ex < Exception
include Foo
end
x = 0
begin
raise Ex.new("oh no")
rescue Union(Bar, Baz)
x = 1
rescue
x = 2
end
x
)).to_i.should eq(2)
end
end
50 changes: 40 additions & 10 deletions spec/compiler/normalize/regex_spec.cr
Original file line number Diff line number Diff line change
@@ -1,30 +1,60 @@
require "../../spec_helper"

private def assert_expand_regex_const(from : String, to, *, flags = nil, file = __FILE__, line = __LINE__)
from_nodes = Parser.parse(from)
assert_expand(from_nodes, flags: flags, file: file, line: line) do |to_nodes, program|
const = program.types[to_nodes.to_s].should be_a(Crystal::Const), file: file, line: line
const.value.to_s.should eq(to.strip), file: file, line: line
end
end

describe "Normalize: regex literal" do
describe "StringLiteral" do
it "expands to const" do
assert_expand Parser.parse(%q(/foo/)) do |to_nodes, program|
to_nodes.to_s.should eq "$Regex:0"
end
end

it "simple" do
assert_expand_regex_const %q(/foo/), <<-'CRYSTAL'
::Regex.new("foo", ::Regex::Options.new(0))
CRYSTAL
end
end

describe "StringInterpolation" do
it "simple" do
assert_expand %q(/#{"foo".to_s}/), <<-'CRYSTAL'
::Regex.new("#{"foo".to_s}", ::Regex::Options.new(0))
CRYSTAL
end
end

describe "options" do
it "empty" do
assert_expand %q(/#{"".to_s}/), <<-'CRYSTAL'
::Regex.new("#{"".to_s}", ::Regex::Options.new(0))
assert_expand_regex_const %q(//), <<-'CRYSTAL'
::Regex.new("", ::Regex::Options.new(0))
CRYSTAL
end
it "i" do
assert_expand %q(/#{"".to_s}/i), <<-'CRYSTAL'
::Regex.new("#{"".to_s}", ::Regex::Options.new(1))
assert_expand_regex_const %q(//i), <<-'CRYSTAL'
::Regex.new("", ::Regex::Options.new(1))
CRYSTAL
end
it "x" do
assert_expand %q(/#{"".to_s}/x), <<-'CRYSTAL'
::Regex.new("#{"".to_s}", ::Regex::Options.new(8))
assert_expand_regex_const %q(//x), <<-'CRYSTAL'
::Regex.new("", ::Regex::Options.new(8))
CRYSTAL
end
it "im" do
assert_expand %q(/#{"".to_s}/im), <<-'CRYSTAL'
::Regex.new("#{"".to_s}", ::Regex::Options.new(7))
assert_expand_regex_const %q(//im), <<-'CRYSTAL'
::Regex.new("", ::Regex::Options.new(7))
CRYSTAL
end
it "imx" do
assert_expand %q(/#{"".to_s}/imx), <<-'CRYSTAL'
::Regex.new("#{"".to_s}", ::Regex::Options.new(15))
assert_expand_regex_const %q(//imx), <<-'CRYSTAL'
::Regex.new("", ::Regex::Options.new(15))
CRYSTAL
end
end
Expand Down
12 changes: 10 additions & 2 deletions spec/compiler/semantic/exception_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,19 @@ describe "Semantic: exception" do
end

it "errors if caught exception is not a subclass of Exception" do
assert_error "begin; rescue ex : Int32; end", "Int32 is not a subclass of Exception"
assert_error "begin; rescue ex : Int32; end", "Int32 cannot be used for `rescue`. Only subclasses of `Exception` and modules, or unions thereof, are allowed."
end

it "errors if caught exception is a union but not all types are valid" do
assert_error "begin; rescue ex : Union(Exception, String); end", "(Exception | String) cannot be used for `rescue`. Only subclasses of `Exception` and modules, or unions thereof, are allowed."
end

it "errors if caught exception is a nested union but not all types are valid" do
assert_error "begin; rescue ex : Union(Exception, Union(Exception, String)); end", "(Exception | String) cannot be used for `rescue`. Only subclasses of `Exception` and modules, or unions thereof, are allowed."
end

it "errors if caught exception is not a subclass of Exception without var" do
assert_error "begin; rescue Int32; end", "Int32 is not a subclass of Exception"
assert_error "begin; rescue Int32; end", "Int32 cannot be used for `rescue`. Only subclasses of `Exception` and modules, or unions thereof, are allowed."
end

assert_syntax_error "begin; rescue ex; rescue ex : Foo; end; ex",
Expand Down
Loading

0 comments on commit fe54ddd

Please sign in to comment.