Skip to content

Commit

Permalink
Auto merge of rust-lang#136549 - matthiaskrgr:rollup-sqbpgtd, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#136242 (Remove `LateContext::match_def_path()`)
 - rust-lang#136274 (Check Sizedness of return type in WF)
 - rust-lang#136284 (Allow using named consts in pattern types)
 - rust-lang#136477 (Fix a couple NLL TLS spans )
 - rust-lang#136497 (Report generic mismatches when calling bodyless trait functions)
 - rust-lang#136520 (Remove unnecessary layout assertions for object-safe receivers)
 - rust-lang#136526 (mir_build: Rename `thir::cx::Cx` to `ThirBuildCx` and remove `UserAnnotatedTyHelpers`)

Failed merges:

 - rust-lang#136304 (Reject negative literals for unsigned or char types in pattern ranges and literals)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Feb 4, 2025
2 parents 3f33b30 + 1b7efa2 commit bef3c3b
Show file tree
Hide file tree
Showing 118 changed files with 1,369 additions and 1,063 deletions.
8 changes: 6 additions & 2 deletions compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}

fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
self.visit_pat(p)
fn visit_pattern_type_pattern(&mut self, pat: &'hir hir::TyPat<'hir>) {
self.insert(pat.span, pat.hir_id, Node::TyPat(pat));

self.with_parent(pat.hir_id, |this| {
intravisit::walk_ty_pat(this, pat);
});
}

fn visit_precise_capturing_arg(
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
}
TyKind::Pat(ty, pat) => hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_pat(pat)),
TyKind::Pat(ty, pat) => {
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
}
TyKind::MacCall(_) => {
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
}
Expand Down
81 changes: 79 additions & 2 deletions compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use rustc_ast::ptr::P;
use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::span_bug;
use rustc_span::source_map::{Spanned, respan};
use rustc_span::{Ident, Span};
use rustc_span::{Ident, Span, kw};

use super::errors::{
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
Expand Down Expand Up @@ -429,4 +429,81 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
}

pub(crate) fn lower_ty_pat(&mut self, pattern: &Pat) -> &'hir hir::TyPat<'hir> {
self.arena.alloc(self.lower_ty_pat_mut(pattern))
}

fn lower_ty_pat_mut(&mut self, mut pattern: &Pat) -> hir::TyPat<'hir> {
// loop here to avoid recursion
let pat_hir_id = self.lower_node_id(pattern.id);
let node = loop {
match &pattern.kind {
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
// FIXME(pattern_types): remove this closure and call `lower_const_arg` instead.
// That requires first modifying the AST to have const args here.
let mut lower_expr = |e: &Expr| -> &_ {
if let ExprKind::Path(None, path) = &e.kind
&& let Some(res) = self
.resolver
.get_partial_res(e.id)
.and_then(|partial_res| partial_res.full_res())
{
self.lower_const_path_to_const_arg(path, res, e.id, e.span)
} else {
let node_id = self.next_node_id();
let def_id = self.create_def(
self.current_hir_id_owner.def_id,
node_id,
kw::Empty,
DefKind::AnonConst,
e.span,
);
let hir_id = self.lower_node_id(node_id);
let ac = self.arena.alloc(hir::AnonConst {
def_id,
hir_id,
body: self.lower_const_body(pattern.span, Some(e)),
span: self.lower_span(pattern.span),
});
self.arena.alloc(hir::ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Anon(ac),
})
}
};
break hir::TyPatKind::Range(
e1.as_deref().map(|e| lower_expr(e)),
e2.as_deref().map(|e| lower_expr(e)),
self.lower_range_end(end, e2.is_some()),
);
}
// return inner to be processed in next loop
PatKind::Paren(inner) => pattern = inner,
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
PatKind::Err(guar) => break hir::TyPatKind::Err(*guar),
PatKind::Deref(..)
| PatKind::Box(..)
| PatKind::Or(..)
| PatKind::Struct(..)
| PatKind::TupleStruct(..)
| PatKind::Tuple(..)
| PatKind::Ref(..)
| PatKind::Expr(..)
| PatKind::Guard(..)
| PatKind::Slice(_)
| PatKind::Ident(..)
| PatKind::Path(..)
| PatKind::Wild
| PatKind::Never
| PatKind::Rest => {
break hir::TyPatKind::Err(
self.dcx().span_err(pattern.span, "pattern not supported in pattern types"),
);
}
}
};

hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
}
}
14 changes: 13 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3112,12 +3112,24 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
drop_span, borrow_span
);

// `TerminatorKind::Return`'s span (the `drop_span` here) `lo` can be subtly wrong and point
// at a single character after the end of the function. This is somehow relied upon in
// existing diagnostics, and changing this in `rustc_mir_build` makes diagnostics worse in
// general. We fix these here.
let sm = self.infcx.tcx.sess.source_map();
let end_of_function = if drop_span.is_empty()
&& let Ok(adjusted_span) = sm.span_extend_prev_while(drop_span, |c| c == '}')
{
adjusted_span
} else {
drop_span
};
self.thread_local_value_does_not_live_long_enough(borrow_span)
.with_span_label(
borrow_span,
"thread-local variables cannot be borrowed beyond the end of the function",
)
.with_span_label(drop_span, "end of enclosing function is here")
.with_span_label(end_of_function, "end of enclosing function is here")
}

#[instrument(level = "debug", skip(self))]
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_driver_impl/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ impl<'tcx> pprust_hir::PpAnn for HirIdentifiedAnn<'tcx> {
s.s.space();
s.synth_comment(format!("pat hir_id: {}", pat.hir_id));
}
pprust_hir::AnnNode::TyPat(pat) => {
s.s.space();
s.synth_comment(format!("ty pat hir_id: {}", pat.hir_id));
}
pprust_hir::AnnNode::Arm(arm) => {
s.s.space();
s.synth_comment(format!("arm hir_id: {}", arm.hir_id));
Expand Down
21 changes: 20 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,14 @@ impl<'hir> Block<'hir> {
}
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TyPat<'hir> {
#[stable_hasher(ignore)]
pub hir_id: HirId,
pub kind: TyPatKind<'hir>,
pub span: Span,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Pat<'hir> {
#[stable_hasher(ignore)]
Expand Down Expand Up @@ -1591,6 +1599,15 @@ pub enum PatExprKind<'hir> {
Path(QPath<'hir>),
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum TyPatKind<'hir> {
/// A range pattern (e.g., `1..=2` or `1..2`).
Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd),

/// A placeholder for a pattern that wasn't well formed in some way.
Err(ErrorGuaranteed),
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum PatKind<'hir> {
/// Represents a wildcard pattern (i.e., `_`).
Expand Down Expand Up @@ -3384,7 +3401,7 @@ pub enum TyKind<'hir, Unambig = ()> {
/// Placeholder for a type that has failed to be defined.
Err(rustc_span::ErrorGuaranteed),
/// Pattern types (`pattern_type!(u32 is 1..)`)
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
/// `TyKind::Infer` means the type should be inferred instead of it having been
/// specified. This can appear anywhere in a type.
///
Expand Down Expand Up @@ -4370,6 +4387,7 @@ pub enum Node<'hir> {
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
TraitRef(&'hir TraitRef<'hir>),
OpaqueTy(&'hir OpaqueTy<'hir>),
TyPat(&'hir TyPat<'hir>),
Pat(&'hir Pat<'hir>),
PatField(&'hir PatField<'hir>),
/// Needed as its own node with its own HirId for tracking
Expand Down Expand Up @@ -4432,6 +4450,7 @@ impl<'hir> Node<'hir> {
| Node::Block(..)
| Node::Ctor(..)
| Node::Pat(..)
| Node::TyPat(..)
| Node::PatExpr(..)
| Node::Arm(..)
| Node::LetStmt(..)
Expand Down
18 changes: 14 additions & 4 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,8 @@ pub trait Visitor<'v>: Sized {
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
walk_expr_field(self, field)
}
fn visit_pattern_type_pattern(&mut self, _p: &'v Pat<'v>) {
// Do nothing. Only a few visitors need to know the details of the pattern type,
// and they opt into it. All other visitors will just choke on our fake patterns
// because they aren't in a body.
fn visit_pattern_type_pattern(&mut self, p: &'v TyPat<'v>) -> Self::Result {
walk_ty_pat(self, p)
}
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) -> Self::Result {
walk_generic_param(self, p)
Expand Down Expand Up @@ -702,6 +700,18 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res
visitor.visit_expr(arm.body)
}

pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result {
try_visit!(visitor.visit_id(pattern.hir_id));
match pattern.kind {
TyPatKind::Range(lower_bound, upper_bound, _) => {
visit_opt!(visitor, visit_const_arg_unambig, lower_bound);
visit_opt!(visitor, visit_const_arg_unambig, upper_bound);
}
TyPatKind::Err(_) => (),
}
V::Result::output()
}

pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V::Result {
try_visit!(visitor.visit_id(pattern.hir_id));
match pattern.kind {
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,6 @@ hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a t
hir_analysis_parenthesized_fn_trait_expansion =
parenthesized trait syntax expands to `{$expanded_type}`
hir_analysis_pattern_type_non_const_range = range patterns must have constant range start and end
hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pattern types
.label = this type is the same as the inner type without a pattern
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
.label = not allowed in type signatures
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
Expand Down
30 changes: 28 additions & 2 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,7 @@ fn check_associated_item(
let ty = tcx.type_of(item.def_id).instantiate_identity();
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
wfcx.register_wf_obligation(span, loc, ty.into());
check_sized_if_body(wfcx, item.def_id.expect_local(), ty, Some(span));
Ok(())
}
ty::AssocKind::Fn => {
Expand Down Expand Up @@ -1189,7 +1190,7 @@ fn check_type_defn<'tcx>(
),
wfcx.param_env,
ty,
tcx.require_lang_item(LangItem::Sized, None),
tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)),
);
}

Expand Down Expand Up @@ -1314,7 +1315,7 @@ fn check_item_type(
),
wfcx.param_env,
item_ty,
tcx.require_lang_item(LangItem::Sized, None),
tcx.require_lang_item(LangItem::Sized, Some(ty_span)),
);
}

Expand Down Expand Up @@ -1644,6 +1645,31 @@ fn check_fn_or_method<'tcx>(
);
}
}

// If the function has a body, additionally require that the return type is sized.
check_sized_if_body(wfcx, def_id, sig.output(), match hir_decl.output {
hir::FnRetTy::Return(ty) => Some(ty.span),
hir::FnRetTy::DefaultReturn(_) => None,
});
}

fn check_sized_if_body<'tcx>(
wfcx: &WfCheckingCtxt<'_, 'tcx>,
def_id: LocalDefId,
ty: Ty<'tcx>,
maybe_span: Option<Span>,
) {
let tcx = wfcx.tcx();
if let Some(body) = tcx.hir().maybe_body_owned_by(def_id) {
let span = maybe_span.unwrap_or(body.value.span);

wfcx.register_bound(
ObligationCause::new(span, def_id, traits::ObligationCauseCode::SizedReturnType),
wfcx.param_env,
ty,
tcx.require_lang_item(LangItem::Sized, Some(span)),
);
}
}

/// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
{
Some(parent_did)
}
Node::TyPat(_) => Some(parent_did),
_ => None,
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -831,8 +831,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}

#[instrument(level = "debug", skip(self))]
fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::Pat<'tcx>) {
intravisit::walk_pat(self, p)
fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::TyPat<'tcx>) {
intravisit::walk_ty_pat(self, p)
}

#[instrument(level = "debug", skip(self))]
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ use crate::hir_ty_lowering::HirTyLowerer;

mod opaque;

fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
use hir::*;
use rustc_middle::ty::Ty;
let tcx = icx.tcx;
let hir_id = tcx.local_def_id_to_hir_id(def_id);

let node = tcx.hir_node(hir_id);
Expand Down Expand Up @@ -54,7 +55,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
hir_id: arg_hir_id,
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
..
}) if anon_hir_id == hir_id => const_arg_anon_type_of(tcx, arg_hir_id, span),
}) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),

// Anon consts outside the type system.
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
Expand Down Expand Up @@ -138,18 +139,28 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
}
}

fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
use hir::*;
use rustc_middle::ty::Ty;

let tcx = icx.tcx;

match tcx.parent_hir_node(arg_hir_id) {
// Array length const arguments do not have `type_of` fed as there is never a corresponding
// generic parameter definition.
Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. })
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
if constant.hir_id == arg_hir_id =>
{
return tcx.types.usize;
tcx.types.usize
}

Node::TyPat(pat) => {
let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else {
bug!()
};
assert_eq!(p.hir_id, pat.hir_id);
icx.lower_ty(ty)
}

// This is not a `bug!` as const arguments in path segments that did not resolve to anything
Expand Down Expand Up @@ -344,7 +355,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
tcx.typeck(def_id).node_type(hir_id)
}

Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
Node::AnonConst(_) => anon_const_type_of(&icx, def_id),

Node::ConstBlock(_) => {
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
Expand Down
Loading

0 comments on commit bef3c3b

Please sign in to comment.