Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8569bb2
Add `FromIterator` impls for `ascii::Char`s to `String`s
yotamofek May 23, 2025
97b7170
const Cell methods
clarfonthey Oct 16, 2025
31a2c56
Move const_drop_in_place test from ptr to manually_drop module
clarfonthey Oct 19, 2025
563302e
os_str: Make platform docs more consistent
thaliaarchi Oct 21, 2025
d9f22d2
Pattern types have their base type as a field
oli-obk Oct 21, 2025
ad4bd08
Add not-null pointer patterns to pattern types
oli-obk Jan 24, 2025
375899c
Allow unsizing pattern types with pointer base
oli-obk Apr 16, 2025
fc7c4be
PassWrapper: Access GlobalValueSummaryInfo::SummaryList via getter fo…
aeubanks Oct 21, 2025
f38839a
format
aeubanks Oct 21, 2025
875cc36
actually compile
aeubanks Oct 21, 2025
206ffcc
os_str: Create UTF-8 platform encoding
thaliaarchi Oct 21, 2025
1e80546
format
aeubanks Oct 21, 2025
7e2b76e
motor: Use UTF-8 guarantee for OS strings
thaliaarchi Oct 17, 2025
92d5196
code refactoring on report_no_match_method_error
chenyukang Oct 16, 2025
38e8066
add UnsatisfiedPredicate type alias
chenyukang Oct 22, 2025
664e3b0
Rollup merge of #141445 - yotamofek:pr/library/from-iter-char-string,…
matthiaskrgr Oct 22, 2025
f6d324f
Rollup merge of #142339 - oli-obk:not-null-pattern-types, r=BoxyUwU
matthiaskrgr Oct 22, 2025
aa64f56
Rollup merge of #147768 - chenyukang:yukang-refactor-report-method-er…
matthiaskrgr Oct 22, 2025
8c40b9c
Rollup merge of #147788 - clarfonthey:const-cell, r=oli-obk
matthiaskrgr Oct 22, 2025
aa65c31
Rollup merge of #147932 - thaliaarchi:utf8-osstring, r=tgross35
matthiaskrgr Oct 22, 2025
4a11759
Rollup merge of #147933 - thaliaarchi:consistent-osstring, r=tgross35
matthiaskrgr Oct 22, 2025
e132d2d
Rollup merge of #147948 - aeubanks:summarylist, r=durin42
matthiaskrgr Oct 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2579,6 +2579,9 @@ pub enum TyPatKind {
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),

/// A `!null` pattern for raw pointers.
NotNull,

Or(ThinVec<TyPat>),

/// Placeholder for a pattern that wasn't syntactically well formed in some way.
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
// return inner to be processed in next loop
PatKind::Paren(inner) => pattern = inner,
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
PatKind::MacCall(_) => {
panic!("{pattern:#?} shouldn't exist here")
}
PatKind::Err(guar) => break hir::PatKind::Err(*guar),
}
};
Expand Down Expand Up @@ -460,6 +462,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
}),
),
TyPatKind::NotNull => hir::TyPatKind::NotNull,
TyPatKind::Or(variants) => {
hir::TyPatKind::Or(self.arena.alloc_from_iter(
variants.iter().map(|pat| self.lower_ty_pat_mut(pat, base_type)),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,7 @@ impl<'a> State<'a> {
self.print_expr_anon_const(end, &[]);
}
}
rustc_ast::TyPatKind::NotNull => self.word("!null"),
rustc_ast::TyPatKind::Or(variants) => {
let mut first = true;
for pat in variants {
Expand Down
24 changes: 15 additions & 9 deletions compiler/rustc_builtin_macros/src/pattern_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@ fn parse_pat_ty<'a>(
let ty = parser.parse_ty()?;
parser.expect_keyword(exp!(Is))?;

let pat = pat_to_ty_pat(
cx,
parser.parse_pat_no_top_guard(
None,
RecoverComma::No,
RecoverColon::No,
CommaRecoveryMode::EitherTupleOrPipe,
)?,
);
let start = parser.token.span;
let pat = if parser.eat(exp!(Bang)) {
parser.expect_keyword(exp!(Null))?;
ty_pat(TyPatKind::NotNull, start.to(parser.token.span))
} else {
pat_to_ty_pat(
cx,
parser.parse_pat_no_top_guard(
None,
RecoverComma::No,
RecoverColon::No,
CommaRecoveryMode::EitherTupleOrPipe,
)?,
)
};

if parser.token != token::Eof {
parser.unexpected()?;
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_cranelift/src/unsize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ pub(crate) fn coerce_unsized_into<'tcx>(
dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout()));
};
match (&src_ty.kind(), &dst_ty.kind()) {
(ty::Pat(a, _), ty::Pat(b, _)) => {
let src = src.cast_pat_ty_to_base(fx.layout_of(*a));
let dst = dst.place_transmute_type(fx, *b);
return coerce_unsized_into(fx, src, dst);
}
(&ty::Ref(..), &ty::Ref(..))
| (&ty::Ref(..), &ty::RawPtr(..))
| (&ty::RawPtr(..), &ty::RawPtr(..)) => coerce_ptr(),
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_codegen_cranelift/src/value_and_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,14 @@ impl<'tcx> CValue<'tcx> {
assert_eq!(self.layout().backend_repr, layout.backend_repr);
CValue(self.0, layout)
}

pub(crate) fn cast_pat_ty_to_base(self, layout: TyAndLayout<'tcx>) -> Self {
let ty::Pat(base, _) = *self.layout().ty.kind() else {
panic!("not a pattern type: {:#?}", self.layout())
};
assert_eq!(layout.ty, base);
CValue(self.0, layout)
}
}

/// A place where you can write a value to or read a value from
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
) -> (Bx::Value, Bx::Value) {
debug!("unsize_ptr: {:?} => {:?}", src_ty, dst_ty);
match (src_ty.kind(), dst_ty.kind()) {
(&ty::Pat(a, _), &ty::Pat(b, _)) => unsize_ptr(bx, src, a, b, old_info),
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
| (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => {
assert_eq!(bx.cx().type_is_sized(a), old_info.is_none());
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_const_eval/src/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
) -> InterpResult<'tcx> {
trace!("Unsizing {:?} of type {} into {}", *src, src.layout.ty, cast_ty.ty);
match (src.layout.ty.kind(), cast_ty.ty.kind()) {
(&ty::Pat(_, s_pat), &ty::Pat(cast_ty, c_pat)) if s_pat == c_pat => {
let src = self.project_field(src, FieldIdx::ZERO)?;
let dest = self.project_field(dest, FieldIdx::ZERO)?;
let cast_ty = self.layout_of(cast_ty)?;
self.unsize_into(&src, cast_ty, &dest)
}
(&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(c, _))
| (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, s, c),
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1261,9 +1261,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
// When you extend this match, make sure to also add tests to
// tests/ui/type/pattern_types/validity.rs((
match **pat {
// Range patterns are precisely reflected into `valid_range` and thus
// Range and non-null patterns are precisely reflected into `valid_range` and thus
// handled fully by `visit_scalar` (called below).
ty::PatternKind::Range { .. } => {},
ty::PatternKind::NotNull => {},

// FIXME(pattern_types): check that the value is covered by one of the variants.
// For now, we rely on layout computation setting the scalar's `valid_range` to
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1854,6 +1854,9 @@ pub enum TyPatKind<'hir> {
/// A range pattern (e.g., `1..=2` or `1..2`).
Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),

/// A pattern that excludes null pointers
NotNull,

/// A list of patterns where only one needs to be satisfied
Or(&'hir [TyPat<'hir>]),

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>)
try_visit!(visitor.visit_const_arg_unambig(upper_bound));
}
TyPatKind::Or(patterns) => walk_list!(visitor, visit_pattern_type_pattern, patterns),
TyPatKind::Err(_) => (),
TyPatKind::NotNull | TyPatKind::Err(_) => (),
}
V::Result::output()
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ hir_analysis_coerce_pointee_not_struct = `derive(CoercePointee)` is only applica
hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
hir_analysis_coerce_same_pat_kind = only pattern types with the same pattern can be coerced between each other
hir_analysis_coerce_unsized_field_validity = for `{$ty}` to have a valid implementation of `{$trait_name}`, it must be possible to coerce the field of type `{$field_ty}`
.label = `{$field_ty}` must be a pointer, reference, or smart pointer that is allowed to be unsized
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,18 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
// in the compiler (in particular, all the call ABI logic) will treat them as repr(transparent)
// even if they do not carry that attribute.
match (source.kind(), target.kind()) {
(&ty::Pat(_, pat_a), &ty::Pat(_, pat_b)) => {
if pat_a != pat_b {
return Err(tcx.dcx().emit_err(errors::CoerceSamePatKind {
span,
trait_name,
pat_a: pat_a.to_string(),
pat_b: pat_b.to_string(),
}));
}
Ok(())
}

(&ty::Ref(r_a, _, mutbl_a), ty::Ref(r_b, _, mutbl_b))
if r_a == *r_b && mutbl_a == *mutbl_b =>
{
Expand Down Expand Up @@ -408,6 +420,18 @@ pub(crate) fn coerce_unsized_info<'tcx>(
(mt_a.ty, mt_b.ty, unsize_trait, None, span)
};
let (source, target, trait_def_id, kind, field_span) = match (source.kind(), target.kind()) {
(&ty::Pat(ty_a, pat_a), &ty::Pat(ty_b, pat_b)) => {
if pat_a != pat_b {
return Err(tcx.dcx().emit_err(errors::CoerceSamePatKind {
span,
trait_name,
pat_a: pat_a.to_string(),
pat_b: pat_b.to_string(),
}));
}
(ty_a, ty_b, coerce_unsized_trait, None, span)
}

(&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => {
infcx.sub_regions(SubregionOrigin::RelateObjectBound(span), r_b, r_a);
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,8 @@ pub(crate) fn orphan_check_impl(
(LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther)
}

ty::Pat(..) => (
LocalImpl::Disallow { problematic_kind: "pattern type" },
NonlocalImpl::DisallowOther,
),

ty::Bool
| ty::Pat(..)
| ty::Char
| ty::Int(..)
| ty::Uint(..)
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,16 @@ pub(crate) struct CoerceUnsizedNonStruct {
pub trait_name: &'static str,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_coerce_same_pat_kind)]
pub(crate) struct CoerceSamePatKind {
#[primary_span]
pub span: Span,
pub trait_name: &'static str,
pub pat_a: String,
pub pat_b: String,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
pub(crate) struct CoerceSameStruct {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2611,6 +2611,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.span_delayed_bug(ty_span, "invalid base type for range pattern")),
}
}
hir::TyPatKind::NotNull => Ok(ty::PatternKind::NotNull),
hir::TyPatKind::Or(patterns) => {
self.tcx()
.mk_patterns_from_iter(patterns.iter().map(|pat| {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_const(current, start, variance);
self.add_constraints_from_const(current, end, variance);
}
ty::PatternKind::NotNull => {}
ty::PatternKind::Or(patterns) => {
for pat in patterns {
self.add_constraints_from_pat(current, variance, pat)
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1888,6 +1888,10 @@ impl<'a> State<'a> {
self.word("..=");
self.print_const_arg(end);
}
TyPatKind::NotNull => {
self.word_space("not");
self.word("null");
}
TyPatKind::Or(patterns) => {
self.popen();
let mut first = true;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1953,7 +1953,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
self.suggest_derive(diag, &[(trait_ref.upcast(self.tcx), None, None)]);
self.suggest_derive(diag, &vec![(trait_ref.upcast(self.tcx), None, None)]);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use tracing::{debug, instrument};
pub(crate) use self::MethodError::*;
use self::probe::{IsSuggestion, ProbeScope};
use crate::FnCtxt;
use crate::method::probe::UnsatisfiedPredicates;

#[derive(Clone, Copy, Debug)]
pub(crate) struct MethodCallee<'tcx> {
Expand Down Expand Up @@ -71,8 +72,7 @@ pub(crate) enum MethodError<'tcx> {
#[derive(Debug)]
pub(crate) struct NoMatchData<'tcx> {
pub static_candidates: Vec<CandidateSource>,
pub unsatisfied_predicates:
Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
pub unsatisfied_predicates: UnsatisfiedPredicates<'tcx>,
pub out_of_scope_traits: Vec<DefId>,
pub similar_candidate: Option<ty::AssocItem>,
pub mode: probe::Mode,
Expand Down
21 changes: 6 additions & 15 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,12 @@ struct PickDiagHints<'a, 'tcx> {

/// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
/// for error reporting
unsatisfied_predicates: &'a mut Vec<(
ty::Predicate<'tcx>,
Option<ty::Predicate<'tcx>>,
Option<ObligationCause<'tcx>>,
)>,
unsatisfied_predicates: &'a mut UnsatisfiedPredicates<'tcx>,
}

pub(crate) type UnsatisfiedPredicates<'tcx> =
Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>;

/// Criteria to apply when searching for a given Pick. This is used during
/// the search for potentially shadowed methods to ensure we don't search
/// more candidates than strictly necessary.
Expand Down Expand Up @@ -1212,11 +1211,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {

fn pick_core(
&self,
unsatisfied_predicates: &mut Vec<(
ty::Predicate<'tcx>,
Option<ty::Predicate<'tcx>>,
Option<ObligationCause<'tcx>>,
)>,
unsatisfied_predicates: &mut UnsatisfiedPredicates<'tcx>,
) -> Option<PickResult<'tcx>> {
// Pick stable methods only first, and consider unstable candidates if not found.
self.pick_all_method(&mut PickDiagHints {
Expand Down Expand Up @@ -1889,11 +1884,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self_ty: Ty<'tcx>,
instantiate_self_ty_obligations: &[PredicateObligation<'tcx>],
probe: &Candidate<'tcx>,
possibly_unsatisfied_predicates: &mut Vec<(
ty::Predicate<'tcx>,
Option<ty::Predicate<'tcx>>,
Option<ObligationCause<'tcx>>,
)>,
possibly_unsatisfied_predicates: &mut UnsatisfiedPredicates<'tcx>,
) -> ProbeResult {
self.probe(|snapshot| {
let outer_universe = self.universe();
Expand Down
Loading
Loading