Auto merge of #134959 - jhpratt:rollup-vxt40of, r=jhpratt

Rollup of 3 pull requests

Successful merges:

 - #134291 (Use python built in type annotations in LLDB visualizer scripts)
 - #134857 (Unsafe binder support in rustdoc)
 - #134957 (chore: fix some typos)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-12-31 10:36:06 +00:00
commit aea4e43703
14 changed files with 209 additions and 229 deletions

View file

@ -5,11 +5,11 @@ from rust_types import RustType, classify_struct, classify_union
# BACKCOMPAT: rust 1.35
def is_hashbrown_hashmap(hash_map):
def is_hashbrown_hashmap(hash_map: lldb.SBValue) -> bool:
return len(hash_map.type.fields) == 1
def classify_rust_type(type):
def classify_rust_type(type: lldb.SBType) -> str:
type_class = type.GetTypeClass()
if type_class == lldb.eTypeClassStruct:
return classify_struct(type.name, type.fields)
@ -19,106 +19,104 @@ def classify_rust_type(type):
return RustType.OTHER
def summary_lookup(valobj, dict):
# type: (SBValue, dict) -> str
def summary_lookup(valobj: lldb.SBValue, _dict: LLDBOpaque) -> str:
"""Returns the summary provider for the given value"""
rust_type = classify_rust_type(valobj.GetType())
if rust_type == RustType.STD_STRING:
return StdStringSummaryProvider(valobj, dict)
return StdStringSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_OS_STRING:
return StdOsStringSummaryProvider(valobj, dict)
return StdOsStringSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_STR:
return StdStrSummaryProvider(valobj, dict)
return StdStrSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_VEC:
return SizeSummaryProvider(valobj, dict)
return SizeSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_VEC_DEQUE:
return SizeSummaryProvider(valobj, dict)
return SizeSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_SLICE:
return SizeSummaryProvider(valobj, dict)
return SizeSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_HASH_MAP:
return SizeSummaryProvider(valobj, dict)
return SizeSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_HASH_SET:
return SizeSummaryProvider(valobj, dict)
return SizeSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_RC:
return StdRcSummaryProvider(valobj, dict)
return StdRcSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_ARC:
return StdRcSummaryProvider(valobj, dict)
return StdRcSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_REF:
return StdRefSummaryProvider(valobj, dict)
return StdRefSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_REF_MUT:
return StdRefSummaryProvider(valobj, dict)
return StdRefSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_REF_CELL:
return StdRefSummaryProvider(valobj, dict)
return StdRefSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_NONZERO_NUMBER:
return StdNonZeroNumberSummaryProvider(valobj, dict)
return StdNonZeroNumberSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_PATHBUF:
return StdPathBufSummaryProvider(valobj, dict)
return StdPathBufSummaryProvider(valobj, _dict)
if rust_type == RustType.STD_PATH:
return StdPathSummaryProvider(valobj, dict)
return StdPathSummaryProvider(valobj, _dict)
return ""
def synthetic_lookup(valobj, dict):
# type: (SBValue, dict) -> object
def synthetic_lookup(valobj: lldb.SBValue, _dict: LLDBOpaque) -> object:
"""Returns the synthetic provider for the given value"""
rust_type = classify_rust_type(valobj.GetType())
if rust_type == RustType.STRUCT:
return StructSyntheticProvider(valobj, dict)
return StructSyntheticProvider(valobj, _dict)
if rust_type == RustType.STRUCT_VARIANT:
return StructSyntheticProvider(valobj, dict, is_variant=True)
return StructSyntheticProvider(valobj, _dict, is_variant=True)
if rust_type == RustType.TUPLE:
return TupleSyntheticProvider(valobj, dict)
return TupleSyntheticProvider(valobj, _dict)
if rust_type == RustType.TUPLE_VARIANT:
return TupleSyntheticProvider(valobj, dict, is_variant=True)
return TupleSyntheticProvider(valobj, _dict, is_variant=True)
if rust_type == RustType.EMPTY:
return EmptySyntheticProvider(valobj, dict)
return EmptySyntheticProvider(valobj, _dict)
if rust_type == RustType.REGULAR_ENUM:
discriminant = valobj.GetChildAtIndex(0).GetChildAtIndex(0).GetValueAsUnsigned()
return synthetic_lookup(valobj.GetChildAtIndex(discriminant), dict)
return synthetic_lookup(valobj.GetChildAtIndex(discriminant), _dict)
if rust_type == RustType.SINGLETON_ENUM:
return synthetic_lookup(valobj.GetChildAtIndex(0), dict)
return synthetic_lookup(valobj.GetChildAtIndex(0), _dict)
if rust_type == RustType.ENUM:
return ClangEncodedEnumProvider(valobj, dict)
return ClangEncodedEnumProvider(valobj, _dict)
if rust_type == RustType.STD_VEC:
return StdVecSyntheticProvider(valobj, dict)
return StdVecSyntheticProvider(valobj, _dict)
if rust_type == RustType.STD_VEC_DEQUE:
return StdVecDequeSyntheticProvider(valobj, dict)
return StdVecDequeSyntheticProvider(valobj, _dict)
if rust_type == RustType.STD_SLICE or rust_type == RustType.STD_STR:
return StdSliceSyntheticProvider(valobj, dict)
return StdSliceSyntheticProvider(valobj, _dict)
if rust_type == RustType.STD_HASH_MAP:
if is_hashbrown_hashmap(valobj):
return StdHashMapSyntheticProvider(valobj, dict)
return StdHashMapSyntheticProvider(valobj, _dict)
else:
return StdOldHashMapSyntheticProvider(valobj, dict)
return StdOldHashMapSyntheticProvider(valobj, _dict)
if rust_type == RustType.STD_HASH_SET:
hash_map = valobj.GetChildAtIndex(0)
if is_hashbrown_hashmap(hash_map):
return StdHashMapSyntheticProvider(valobj, dict, show_values=False)
return StdHashMapSyntheticProvider(valobj, _dict, show_values=False)
else:
return StdOldHashMapSyntheticProvider(hash_map, dict, show_values=False)
return StdOldHashMapSyntheticProvider(hash_map, _dict, show_values=False)
if rust_type == RustType.STD_RC:
return StdRcSyntheticProvider(valobj, dict)
return StdRcSyntheticProvider(valobj, _dict)
if rust_type == RustType.STD_ARC:
return StdRcSyntheticProvider(valobj, dict, is_atomic=True)
return StdRcSyntheticProvider(valobj, _dict, is_atomic=True)
if rust_type == RustType.STD_CELL:
return StdCellSyntheticProvider(valobj, dict)
return StdCellSyntheticProvider(valobj, _dict)
if rust_type == RustType.STD_REF:
return StdRefSyntheticProvider(valobj, dict)
return StdRefSyntheticProvider(valobj, _dict)
if rust_type == RustType.STD_REF_MUT:
return StdRefSyntheticProvider(valobj, dict)
return StdRefSyntheticProvider(valobj, _dict)
if rust_type == RustType.STD_REF_CELL:
return StdRefSyntheticProvider(valobj, dict, is_cell=True)
return StdRefSyntheticProvider(valobj, _dict, is_cell=True)
return DefaultSyntheticProvider(valobj, dict)
return DefaultSyntheticProvider(valobj, _dict)

View file

@ -3,6 +3,7 @@ import sys
from lldb import (
SBData,
SBError,
SBValue,
eBasicTypeLong,
eBasicTypeUnsignedLong,
eBasicTypeUnsignedChar,
@ -44,24 +45,28 @@ from lldb import (
PY3 = sys.version_info[0] == 3
class LLDBOpaque:
"""
An marker type for use in type hints to denote LLDB bookkeeping variables. Values marked with
this type should never be used except when passing as an argument to an LLDB function.
"""
class ValueBuilder:
def __init__(self, valobj):
# type: (SBValue) -> ValueBuilder
def __init__(self, valobj: SBValue):
self.valobj = valobj
process = valobj.GetProcess()
self.endianness = process.GetByteOrder()
self.pointer_size = process.GetAddressByteSize()
def from_int(self, name, value):
# type: (str, int) -> SBValue
def from_int(self, name: str, value: int) -> SBValue:
type = self.valobj.GetType().GetBasicType(eBasicTypeLong)
data = SBData.CreateDataFromSInt64Array(
self.endianness, self.pointer_size, [value]
)
return self.valobj.CreateValueFromData(name, data, type)
def from_uint(self, name, value):
# type: (str, int) -> SBValue
def from_uint(self, name: str, value: int) -> SBValue:
type = self.valobj.GetType().GetBasicType(eBasicTypeUnsignedLong)
data = SBData.CreateDataFromUInt64Array(
self.endianness, self.pointer_size, [value]
@ -69,7 +74,7 @@ class ValueBuilder:
return self.valobj.CreateValueFromData(name, data, type)
def unwrap_unique_or_non_null(unique_or_nonnull):
def unwrap_unique_or_non_null(unique_or_nonnull: SBValue) -> SBValue:
# BACKCOMPAT: rust 1.32
# https://github.com/rust-lang/rust/commit/7a0911528058e87d22ea305695f4047572c5e067
# BACKCOMPAT: rust 1.60
@ -79,67 +84,54 @@ def unwrap_unique_or_non_null(unique_or_nonnull):
class DefaultSyntheticProvider:
def __init__(self, valobj, dict):
# type: (SBValue, dict) -> DefaultSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
# logger = Logger.Logger()
# logger >> "Default synthetic provider for " + str(valobj.GetName())
self.valobj = valobj
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return self.valobj.GetNumChildren()
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
return self.valobj.GetIndexOfChildWithName(name)
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
return self.valobj.GetChildAtIndex(index)
def update(self):
# type: () -> None
pass
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return self.valobj.MightHaveChildren()
class EmptySyntheticProvider:
def __init__(self, valobj, dict):
# type: (SBValue, dict) -> EmptySyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
# logger = Logger.Logger()
# logger >> "[EmptySyntheticProvider] for " + str(valobj.GetName())
self.valobj = valobj
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return 0
def get_child_index(self, name):
# type: (str) -> int
return None
def get_child_index(self, name: str) -> int:
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
return None
def update(self):
# type: () -> None
pass
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return False
def SizeSummaryProvider(valobj, dict):
# type: (SBValue, dict) -> str
def SizeSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
return "size=" + str(valobj.GetNumChildren())
def vec_to_string(vec):
def vec_to_string(vec: SBValue) -> str:
length = vec.GetNumChildren()
chars = [vec.GetChildAtIndex(i).GetValueAsUnsigned() for i in range(length)]
return (
@ -149,16 +141,14 @@ def vec_to_string(vec):
)
def StdStringSummaryProvider(valobj, dict):
# type: (SBValue, dict) -> str
def StdStringSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
# logger = Logger.Logger()
# logger >> "[StdStringSummaryProvider] for " + str(valobj.GetName())
vec = valobj.GetChildAtIndex(0)
return '"%s"' % vec_to_string(vec)
def StdOsStringSummaryProvider(valobj, dict):
# type: (SBValue, dict) -> str
def StdOsStringSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
# logger = Logger.Logger()
# logger >> "[StdOsStringSummaryProvider] for " + str(valobj.GetName())
buf = valobj.GetChildAtIndex(0).GetChildAtIndex(0)
@ -167,8 +157,7 @@ def StdOsStringSummaryProvider(valobj, dict):
return '"%s"' % vec_to_string(vec)
def StdStrSummaryProvider(valobj, dict):
# type: (SBValue, dict) -> str
def StdStrSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
# logger = Logger.Logger()
# logger >> "[StdStrSummaryProvider] for " + str(valobj.GetName())
@ -189,15 +178,13 @@ def StdStrSummaryProvider(valobj, dict):
return '"%s"' % data
def StdPathBufSummaryProvider(valobj, dict):
# type: (SBValue, dict) -> str
def StdPathBufSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
# logger = Logger.Logger()
# logger >> "[StdPathBufSummaryProvider] for " + str(valobj.GetName())
return StdOsStringSummaryProvider(valobj.GetChildMemberWithName("inner"), dict)
return StdOsStringSummaryProvider(valobj.GetChildMemberWithName("inner"), _dict)
def StdPathSummaryProvider(valobj, dict):
# type: (SBValue, dict) -> str
def StdPathSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
# logger = Logger.Logger()
# logger >> "[StdPathSummaryProvider] for " + str(valobj.GetName())
length = valobj.GetChildMemberWithName("length").GetValueAsUnsigned()
@ -221,8 +208,7 @@ def StdPathSummaryProvider(valobj, dict):
class StructSyntheticProvider:
"""Pretty-printer for structs and struct enum variants"""
def __init__(self, valobj, dict, is_variant=False):
# type: (SBValue, dict, bool) -> StructSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_variant: bool = False):
# logger = Logger.Logger()
self.valobj = valobj
self.is_variant = is_variant
@ -239,16 +225,13 @@ class StructSyntheticProvider:
for number, field in enumerate(real_fields):
self.fields[field.name] = number
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return self.fields_count
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
return self.fields.get(name, -1)
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
if self.is_variant:
field = self.type.GetFieldAtIndex(index + 1)
else:
@ -259,8 +242,7 @@ class StructSyntheticProvider:
# type: () -> None
pass
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
@ -270,26 +252,26 @@ class ClangEncodedEnumProvider:
DISCRIMINANT_MEMBER_NAME = "$discr$"
VALUE_MEMBER_NAME = "value"
def __init__(self, valobj, dict):
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
self.valobj = valobj
self.update()
def has_children(self):
def has_children(self) -> bool:
return True
def num_children(self):
def num_children(self) -> int:
if self.is_default:
return 1
return 2
def get_child_index(self, name):
def get_child_index(self, name: str) -> int:
if name == ClangEncodedEnumProvider.VALUE_MEMBER_NAME:
return 0
if name == ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME:
return 1
return -1
def get_child_at_index(self, index):
def get_child_at_index(self, index: int) -> SBValue:
if index == 0:
return self.variant.GetChildMemberWithName(
ClangEncodedEnumProvider.VALUE_MEMBER_NAME
@ -310,7 +292,7 @@ class ClangEncodedEnumProvider:
== -1
)
def _getCurrentVariantIndex(self, all_variants):
def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
default_index = 0
for i in range(all_variants.GetNumChildren()):
variant = all_variants.GetChildAtIndex(i)
@ -329,8 +311,7 @@ class ClangEncodedEnumProvider:
class TupleSyntheticProvider:
"""Pretty-printer for tuples and tuple enum variants"""
def __init__(self, valobj, dict, is_variant=False):
# type: (SBValue, dict, bool) -> TupleSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_variant: bool = False):
# logger = Logger.Logger()
self.valobj = valobj
self.is_variant = is_variant
@ -341,19 +322,16 @@ class TupleSyntheticProvider:
else:
self.size = self.type.GetNumberOfFields()
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return self.size
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
if name.isdigit():
return int(name)
else:
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
if self.is_variant:
field = self.type.GetFieldAtIndex(index + 1)
else:
@ -364,11 +342,9 @@ class TupleSyntheticProvider:
)
def update(self):
# type: () -> None
pass
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
@ -385,27 +361,23 @@ class StdVecSyntheticProvider:
struct NonNull<T> { pointer: *const T }
"""
def __init__(self, valobj, dict):
# type: (SBValue, dict) -> StdVecSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
# logger = Logger.Logger()
# logger >> "[StdVecSyntheticProvider] for " + str(valobj.GetName())
self.valobj = valobj
self.update()
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return self.length
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
index = name.lstrip("[").rstrip("]")
if index.isdigit():
return int(index)
else:
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
start = self.data_ptr.GetValueAsUnsigned()
address = start + index * self.element_type_size
element = self.data_ptr.CreateValueFromAddress(
@ -414,7 +386,6 @@ class StdVecSyntheticProvider:
return element
def update(self):
# type: () -> None
self.length = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
self.buf = self.valobj.GetChildMemberWithName("buf").GetChildMemberWithName(
"inner"
@ -427,30 +398,26 @@ class StdVecSyntheticProvider:
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
self.element_type_size = self.element_type.GetByteSize()
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
class StdSliceSyntheticProvider:
def __init__(self, valobj, dict):
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
self.valobj = valobj
self.update()
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return self.length
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
index = name.lstrip("[").rstrip("]")
if index.isdigit():
return int(index)
else:
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
start = self.data_ptr.GetValueAsUnsigned()
address = start + index * self.element_type_size
element = self.data_ptr.CreateValueFromAddress(
@ -459,15 +426,13 @@ class StdSliceSyntheticProvider:
return element
def update(self):
# type: () -> None
self.length = self.valobj.GetChildMemberWithName("length").GetValueAsUnsigned()
self.data_ptr = self.valobj.GetChildMemberWithName("data_ptr")
self.element_type = self.data_ptr.GetType().GetPointeeType()
self.element_type_size = self.element_type.GetByteSize()
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
@ -477,27 +442,23 @@ class StdVecDequeSyntheticProvider:
struct VecDeque<T> { head: usize, len: usize, buf: RawVec<T> }
"""
def __init__(self, valobj, dict):
# type: (SBValue, dict) -> StdVecDequeSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
# logger = Logger.Logger()
# logger >> "[StdVecDequeSyntheticProvider] for " + str(valobj.GetName())
self.valobj = valobj
self.update()
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return self.size
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
index = name.lstrip("[").rstrip("]")
if index.isdigit() and int(index) < self.size:
return int(index)
else:
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
start = self.data_ptr.GetValueAsUnsigned()
address = start + ((index + self.head) % self.cap) * self.element_type_size
element = self.data_ptr.CreateValueFromAddress(
@ -506,7 +467,6 @@ class StdVecDequeSyntheticProvider:
return element
def update(self):
# type: () -> None
self.head = self.valobj.GetChildMemberWithName("head").GetValueAsUnsigned()
self.size = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
self.buf = self.valobj.GetChildMemberWithName("buf").GetChildMemberWithName(
@ -524,8 +484,7 @@ class StdVecDequeSyntheticProvider:
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
self.element_type_size = self.element_type.GetByteSize()
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
@ -537,26 +496,22 @@ class StdOldHashMapSyntheticProvider:
struct RawTable<K, V> { capacity_mask: usize, size: usize, hashes: TaggedHashUintPtr, ... }
"""
def __init__(self, valobj, dict, show_values=True):
# type: (SBValue, dict, bool) -> StdOldHashMapSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque, show_values: bool = True):
self.valobj = valobj
self.show_values = show_values
self.update()
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return self.size
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
index = name.lstrip("[").rstrip("]")
if index.isdigit():
return int(index)
else:
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
# logger = Logger.Logger()
start = self.data_ptr.GetValueAsUnsigned() & ~1
@ -592,7 +547,6 @@ class StdOldHashMapSyntheticProvider:
)
def update(self):
# type: () -> None
# logger = Logger.Logger()
self.table = self.valobj.GetChildMemberWithName("table") # type: SBValue
@ -624,34 +578,29 @@ class StdOldHashMapSyntheticProvider:
# logger >> "Valid indices: {}".format(str(self.valid_indices))
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
class StdHashMapSyntheticProvider:
"""Pretty-printer for hashbrown's HashMap"""
def __init__(self, valobj, dict, show_values=True):
# type: (SBValue, dict, bool) -> StdHashMapSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque, show_values: bool = True):
self.valobj = valobj
self.show_values = show_values
self.update()
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return self.size
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
index = name.lstrip("[").rstrip("]")
if index.isdigit():
return int(index)
else:
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
pairs_start = self.data_ptr.GetValueAsUnsigned()
idx = self.valid_indices[index]
if self.new_layout:
@ -669,7 +618,6 @@ class StdHashMapSyntheticProvider:
)
def update(self):
# type: () -> None
table = self.table()
inner_table = table.GetChildMemberWithName("table")
@ -707,8 +655,7 @@ class StdHashMapSyntheticProvider:
if is_present:
self.valid_indices.append(idx)
def table(self):
# type: () -> SBValue
def table(self) -> SBValue:
if self.show_values:
hashbrown_hashmap = self.valobj.GetChildMemberWithName("base")
else:
@ -718,13 +665,11 @@ class StdHashMapSyntheticProvider:
hashbrown_hashmap = self.valobj.GetChildAtIndex(0).GetChildAtIndex(0)
return hashbrown_hashmap.GetChildMemberWithName("table")
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
def StdRcSummaryProvider(valobj, dict):
# type: (SBValue, dict) -> str
def StdRcSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
strong = valobj.GetChildMemberWithName("strong").GetValueAsUnsigned()
weak = valobj.GetChildMemberWithName("weak").GetValueAsUnsigned()
return "strong={}, weak={}".format(strong, weak)
@ -746,8 +691,7 @@ class StdRcSyntheticProvider:
struct AtomicUsize { v: UnsafeCell<usize> }
"""
def __init__(self, valobj, dict, is_atomic=False):
# type: (SBValue, dict, bool) -> StdRcSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_atomic: bool = False):
self.valobj = valobj
self.ptr = unwrap_unique_or_non_null(self.valobj.GetChildMemberWithName("ptr"))
@ -769,13 +713,11 @@ class StdRcSyntheticProvider:
self.update()
def num_children(self):
# type: () -> int
def num_children(self) -> int:
# Actually there are 3 children, but only the `value` should be shown as a child
return 1
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
if name == "value":
return 0
if name == "strong":
@ -784,8 +726,7 @@ class StdRcSyntheticProvider:
return 2
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
if index == 0:
return self.value
if index == 1:
@ -796,50 +737,41 @@ class StdRcSyntheticProvider:
return None
def update(self):
# type: () -> None
self.strong_count = self.strong.GetValueAsUnsigned()
self.weak_count = self.weak.GetValueAsUnsigned() - 1
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
class StdCellSyntheticProvider:
"""Pretty-printer for std::cell::Cell"""
def __init__(self, valobj, dict):
# type: (SBValue, dict) -> StdCellSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
self.valobj = valobj
self.value = valobj.GetChildMemberWithName("value").GetChildAtIndex(0)
def num_children(self):
# type: () -> int
def num_children(self) -> int:
return 1
def get_child_index(self, name):
# type: (str) -> int
def get_child_index(self, name: str) -> int:
if name == "value":
return 0
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
if index == 0:
return self.value
return None
def update(self):
# type: () -> None
pass
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
def StdRefSummaryProvider(valobj, dict):
# type: (SBValue, dict) -> str
def StdRefSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
borrow = valobj.GetChildMemberWithName("borrow").GetValueAsSigned()
return (
"borrow={}".format(borrow) if borrow >= 0 else "borrow_mut={}".format(-borrow)
@ -849,8 +781,7 @@ def StdRefSummaryProvider(valobj, dict):
class StdRefSyntheticProvider:
"""Pretty-printer for std::cell::Ref, std::cell::RefMut, and std::cell::RefCell"""
def __init__(self, valobj, dict, is_cell=False):
# type: (SBValue, dict, bool) -> StdRefSyntheticProvider
def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_cell: bool = False):
self.valobj = valobj
borrow = valobj.GetChildMemberWithName("borrow")
@ -872,20 +803,18 @@ class StdRefSyntheticProvider:
self.update()
def num_children(self):
# type: () -> int
def num_children(self) -> int:
# Actually there are 2 children, but only the `value` should be shown as a child
return 1
def get_child_index(self, name):
def get_child_index(self, name: str) -> int:
if name == "value":
return 0
if name == "borrow":
return 1
return -1
def get_child_at_index(self, index):
# type: (int) -> SBValue
def get_child_at_index(self, index: int) -> SBValue:
if index == 0:
return self.value
if index == 1:
@ -893,16 +822,13 @@ class StdRefSyntheticProvider:
return None
def update(self):
# type: () -> None
self.borrow_count = self.borrow.GetValueAsSigned()
def has_children(self):
# type: () -> bool
def has_children(self) -> bool:
return True
def StdNonZeroNumberSummaryProvider(valobj, _dict):
# type: (SBValue, dict) -> str
def StdNonZeroNumberSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
inner = valobj.GetChildAtIndex(0)
inner_inner = inner.GetChildAtIndex(0)

View file

@ -1,3 +1,4 @@
from typing import List
import re
@ -85,12 +86,11 @@ STD_TYPE_TO_REGEX = {
}
def is_tuple_fields(fields):
# type: (list) -> bool
def is_tuple_fields(fields: List) -> bool:
return all(TUPLE_ITEM_REGEX.match(str(field.name)) for field in fields)
def classify_struct(name, fields):
def classify_struct(name: str, fields: List) -> str:
if len(fields) == 0:
return RustType.EMPTY
@ -111,7 +111,7 @@ def classify_struct(name, fields):
return RustType.STRUCT
def classify_union(fields):
def classify_union(fields: List) -> str:
if len(fields) == 0:
return RustType.EMPTY

View file

@ -1844,8 +1844,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
DynTrait(bounds, lifetime)
}
TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
TyKind::UnsafeBinder(..) => {
unimplemented!("unsafe binders are not supported yet")
TyKind::UnsafeBinder(unsafe_binder_ty) => {
UnsafeBinder(Box::new(clean_unsafe_binder_ty(unsafe_binder_ty, cx)))
}
// Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
TyKind::Infer
@ -2075,6 +2075,11 @@ pub(crate) fn clean_middle_ty<'tcx>(
abi: sig.abi(),
}))
}
ty::UnsafeBinder(inner) => {
let generic_params = clean_bound_vars(inner.bound_vars());
let ty = clean_middle_ty(inner.into(), cx, None, None);
UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, ty }))
}
ty::Adt(def, args) => {
let did = def.did();
let kind = match def.adt_kind() {
@ -2253,7 +2258,6 @@ pub(crate) fn clean_middle_ty<'tcx>(
}
}
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binders)"),
ty::Closure(..) => panic!("Closure"),
ty::CoroutineClosure(..) => panic!("CoroutineClosure"),
ty::Coroutine(..) => panic!("Coroutine"),
@ -2564,6 +2568,21 @@ fn clean_bare_fn_ty<'tcx>(
BareFunctionDecl { safety: bare_fn.safety, abi: bare_fn.abi, decl, generic_params }
}
fn clean_unsafe_binder_ty<'tcx>(
unsafe_binder_ty: &hir::UnsafeBinderTy<'tcx>,
cx: &mut DocContext<'tcx>,
) -> UnsafeBinderTy {
// NOTE: generics must be cleaned before args
let generic_params = unsafe_binder_ty
.generic_params
.iter()
.filter(|p| !is_elided_lifetime(p))
.map(|x| clean_generic_param(cx, None, x))
.collect();
let ty = clean_ty(unsafe_binder_ty.inner_ty, cx);
UnsafeBinderTy { generic_params, ty }
}
pub(crate) fn reexport_chain(
tcx: TyCtxt<'_>,
import_def_id: LocalDefId,

View file

@ -32,7 +32,7 @@ use {rustc_ast as ast, rustc_hir as hir};
pub(crate) use self::ItemKind::*;
pub(crate) use self::Type::{
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
RawPointer, SelfTy, Slice, Tuple,
RawPointer, SelfTy, Slice, Tuple, UnsafeBinder,
};
use crate::clean::cfg::Cfg;
use crate::clean::clean_middle_path;
@ -1511,6 +1511,8 @@ pub(crate) enum Type {
/// An `impl Trait`: `impl TraitA + TraitB + ...`
ImplTrait(Vec<GenericBound>),
UnsafeBinder(Box<UnsafeBinderTy>),
}
impl Type {
@ -1703,7 +1705,7 @@ impl Type {
Type::Pat(..) => PrimitiveType::Pat,
RawPointer(..) => PrimitiveType::RawPointer,
QPath(box QPathData { ref self_type, .. }) => return self_type.def_id(cache),
Generic(_) | SelfTy | Infer | ImplTrait(_) => return None,
Generic(_) | SelfTy | Infer | ImplTrait(_) | UnsafeBinder(_) => return None,
};
Primitive(t).def_id(cache)
}
@ -2343,6 +2345,12 @@ pub(crate) struct BareFunctionDecl {
pub(crate) abi: ExternAbi,
}
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub(crate) struct UnsafeBinderTy {
pub(crate) generic_params: Vec<GenericParamDef>,
pub(crate) ty: Type,
}
#[derive(Clone, Debug)]
pub(crate) struct Static {
pub(crate) type_: Box<Type>,

View file

@ -282,7 +282,8 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
match pred {
clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
print_higher_ranked_params_with_space(bound_params, cx).fmt(f)?;
print_higher_ranked_params_with_space(bound_params, cx, "for")
.fmt(f)?;
ty.print(cx).fmt(f)?;
f.write_str(":")?;
if !bounds.is_empty() {
@ -386,7 +387,7 @@ impl clean::ConstantKind {
impl clean::PolyTrait {
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
display_fn(move |f| {
print_higher_ranked_params_with_space(&self.generic_params, cx).fmt(f)?;
print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?;
self.trait_.print(cx).fmt(f)
})
}
@ -968,10 +969,12 @@ fn tybounds<'a, 'tcx: 'a>(
fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
params: &'a [clean::GenericParamDef],
cx: &'a Context<'tcx>,
keyword: &'static str,
) -> impl Display + 'a + Captures<'tcx> {
display_fn(move |f| {
if !params.is_empty() {
f.write_str(if f.alternate() { "for<" } else { "for&lt;" })?;
f.write_str(keyword)?;
f.write_str(if f.alternate() { "<" } else { "&lt;" })?;
comma_sep(params.iter().map(|lt| lt.print(cx)), true).fmt(f)?;
f.write_str(if f.alternate() { "> " } else { "&gt; " })?;
}
@ -1027,7 +1030,7 @@ fn fmt_type(
primitive_link(f, prim, format_args!("{}", prim.as_sym().as_str()), cx)
}
clean::BareFunction(ref decl) => {
print_higher_ranked_params_with_space(&decl.generic_params, cx).fmt(f)?;
print_higher_ranked_params_with_space(&decl.generic_params, cx, "for").fmt(f)?;
decl.safety.print_with_space().fmt(f)?;
print_abi_with_space(decl.abi).fmt(f)?;
if f.alternate() {
@ -1037,6 +1040,10 @@ fn fmt_type(
}
decl.decl.print(cx).fmt(f)
}
clean::UnsafeBinder(ref binder) => {
print_higher_ranked_params_with_space(&binder.generic_params, cx, "unsafe").fmt(f)?;
binder.ty.print(cx).fmt(f)
}
clean::Tuple(ref typs) => match &typs[..] {
&[] => primitive_link(f, PrimitiveType::Unit, format_args!("()"), cx),
[one] => {
@ -1354,7 +1361,7 @@ impl clean::Impl {
// Hardcoded anchor library/core/src/primitive_docs.rs
// Link should match `# Trait implementations`
print_higher_ranked_params_with_space(&bare_fn.generic_params, cx).fmt(f)?;
print_higher_ranked_params_with_space(&bare_fn.generic_params, cx, "for").fmt(f)?;
bare_fn.safety.print_with_space().fmt(f)?;
print_abi_with_space(bare_fn.abi).fmt(f)?;
let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" };

View file

@ -900,7 +900,8 @@ fn get_index_type_id(
| clean::Generic(_)
| clean::SelfTy
| clean::ImplTrait(_)
| clean::Infer => None,
| clean::Infer
| clean::UnsafeBinder(_) => None,
}
}

View file

@ -573,7 +573,7 @@ impl FromClean<clean::Type> for Type {
fn from_clean(ty: clean::Type, renderer: &JsonRenderer<'_>) -> Self {
use clean::Type::{
Array, BareFunction, BorrowedRef, Generic, ImplTrait, Infer, Primitive, QPath,
RawPointer, SelfTy, Slice, Tuple,
RawPointer, SelfTy, Slice, Tuple, UnsafeBinder,
};
match ty {
@ -613,6 +613,8 @@ impl FromClean<clean::Type> for Type {
self_type: Box::new(self_type.into_json(renderer)),
trait_: trait_.map(|trait_| trait_.into_json(renderer)),
},
// FIXME(unsafe_binder): Implement rustdoc-json.
UnsafeBinder(_) => todo!(),
}
}
}

View file

@ -21,7 +21,7 @@
/// }
/// ```
///
/// But this shoudln't produce a warning:
/// But this shouldn't produce a warning:
/// ```rust,no_run
/// # extern crate pub_trait;
/// # use pub_trait::Trait;

View file

@ -0,0 +1,4 @@
#![feature(unsafe_binders)]
#![allow(incomplete_features)]
pub fn woof() -> unsafe<'a> &'a str { todo!() }

View file

@ -0,0 +1,15 @@
//@ aux-build:unsafe-binder-dep.rs
#![feature(unsafe_binders)]
#![allow(incomplete_features)]
extern crate unsafe_binder_dep;
//@ has 'unsafe_binder/fn.woof.html' //pre "fn woof() -> unsafe<'a> &'a str"
pub use unsafe_binder_dep::woof;
//@ has 'unsafe_binder/fn.meow.html' //pre "fn meow() -> unsafe<'a> &'a str"
pub fn meow() -> unsafe<'a> &'a str { todo!() }
//@ has 'unsafe_binder/fn.meow_squared.html' //pre "fn meow_squared() -> unsafe<'b, 'a> &'a &'b str"
pub fn meow_squared() -> unsafe<'b, 'a> &'a &'b str { todo!() }

View file

@ -6,7 +6,7 @@ fn func(func_arg: &mut V) {
|| {
// Declaring `x` separately instead of using
// a destructuring binding like `let V(x) = ...`
// becaue only `V(x) = ...` triggers the ICE
// because only `V(x) = ...` triggers the ICE
let x;
V(x) = func_arg; //~ ERROR: mismatched types
func_arg.0 = 0;

View file

@ -6,7 +6,7 @@
// to process this `'r` region bound. In particular, to be WF, the
// region bound must meet the requirements of the trait, and hence we
// got `for<'r> { 'r: 'static }`. This would ICE because the `Binder`
// constructor we were using was assering that no higher-ranked
// constructor we were using was asserting that no higher-ranked
// regions were involved (because the WF code is supposed to skip
// those). The error (if debug-asserions were disabled) came because
// we obviously cannot prove that `'r: 'static` for any region `'r`.

View file

@ -17,7 +17,7 @@
// `__rust_{begin,end}_short_backtrace` markers, which only appear in full
// backtraces. The rest of the backtrace is filtered out.
//
// Ignored on msvc becaue the `__rust_{begin,end}_short_backtrace` symbols
// Ignored on msvc because the `__rust_{begin,end}_short_backtrace` symbols
// aren't reliable.
fn main() { missing_ident; }