mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Merge branch 'trunk' into add-dec-types
This commit is contained in:
commit
de7cab629d
6 changed files with 197 additions and 41 deletions
|
@ -19,8 +19,7 @@ use crate::llvm::build_str::{
|
||||||
};
|
};
|
||||||
use crate::llvm::compare::{generic_eq, generic_neq};
|
use crate::llvm::compare::{generic_eq, generic_neq};
|
||||||
use crate::llvm::convert::{
|
use crate::llvm::convert::{
|
||||||
basic_type_from_builtin, basic_type_from_layout, block_of_memory, block_of_memory_slices,
|
basic_type_from_builtin, basic_type_from_layout, block_of_memory_slices, ptr_int,
|
||||||
ptr_int,
|
|
||||||
};
|
};
|
||||||
use crate::llvm::refcounting::{
|
use crate::llvm::refcounting::{
|
||||||
decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
|
decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
|
||||||
|
@ -1081,6 +1080,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
lookup_at_index_ptr2(
|
lookup_at_index_ptr2(
|
||||||
env,
|
env,
|
||||||
|
union_layout,
|
||||||
tag_id_type,
|
tag_id_type,
|
||||||
field_layouts,
|
field_layouts,
|
||||||
*index as usize,
|
*index as usize,
|
||||||
|
@ -1094,11 +1094,11 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
lookup_at_index_ptr(
|
lookup_at_index_ptr(
|
||||||
env,
|
env,
|
||||||
|
union_layout,
|
||||||
field_layouts,
|
field_layouts,
|
||||||
*index as usize,
|
*index as usize,
|
||||||
argument.into_pointer_value(),
|
argument.into_pointer_value(),
|
||||||
struct_type.into_struct_type(),
|
struct_type.into_struct_type(),
|
||||||
&struct_layout,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
UnionLayout::NullableWrapped {
|
UnionLayout::NullableWrapped {
|
||||||
|
@ -1121,6 +1121,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
lookup_at_index_ptr2(
|
lookup_at_index_ptr2(
|
||||||
env,
|
env,
|
||||||
|
union_layout,
|
||||||
tag_id_type,
|
tag_id_type,
|
||||||
field_layouts,
|
field_layouts,
|
||||||
*index as usize,
|
*index as usize,
|
||||||
|
@ -1141,12 +1142,12 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
lookup_at_index_ptr(
|
lookup_at_index_ptr(
|
||||||
env,
|
env,
|
||||||
|
union_layout,
|
||||||
field_layouts,
|
field_layouts,
|
||||||
// the tag id is not stored
|
// the tag id is not stored
|
||||||
*index as usize,
|
*index as usize,
|
||||||
argument.into_pointer_value(),
|
argument.into_pointer_value(),
|
||||||
struct_type.into_struct_type(),
|
struct_type.into_struct_type(),
|
||||||
&struct_layout,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1655,11 +1656,11 @@ pub fn get_tag_id<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
fn lookup_at_index_ptr<'a, 'ctx, 'env>(
|
fn lookup_at_index_ptr<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
union_layout: &UnionLayout<'a>,
|
||||||
field_layouts: &[Layout<'_>],
|
field_layouts: &[Layout<'_>],
|
||||||
index: usize,
|
index: usize,
|
||||||
value: PointerValue<'ctx>,
|
value: PointerValue<'ctx>,
|
||||||
struct_type: StructType<'ctx>,
|
struct_type: StructType<'ctx>,
|
||||||
structure_layout: &Layout<'_>,
|
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
|
||||||
|
@ -1681,11 +1682,13 @@ fn lookup_at_index_ptr<'a, 'ctx, 'env>(
|
||||||
if let Some(Layout::RecursivePointer) = field_layouts.get(index as usize) {
|
if let Some(Layout::RecursivePointer) = field_layouts.get(index as usize) {
|
||||||
// a recursive field is stored as a `i64*`, to use it we must cast it to
|
// a recursive field is stored as a `i64*`, to use it we must cast it to
|
||||||
// a pointer to the block of memory representation
|
// a pointer to the block of memory representation
|
||||||
|
let actual_type = basic_type_from_layout(env, &Layout::Union(*union_layout));
|
||||||
|
debug_assert!(actual_type.is_pointer_type());
|
||||||
|
|
||||||
builder.build_bitcast(
|
builder.build_bitcast(
|
||||||
result,
|
result,
|
||||||
block_of_memory(env.context, structure_layout, env.ptr_bytes)
|
actual_type,
|
||||||
.ptr_type(AddressSpace::Generic),
|
"cast_rec_pointer_lookup_at_index_ptr_old",
|
||||||
"cast_rec_pointer_lookup_at_index_ptr",
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
result
|
result
|
||||||
|
@ -1694,6 +1697,7 @@ fn lookup_at_index_ptr<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
fn lookup_at_index_ptr2<'a, 'ctx, 'env>(
|
fn lookup_at_index_ptr2<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
union_layout: &UnionLayout<'a>,
|
||||||
tag_id_type: IntType<'ctx>,
|
tag_id_type: IntType<'ctx>,
|
||||||
field_layouts: &[Layout<'_>],
|
field_layouts: &[Layout<'_>],
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -1731,17 +1735,13 @@ fn lookup_at_index_ptr2<'a, 'ctx, 'env>(
|
||||||
// a recursive field is stored as a `i64*`, to use it we must cast it to
|
// a recursive field is stored as a `i64*`, to use it we must cast it to
|
||||||
// a pointer to the block of memory representation
|
// a pointer to the block of memory representation
|
||||||
|
|
||||||
let tags = &[field_layouts];
|
let actual_type = basic_type_from_layout(env, &Layout::Union(*union_layout));
|
||||||
let struct_type = block_of_memory_slices(env.context, tags, env.ptr_bytes);
|
debug_assert!(actual_type.is_pointer_type());
|
||||||
|
|
||||||
let opaque_wrapper_type = env
|
|
||||||
.context
|
|
||||||
.struct_type(&[struct_type, tag_id_type.into()], false);
|
|
||||||
|
|
||||||
builder.build_bitcast(
|
builder.build_bitcast(
|
||||||
result,
|
result,
|
||||||
opaque_wrapper_type.ptr_type(AddressSpace::Generic),
|
actual_type,
|
||||||
"cast_rec_pointer_lookup_at_index_ptr",
|
"cast_rec_pointer_lookup_at_index_ptr_new",
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
result
|
result
|
||||||
|
|
|
@ -739,15 +739,20 @@ fn lowlevel_spec(
|
||||||
|
|
||||||
builder.add_sub_block(block, sub_block)
|
builder.add_sub_block(block, sub_block)
|
||||||
}
|
}
|
||||||
|
NumToFloat => {
|
||||||
|
// just dream up a unit value
|
||||||
|
builder.add_make_tuple(block, &[])
|
||||||
|
}
|
||||||
Eq | NotEq => {
|
Eq | NotEq => {
|
||||||
// just dream up a unit value
|
// just dream up a unit value
|
||||||
builder.add_make_tuple(block, &[])
|
builder.add_make_tuple(block, &[])
|
||||||
}
|
}
|
||||||
NumLte | NumLt | NumGt | NumGte => {
|
NumLte | NumLt | NumGt | NumGte | NumCompare => {
|
||||||
// just dream up a unit value
|
// just dream up a unit value
|
||||||
builder.add_make_tuple(block, &[])
|
builder.add_make_tuple(block, &[])
|
||||||
}
|
}
|
||||||
ListLen => {
|
ListLen | DictSize => {
|
||||||
|
// TODO should this touch the heap cell?
|
||||||
// just dream up a unit value
|
// just dream up a unit value
|
||||||
builder.add_make_tuple(block, &[])
|
builder.add_make_tuple(block, &[])
|
||||||
}
|
}
|
||||||
|
@ -775,7 +780,70 @@ fn lowlevel_spec(
|
||||||
|
|
||||||
Ok(list)
|
Ok(list)
|
||||||
}
|
}
|
||||||
|
ListAppend => {
|
||||||
|
let list = env.symbols[&arguments[0]];
|
||||||
|
let to_insert = env.symbols[&arguments[1]];
|
||||||
|
|
||||||
|
let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
|
||||||
|
let cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;
|
||||||
|
|
||||||
|
let _unit = builder.add_update(block, update_mode_var, cell)?;
|
||||||
|
|
||||||
|
builder.add_bag_insert(block, bag, to_insert)?;
|
||||||
|
|
||||||
|
Ok(list)
|
||||||
|
}
|
||||||
|
DictEmpty => {
|
||||||
|
match layout {
|
||||||
|
Layout::Builtin(Builtin::EmptyDict) => {
|
||||||
|
// just make up an element type
|
||||||
|
let type_id = builder.add_tuple_type(&[])?;
|
||||||
|
new_dict(builder, block, type_id, type_id)
|
||||||
|
}
|
||||||
|
Layout::Builtin(Builtin::Dict(key_layout, value_layout)) => {
|
||||||
|
let key_id = layout_spec(builder, key_layout)?;
|
||||||
|
let value_id = layout_spec(builder, value_layout)?;
|
||||||
|
new_dict(builder, block, key_id, value_id)
|
||||||
|
}
|
||||||
|
_ => unreachable!("empty array does not have a list layout"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DictGetUnsafe => {
|
||||||
|
// NOTE DictGetUnsafe returns a { flag: Bool, value: v }
|
||||||
|
// when the flag is True, the value is found and defined;
|
||||||
|
// otherwise it is not and `Dict.get` should return `Err ...`
|
||||||
|
|
||||||
|
let dict = env.symbols[&arguments[0]];
|
||||||
|
let key = env.symbols[&arguments[1]];
|
||||||
|
|
||||||
|
// indicate that we use the key
|
||||||
|
builder.add_recursive_touch(block, key)?;
|
||||||
|
|
||||||
|
let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?;
|
||||||
|
let cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?;
|
||||||
|
|
||||||
|
let _unit = builder.add_touch(block, cell)?;
|
||||||
|
|
||||||
|
builder.add_bag_get(block, bag)
|
||||||
|
}
|
||||||
|
DictInsert => {
|
||||||
|
let dict = env.symbols[&arguments[0]];
|
||||||
|
let key = env.symbols[&arguments[1]];
|
||||||
|
let value = env.symbols[&arguments[2]];
|
||||||
|
|
||||||
|
let key_value = builder.add_make_tuple(block, &[key, value])?;
|
||||||
|
|
||||||
|
let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?;
|
||||||
|
let cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?;
|
||||||
|
|
||||||
|
let _unit = builder.add_update(block, update_mode_var, cell)?;
|
||||||
|
|
||||||
|
builder.add_bag_insert(block, bag, key_value)?;
|
||||||
|
|
||||||
|
Ok(dict)
|
||||||
|
}
|
||||||
_other => {
|
_other => {
|
||||||
|
// println!("missing {:?}", _other);
|
||||||
// TODO overly pessimstic
|
// TODO overly pessimstic
|
||||||
let arguments: Vec<_> = arguments.iter().map(|symbol| env.symbols[symbol]).collect();
|
let arguments: Vec<_> = arguments.iter().map(|symbol| env.symbols[symbol]).collect();
|
||||||
|
|
||||||
|
@ -1041,6 +1109,18 @@ fn new_list(builder: &mut FuncDefBuilder, block: BlockId, element_type: TypeId)
|
||||||
builder.add_make_tuple(block, &[cell, bag])
|
builder.add_make_tuple(block, &[cell, bag])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_dict(
|
||||||
|
builder: &mut FuncDefBuilder,
|
||||||
|
block: BlockId,
|
||||||
|
key_type: TypeId,
|
||||||
|
value_type: TypeId,
|
||||||
|
) -> Result<ValueId> {
|
||||||
|
let cell = builder.add_new_heap_cell(block)?;
|
||||||
|
let element_type = builder.add_tuple_type(&[key_type, value_type])?;
|
||||||
|
let bag = builder.add_empty_bag(block, element_type)?;
|
||||||
|
builder.add_make_tuple(block, &[cell, bag])
|
||||||
|
}
|
||||||
|
|
||||||
fn new_static_string(builder: &mut FuncDefBuilder, block: BlockId) -> Result<ValueId> {
|
fn new_static_string(builder: &mut FuncDefBuilder, block: BlockId) -> Result<ValueId> {
|
||||||
let module = MOD_APP;
|
let module = MOD_APP;
|
||||||
|
|
||||||
|
|
|
@ -353,7 +353,7 @@ fn to_nonredundant_rows(
|
||||||
vec![simplify(&loc_pat.value)]
|
vec![simplify(&loc_pat.value)]
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_useful(checked_rows.clone(), next_row.clone()) {
|
if matches!(guard, Guard::HasGuard) || is_useful(checked_rows.clone(), next_row.clone()) {
|
||||||
checked_rows.push(next_row);
|
checked_rows.push(next_row);
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::Redundant {
|
return Err(Error::Redundant {
|
||||||
|
|
|
@ -503,7 +503,6 @@ fn when_on_single_value_tag() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn if_guard_multiple() {
|
fn if_guard_multiple() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
|
116
docs/src/lib.rs
116
docs/src/lib.rs
|
@ -350,15 +350,14 @@ fn new_line(buf: &mut String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &TypeAnnotation) {
|
fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &TypeAnnotation) {
|
||||||
|
let is_multiline = should_be_multiline(type_ann);
|
||||||
match type_ann {
|
match type_ann {
|
||||||
TypeAnnotation::TagUnion { tags, extension } => {
|
TypeAnnotation::TagUnion { tags, extension } => {
|
||||||
let tags_len = tags.len();
|
let tags_len = tags.len();
|
||||||
|
|
||||||
let more_than_one_tag = tags_len > 1;
|
|
||||||
|
|
||||||
let tag_union_indent = indent_level + 1;
|
let tag_union_indent = indent_level + 1;
|
||||||
|
|
||||||
if more_than_one_tag {
|
if is_multiline {
|
||||||
new_line(buf);
|
new_line(buf);
|
||||||
|
|
||||||
indent(buf, tag_union_indent);
|
indent(buf, tag_union_indent);
|
||||||
|
@ -366,14 +365,14 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
|
|
||||||
buf.push('[');
|
buf.push('[');
|
||||||
|
|
||||||
if more_than_one_tag {
|
if is_multiline {
|
||||||
new_line(buf);
|
new_line(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_indent_level = tag_union_indent + 1;
|
let next_indent_level = tag_union_indent + 1;
|
||||||
|
|
||||||
for (index, tag) in tags.iter().enumerate() {
|
for (index, tag) in tags.iter().enumerate() {
|
||||||
if more_than_one_tag {
|
if is_multiline {
|
||||||
indent(buf, next_indent_level);
|
indent(buf, next_indent_level);
|
||||||
} else {
|
} else {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
|
@ -386,7 +385,7 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
type_annotation_to_html(next_indent_level, buf, type_value);
|
type_annotation_to_html(next_indent_level, buf, type_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if more_than_one_tag {
|
if is_multiline {
|
||||||
if index < (tags_len - 1) {
|
if index < (tags_len - 1) {
|
||||||
buf.push(',');
|
buf.push(',');
|
||||||
}
|
}
|
||||||
|
@ -395,7 +394,7 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if more_than_one_tag {
|
if is_multiline {
|
||||||
indent(buf, tag_union_indent);
|
indent(buf, tag_union_indent);
|
||||||
} else {
|
} else {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
|
@ -424,24 +423,23 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
TypeAnnotation::Record { fields, extension } => {
|
TypeAnnotation::Record { fields, extension } => {
|
||||||
let fields_len = fields.len();
|
let fields_len = fields.len();
|
||||||
|
|
||||||
let more_than_one_field = fields_len > 1;
|
|
||||||
|
|
||||||
let record_indent = indent_level + 1;
|
let record_indent = indent_level + 1;
|
||||||
|
|
||||||
if more_than_one_field {
|
if is_multiline {
|
||||||
indent(buf, indent_level);
|
new_line(buf);
|
||||||
|
indent(buf, record_indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.push('{');
|
buf.push('{');
|
||||||
|
|
||||||
if more_than_one_field {
|
if is_multiline {
|
||||||
new_line(buf);
|
new_line(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_indent_level = record_indent + 1;
|
let next_indent_level = record_indent + 1;
|
||||||
|
|
||||||
for (index, field) in fields.iter().enumerate() {
|
for (index, field) in fields.iter().enumerate() {
|
||||||
if more_than_one_field {
|
if is_multiline {
|
||||||
indent(buf, next_indent_level);
|
indent(buf, next_indent_level);
|
||||||
} else {
|
} else {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
|
@ -471,7 +469,7 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
RecordField::LabelOnly { .. } => {}
|
RecordField::LabelOnly { .. } => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if more_than_one_field {
|
if is_multiline {
|
||||||
if index < (fields_len - 1) {
|
if index < (fields_len - 1) {
|
||||||
buf.push(',');
|
buf.push(',');
|
||||||
}
|
}
|
||||||
|
@ -480,7 +478,7 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if more_than_one_field {
|
if is_multiline {
|
||||||
indent(buf, record_indent);
|
indent(buf, record_indent);
|
||||||
} else {
|
} else {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
|
@ -491,11 +489,12 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
type_annotation_to_html(indent_level, buf, extension);
|
type_annotation_to_html(indent_level, buf, extension);
|
||||||
}
|
}
|
||||||
TypeAnnotation::Function { args, output } => {
|
TypeAnnotation::Function { args, output } => {
|
||||||
let more_than_one_arg = args.len() > 1;
|
|
||||||
let mut peekable_args = args.iter().peekable();
|
let mut peekable_args = args.iter().peekable();
|
||||||
while let Some(arg) = peekable_args.next() {
|
while let Some(arg) = peekable_args.next() {
|
||||||
if more_than_one_arg {
|
if is_multiline {
|
||||||
new_line(buf);
|
if !should_be_multiline(arg) {
|
||||||
|
new_line(buf);
|
||||||
|
}
|
||||||
indent(buf, indent_level + 1);
|
indent(buf, indent_level + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,13 +505,20 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if more_than_one_arg {
|
if is_multiline {
|
||||||
new_line(buf);
|
new_line(buf);
|
||||||
indent(buf, indent_level + 1);
|
indent(buf, indent_level + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.push_str(" -> ");
|
buf.push_str(" -> ");
|
||||||
type_annotation_to_html(indent_level, buf, output);
|
|
||||||
|
let mut next_indent_level = indent_level;
|
||||||
|
|
||||||
|
if should_be_multiline(output) {
|
||||||
|
next_indent_level += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_annotation_to_html(next_indent_level, buf, output);
|
||||||
}
|
}
|
||||||
TypeAnnotation::ObscuredTagUnion => {
|
TypeAnnotation::ObscuredTagUnion => {
|
||||||
buf.push_str("[ @.. ]");
|
buf.push_str("[ @.. ]");
|
||||||
|
@ -525,6 +531,76 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn should_be_multiline(type_ann: &TypeAnnotation) -> bool {
|
||||||
|
match type_ann {
|
||||||
|
TypeAnnotation::TagUnion { tags, extension } => {
|
||||||
|
let mut is_multiline = should_be_multiline(extension) || tags.len() > 1;
|
||||||
|
|
||||||
|
for tag in tags {
|
||||||
|
for value in &tag.values {
|
||||||
|
if is_multiline {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
is_multiline = should_be_multiline(&value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_multiline
|
||||||
|
}
|
||||||
|
TypeAnnotation::Function { args, output } => {
|
||||||
|
let mut is_multiline = should_be_multiline(output) || args.len() > 1;
|
||||||
|
|
||||||
|
for arg in args {
|
||||||
|
if is_multiline {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_multiline = should_be_multiline(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
is_multiline
|
||||||
|
}
|
||||||
|
TypeAnnotation::ObscuredTagUnion => false,
|
||||||
|
TypeAnnotation::ObscuredRecord => false,
|
||||||
|
TypeAnnotation::BoundVariable(_) => false,
|
||||||
|
TypeAnnotation::Apply { parts, .. } => {
|
||||||
|
let mut is_multiline = false;
|
||||||
|
|
||||||
|
for part in parts {
|
||||||
|
is_multiline = should_be_multiline(part);
|
||||||
|
|
||||||
|
if is_multiline {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_multiline
|
||||||
|
}
|
||||||
|
TypeAnnotation::Record { fields, extension } => {
|
||||||
|
let mut is_multiline = should_be_multiline(extension) || fields.len() > 1;
|
||||||
|
|
||||||
|
for field in fields {
|
||||||
|
if is_multiline {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
match field {
|
||||||
|
RecordField::RecordField {
|
||||||
|
type_annotation, ..
|
||||||
|
} => is_multiline = should_be_multiline(type_annotation),
|
||||||
|
RecordField::OptionalField {
|
||||||
|
type_annotation, ..
|
||||||
|
} => is_multiline = should_be_multiline(type_annotation),
|
||||||
|
RecordField::LabelOnly { .. } => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_multiline
|
||||||
|
}
|
||||||
|
TypeAnnotation::Wildcard => false,
|
||||||
|
TypeAnnotation::NoTypeAnn => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert_doc_links(scope: &mut Scope, interns: &Interns, markdown: String) -> String {
|
pub fn insert_doc_links(scope: &mut Scope, interns: &Interns, markdown: String) -> String {
|
||||||
let buf = &markdown;
|
let buf = &markdown;
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
|
|
|
@ -282,8 +282,9 @@ code {
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
color: var(--code-color);
|
color: var(--code-color);
|
||||||
background-color: var(--code-bg-color);
|
background-color: var(--code-bg-color);
|
||||||
padding: 2px 8px;
|
padding: 0 8px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
line-height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
code a {
|
code a {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue