Skip to content
2 changes: 0 additions & 2 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,8 +1197,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
} else {
self.emit_bad_parenthesized_trait_in_assoc_ty(data);
// FIXME(return_type_notation): we could issue a feature error
// if the parens are empty and there's no return type.
self.lower_angle_bracketed_parameter_data(
&data.as_angle_bracketed_args(),
ParamMode::Explicit,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/var_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use tracing::debug;
use crate::region_infer::RegionInferenceContext;

impl<'tcx> RegionInferenceContext<'tcx> {
/// Find the the name and span of the variable corresponding to the given region.
/// Find the name and span of the variable corresponding to the given region.
/// The returned var will also be ensured to actually be used in `body`.
pub(crate) fn get_var_name_and_span_for_region(
&self,
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> {
}
}

DefKind::TraitAlias | DefKind::Fn => {
DefKind::TraitAlias | DefKind::Fn | DefKind::TyAlias => {
self.ev.queue.insert(def_id);
}

Expand All @@ -808,7 +808,6 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> {

// Can't be reached
DefKind::Impl { .. }
| DefKind::TyAlias
| DefKind::Field
| DefKind::Variant
| DefKind::Static { .. }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/solve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl<T: Copy + Debug + Hash + Eq> AsRef<[T]> for SmallCopyList<T> {
/// | never | no | no |
/// | always | yes | yes |
/// | [defid in storage] | no | only if any of the defids in the list is in the opaque type storage OR if TypingMode::PostAnalysis |
/// | opaque with hidden type | no | only if any of the the opaques in the opaque type storage has a hidden type in this list AND if TypingMode::Analysis |
/// | opaque with hidden type | no | only if any of the opaques in the opaque type storage has a hidden type in this list AND if TypingMode::Analysis |
///
/// - "bail" is implemented with [`should_bail`](Self::should_bail).
/// If true, we're abandoning our attempt to canonicalize in [`TypingMode::ErasedNotCoherence`],
Expand Down
96 changes: 74 additions & 22 deletions src/etc/lldb_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from rust_types import is_tuple_fields

if TYPE_CHECKING:
from lldb import SBValue, SBType, SBTypeStaticField, SBTarget
from lldb import SBValue, SBType, SBTypeStaticField, SBTarget, SBProcess

# from lldb.formatters import Logger

Expand Down Expand Up @@ -289,6 +289,28 @@ def vec_to_string(vec: SBValue) -> str:
)


def read_string(
process: SBProcess, address: int, length: int, error: Optional[SBError] = None
) -> str:
"""Reads a string from running process's memory. If `error` is passed in, it will be passed
to the `SBProcess.ReadMemory` call, and will reflect any errors after the function is called.

If any error or exception occurs, a placeholder byte array of the form "<error: [reason]>" will
be returned instead."""

if error is None:
error = SBError()
try:
data = process.ReadMemory(address, length, error)
if error.Success():
return '"' + data.decode("utf-8", "replace") + '"'
else:
return f"<error: {error.GetCString()}>"
except Exception as e:
print(f"Unable to generate String summary: {e.__cause__}")
return "<error: Unable to read memory>"


def StdStringSummaryProvider(valobj: SBValue, dict: LLDBOpaque):
inner_vec = (
valobj.GetNonSyntheticValue()
Expand All @@ -305,16 +327,25 @@ def StdStringSummaryProvider(valobj: SBValue, dict: LLDBOpaque):
)

length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned()
capacity = (
inner_vec.GetChildMemberWithName("buf")
.GetChildMemberWithName("cap")
.GetValueAsUnsigned()
)

if length <= 0:
return '""'
error = SBError()

no_hi_bit_max: int = 1 << ((pointer.GetByteSize() * 8) - 1)
# technically length isn't a NoHighBit<usize>, but length should always be <= capacity
if length >= no_hi_bit_max or capacity >= no_hi_bit_max:
return "<error: invalid len/capacity>"
if pointer.GetValueAsUnsigned() == 0:
return "<error: String pointer is null>"

process = pointer.GetProcess()
data = process.ReadMemory(pointer.GetValueAsUnsigned(), length, error)
if error.Success():
return '"' + data.decode("utf8", "replace") + '"'
else:
raise Exception("ReadMemory error: %s", error.GetCString())

return read_string(process, pointer.GetValueAsAddress(), length)


def StdOsStringSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
Expand Down Expand Up @@ -363,15 +394,9 @@ def StdPathSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
data_ptr = valobj.GetChildMemberWithName("data_ptr")

start = data_ptr.GetValueAsUnsigned()
error = SBError()
process = data_ptr.GetProcess()
data = process.ReadMemory(start, length, error)
if PY3:
try:
data = data.decode(encoding="UTF-8")
except UnicodeDecodeError:
return "%r" % data
return '"%s"' % data

return read_string(process, start, length)


def sequence_formatter(output: str, valobj: SBValue, _dict: LLDBOpaque):
Expand Down Expand Up @@ -443,6 +468,9 @@ def has_children(self) -> bool:
class StdStringSyntheticProvider:
def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
self.valobj = valobj
ptr_size = valobj.GetTarget().GetAddressByteSize() * 8
self.no_hi_bit_max = 1 << (ptr_size - 1)

self.update()

def update(self):
Expand All @@ -454,7 +482,25 @@ def update(self):
.GetChildMemberWithName("pointer")
.GetChildMemberWithName("pointer")
)
self.length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned()

self.capacity = (
inner_vec.GetChildMemberWithName("buf")
.GetChildMemberWithName("cap")
.GetValueAsUnsigned()
)

# As of 4/18/2026, LLDB cannot accurately determine the difference between Some("") and None
# this just makes sure we're not trying to access data when the string is clearly in an
# invalid state.
if (
self.capacity >= self.no_hi_bit_max
or self.data_ptr.GetValueAsUnsigned() == 0
):
self.capacity = 0
self.length = 0
else:
self.length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned()

self.element_type = self.data_ptr.GetType().GetPointeeType()

def has_children(self) -> bool:
Expand Down Expand Up @@ -928,6 +974,8 @@ def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
# logger >> "[StdVecSyntheticProvider] for " + str(valobj.GetName())
self.valobj = valobj
self.element_type = None
ptr_size = valobj.GetTarget().GetAddressByteSize() * 8
self.no_hi_bit_max = 1 << (ptr_size - 1)
self.update()

def num_children(self) -> int:
Expand All @@ -949,15 +997,19 @@ def get_child_at_index(self, index: int) -> Optional[SBValue]:
return element

def update(self):
self.length = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
self.buf = self.valobj.GetChildMemberWithName("buf").GetChildMemberWithName(
"inner"
)

buf: SBValue = self.valobj.GetChildMemberWithName("buf")
self.data_ptr = unwrap_unique_or_non_null(
self.buf.GetChildMemberWithName("ptr")
buf.GetChildMemberWithName("inner").GetChildMemberWithName("ptr")
)

capacity: int = buf.GetChildMemberWithName("cap").GetValueAsUnsigned()

if capacity >= self.no_hi_bit_max or self.data_ptr.GetValueAsUnsigned() == 0:
self.capacity = 0
self.length = 0
else:
self.length = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()

self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)

if not self.element_type.IsValid():
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/privacy/reach-type-alias-issue-156778.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ check-pass
#![feature(lazy_type_alias)]

use src::hidden_core;
mod src {
mod aliases {
use hidden_core::InternalStruct;
pub type ExposedType = InternalStruct<f32>;
}
pub mod hidden_core {
use super::aliases::ExposedType;
pub struct InternalStruct<T> {
_x: T,
}
pub fn new() -> ExposedType {
InternalStruct { _x: 1.0 }
}
}
}
fn main() {}
Loading