diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py index abbd802dcdd12..f4ea904b7f50b 100644 --- a/src/etc/lldb_lookup.py +++ b/src/etc/lldb_lookup.py @@ -5,11 +5,11 @@ # 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) diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index c24ec8ab31091..2f32ed833af1e 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -3,6 +3,7 @@ from lldb import ( SBData, SBError, + SBValue, eBasicTypeLong, eBasicTypeUnsignedLong, eBasicTypeUnsignedChar, @@ -44,24 +45,28 @@ 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 @@ def from_uint(self, name, value): 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 @@ def __init__(self, valobj, dict, is_variant=False): 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 @@ def update(self): # 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 @@ def update(self): == -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 @@ def _getCurrentVariantIndex(self, all_variants): 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 @@ def __init__(self, valobj, dict, is_variant=False): 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 @@ def get_child_at_index(self, index): ) 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 { 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 @@ def get_child_at_index(self, index): 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 @@ def update(self): 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 @@ def get_child_at_index(self, index): 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 { head: usize, len: usize, buf: RawVec } """ - 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 @@ def get_child_at_index(self, index): 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 @@ def update(self): 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 { 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 @@ def get_child_at_index(self, index): ) def update(self): - # type: () -> None # logger = Logger.Logger() self.table = self.valobj.GetChildMemberWithName("table") # type: SBValue @@ -624,34 +578,29 @@ def update(self): # 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 @@ def get_child_at_index(self, index): ) def update(self): - # type: () -> None table = self.table() inner_table = table.GetChildMemberWithName("table") @@ -707,8 +655,7 @@ def update(self): 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 @@ def table(self): 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 } """ - 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 @@ def __init__(self, valobj, dict, is_atomic=False): 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 @@ def get_child_index(self, name): 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 @@ def get_child_at_index(self, index): 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 @@ def __init__(self, valobj, dict, is_cell=False): 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 @@ def get_child_at_index(self, index): 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) diff --git a/src/etc/rust_types.py b/src/etc/rust_types.py index 42ec9bed9bdc3..af03e8ede9c3f 100644 --- a/src/etc/rust_types.py +++ b/src/etc/rust_types.py @@ -1,3 +1,4 @@ +from typing import List import re @@ -85,12 +86,11 @@ class RustType(object): } -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 diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3c9e0914b59d7..0f84b43866290 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 8c7ab925577df..3c4fad4bca97e 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -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), + + UnsafeBinder(Box), } 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, + pub(crate) ty: Type, +} + #[derive(Clone, Debug)] pub(crate) struct Static { pub(crate) type_: Box, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 136002b8e155b..621abd535010f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -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<" })?; + f.write_str(keyword)?; + f.write_str(if f.alternate() { "<" } else { "<" })?; comma_sep(params.iter().map(|lt| lt.print(cx)), true).fmt(f)?; f.write_str(if f.alternate() { "> " } else { "> " })?; } @@ -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 { "" }; diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index fe2e155c9ba7a..66c52bec4bad7 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -900,7 +900,8 @@ fn get_index_type_id( | clean::Generic(_) | clean::SelfTy | clean::ImplTrait(_) - | clean::Infer => None, + | clean::Infer + | clean::UnsafeBinder(_) => None, } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 7f072aa7e2fc4..7fcdfe3fb22ea 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -573,7 +573,7 @@ impl FromClean 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 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!(), } } } diff --git a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs index 04fdd2855067d..f2540574f15ae 100644 --- a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs +++ b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs @@ -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; diff --git a/tests/rustdoc/auxiliary/unsafe-binder-dep.rs b/tests/rustdoc/auxiliary/unsafe-binder-dep.rs new file mode 100644 index 0000000000000..65aa9032fed19 --- /dev/null +++ b/tests/rustdoc/auxiliary/unsafe-binder-dep.rs @@ -0,0 +1,4 @@ +#![feature(unsafe_binders)] +#![allow(incomplete_features)] + +pub fn woof() -> unsafe<'a> &'a str { todo!() } diff --git a/tests/rustdoc/unsafe-binder.rs b/tests/rustdoc/unsafe-binder.rs new file mode 100644 index 0000000000000..621c3dadc72ee --- /dev/null +++ b/tests/rustdoc/unsafe-binder.rs @@ -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!() } diff --git a/tests/ui/closures/2229_closure_analysis/issue-118144.rs b/tests/ui/closures/2229_closure_analysis/issue-118144.rs index 3e5d9f9739a59..5747cc75e98af 100644 --- a/tests/ui/closures/2229_closure_analysis/issue-118144.rs +++ b/tests/ui/closures/2229_closure_analysis/issue-118144.rs @@ -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; diff --git a/tests/ui/coroutine/issue-53548.rs b/tests/ui/coroutine/issue-53548.rs index 3b8dff2be28c1..c70f3e5a0d0a1 100644 --- a/tests/ui/coroutine/issue-53548.rs +++ b/tests/ui/coroutine/issue-53548.rs @@ -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`. diff --git a/tests/ui/panics/default-backtrace-ice.rs b/tests/ui/panics/default-backtrace-ice.rs index c47f458f6e97a..9933f54875836 100644 --- a/tests/ui/panics/default-backtrace-ice.rs +++ b/tests/ui/panics/default-backtrace-ice.rs @@ -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; }