Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: JuliaLang/julia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 45b2b81c6a015a39958e8827df2aa992c1cab8cc
Choose a base ref
..
head repository: JuliaLang/julia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d22ab50b5bced55e1a46995ffd020e51c0bcb007
Choose a head ref
Showing with 23 additions and 5 deletions.
  1. +1 −1 base/namedtuple.jl
  2. +16 −4 src/jltypes.c
  3. +6 −0 test/namedtuple.jl
2 changes: 1 addition & 1 deletion base/namedtuple.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

@generated function namedtuple(::Type{NamedTuple{names,T} where T}, args...) where names
@generated function namedtuple(::Type{NamedTuple{names}}, args...) where names
N = length(names)
if length(args) == N
Expr(:new, :(NamedTuple{names,$(Tuple{args...})}), Any[ :(args[$i]) for i in 1:N ]...)
20 changes: 16 additions & 4 deletions src/jltypes.c
Original file line number Diff line number Diff line change
@@ -1136,9 +1136,19 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
else if (isnamedtuple) {
jl_value_t *names_tup = jl_svecref(p, 0);
jl_value_t *values_tt = jl_svecref(p, 1);
if (jl_is_tuple_type(values_tt) && jl_is_tuple(names_tup)) {
jl_svec_t *names = jl_alloc_svec_uninit(jl_nfields(names_tup));
memcpy(jl_svec_data(names), (jl_value_t**)names_tup, jl_nfields(names_tup)*sizeof(jl_value_t*));
if (!jl_has_free_typevars(names_tup) && !jl_has_free_typevars(values_tt)) {
if (!jl_is_tuple(names_tup))
jl_type_error_rt("NamedTuple", "names", jl_anytuple_type, names_tup);
size_t nf = jl_nfields(names_tup);
jl_svec_t *names = jl_alloc_svec_uninit(nf);
for(size_t i = 0; i < nf; i++) {
jl_value_t *ni = jl_fieldref(names_tup, i);
if (!jl_is_symbol(ni))
jl_type_error_rt("NamedTuple", "name", jl_symbol_type, ni);
jl_svecset(names, i, ni);
}
if (jl_is_va_tuple(values_tt) || jl_nparams(values_tt) != nf)
jl_error("NamedTuple names and field types must have matching lengths");
ndt->names = names;
jl_gc_wb(ndt, ndt->names);
ndt->types = ((jl_datatype_t*)values_tt)->parameters;
@@ -2049,7 +2059,9 @@ void jl_init_types(void)
jl_perm_symsvec(1, "len"), jl_svec1(jl_long_type),
0, 1, 1);

tv = jl_svec2(tvar("names"), tvar("T"));
jl_tvar_t *ntval_var = jl_new_typevar(jl_symbol("T"), (jl_value_t*)jl_bottom_type,
(jl_value_t*)jl_anytuple_type);
tv = jl_svec2(tvar("names"), ntval_var);
jl_datatype_t *ntt = jl_new_datatype(jl_symbol("NamedTuple"), jl_any_type, tv,
jl_emptysvec, jl_emptysvec, 0, 0, 0);
jl_namedtuple_type = (jl_unionall_t*)ntt->name->wrapper;
6 changes: 6 additions & 0 deletions test/namedtuple.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

@test_throws TypeError NamedTuple{1,Tuple{}}
@test_throws TypeError NamedTuple{(),1}
@test_throws TypeError NamedTuple{(:a,1),Tuple{Int}}
@test_throws ErrorException NamedTuple{(:a,:b),Tuple{Int}}
@test_throws ErrorException NamedTuple{(:a,:b),Tuple{Int,Vararg{Int}}}

@test (a=1,).a == 1
@test (a=2,)[1] == 2
@test (a=3,)[:a] == 3