Skip to content

Rollup of 7 pull requests #135213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 20 commits into from
Closed
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6b9d6c7
stop clearing box's drop flags early
beepster4096 Oct 2, 2024
1bd8217
add mir-opt test for box allocator dropping
beepster4096 Oct 18, 2024
baf4bb7
remove unnecessary `eval_verify_bound`
lcnr Dec 3, 2024
1228b38
add assert
lcnr Dec 4, 2024
b579c36
add guard patterns to HIR and implement lowering
max-niederman Aug 25, 2024
087b872
typecheck guard pattern conditions
max-niederman Sep 15, 2024
c3132e7
allow irrefutable let patterns in feature gate test
max-niederman Jan 1, 2025
8cefc0a
cover guard patterns in clippy lints
max-niederman Oct 6, 2024
ab07e78
Failing test
compiler-errors Jan 6, 2025
86d8b79
Use a post-monomorphization typing env when mangling components that …
compiler-errors Jan 6, 2025
5a56600
Normalize each signature input/output in typeck_with_fallback with it…
compiler-errors Dec 25, 2024
c7a806a
rustdoc: use stable paths as preferred canonical paths
notriddle Jan 6, 2025
b77eb96
rustfmt: drop nightly-gating of the `--style-edition` flag registration
jieyouxu Jan 7, 2025
7104e01
Rollup merge of #131146 - beepster4096:box_drop_flags, r=wesleywiser
matthiaskrgr Jan 7, 2025
59c4b4d
Rollup merge of #133810 - lcnr:remove-verify_bound, r=compiler-errors
matthiaskrgr Jan 7, 2025
2034dc4
Rollup merge of #134745 - compiler-errors:better-arg-span-in-typeck, …
matthiaskrgr Jan 7, 2025
ebbbf0f
Rollup merge of #134989 - max-niederman:guard-patterns-hir, r=oli-obk
matthiaskrgr Jan 7, 2025
de304e8
Rollup merge of #135149 - compiler-errors:mangle, r=oli-obk
matthiaskrgr Jan 7, 2025
847c1de
Rollup merge of #135171 - notriddle:notriddle/stable-path-is-better, …
matthiaskrgr Jan 7, 2025
bd9744d
Rollup merge of #135200 - jieyouxu:stabilize-style-edition, r=ytmimi,…
matthiaskrgr Jan 7, 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
5 changes: 3 additions & 2 deletions compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
@@ -120,8 +120,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_range_end(end, e2.is_some()),
);
}
// FIXME(guard_patterns): lower pattern guards to HIR
PatKind::Guard(inner, _) => pattern = inner,
PatKind::Guard(inner, cond) => {
break hir::PatKind::Guard(self.lower_pat(inner), self.lower_expr(cond));
}
PatKind::Slice(pats) => break self.lower_pat_slice(pats),
PatKind::Rest => {
// If we reach here the `..` pattern is not semantically allowed.
26 changes: 8 additions & 18 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
@@ -978,7 +978,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
) -> bool {
let tcx = infcx.tcx;
let TypeTest { generic_kind, lower_bound, span: blame_span, ref verify_bound } = *type_test;
let TypeTest { generic_kind, lower_bound, span: blame_span, verify_bound: _ } = *type_test;

let generic_ty = generic_kind.to_ty(tcx);
let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else {
@@ -1016,25 +1016,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// For each region outlived by lower_bound find a non-local,
// universal region (it may be the same region) and add it to
// `ClosureOutlivesRequirement`.
let mut found_outlived_universal_region = false;
for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
found_outlived_universal_region = true;
debug!("universal_region_outlived_by ur={:?}", ur);
// Check whether we can already prove that the "subject" outlives `ur`.
// If so, we don't have to propagate this requirement to our caller.
//
// To continue the example from the function, if we are trying to promote
// a requirement that `T: 'X`, and we know that `'X = '1 + '2` (i.e., the union
// `'1` and `'2`), then in this loop `ur` will be `'1` (and `'2`). So here
// we check whether `T: '1` is something we *can* prove. If so, no need
// to propagate that requirement.
//
// This is needed because -- particularly in the case
// where `ur` is a local bound -- we are sometimes in a
// position to prove things that our caller cannot. See
// #53570 for an example.
if self.eval_verify_bound(infcx, generic_ty, ur, &verify_bound) {
continue;
}

let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur);
debug!(?non_local_ub);

@@ -1056,6 +1041,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
propagated_outlives_requirements.push(requirement);
}
}
// If we succeed to promote the subject, i.e. it only contains non-local regions,
// and fail to prove the type test inside of the closure, the `lower_bound` has to
// also be at least as large as some universal region, as the type test is otherwise
// trivial.
assert!(found_outlived_universal_region);
true
}

7 changes: 5 additions & 2 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -1387,7 +1387,7 @@ impl<'hir> Pat<'hir> {
use PatKind::*;
match self.kind {
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => true,
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
Slice(before, slice, after) => {
@@ -1414,7 +1414,7 @@ impl<'hir> Pat<'hir> {
use PatKind::*;
match self.kind {
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => {}
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
Slice(before, slice, after) => {
@@ -1566,6 +1566,9 @@ pub enum PatKind<'hir> {
/// A literal.
Lit(&'hir Expr<'hir>),

/// A guard pattern (e.g., `x if guard(x)`).
Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),

/// A range pattern (e.g., `1..=2` or `1..2`).
Range(Option<&'hir Expr<'hir>>, Option<&'hir Expr<'hir>>, RangeEnd),

4 changes: 4 additions & 0 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
@@ -696,6 +696,10 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
visit_opt!(visitor, visit_pat, slice_pattern);
walk_list!(visitor, visit_pat, postpatterns);
}
PatKind::Guard(subpat, condition) => {
try_visit!(visitor.visit_pat(subpat));
try_visit!(visitor.visit_expr(condition));
}
}
V::Result::output()
}
5 changes: 4 additions & 1 deletion compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
@@ -654,6 +654,7 @@ fn resolve_local<'tcx>(
/// | ( ..., P&, ... )
/// | ... "|" P& "|" ...
/// | box P&
/// | P& if ...
/// ```
fn is_binding_pat(pat: &hir::Pat<'_>) -> bool {
// Note that the code below looks for *explicit* refs only, that is, it won't
@@ -694,7 +695,9 @@ fn resolve_local<'tcx>(
| PatKind::TupleStruct(_, subpats, _)
| PatKind::Tuple(subpats, _) => subpats.iter().any(|p| is_binding_pat(p)),

PatKind::Box(subpat) | PatKind::Deref(subpat) => is_binding_pat(subpat),
PatKind::Box(subpat) | PatKind::Deref(subpat) | PatKind::Guard(subpat, _) => {
is_binding_pat(subpat)
}

PatKind::Ref(_, _)
| PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
6 changes: 6 additions & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1999,6 +1999,12 @@ impl<'a> State<'a> {
self.commasep(Inconsistent, after, |s, p| s.print_pat(p));
self.word("]");
}
PatKind::Guard(inner, cond) => {
self.print_pat(inner);
self.space();
self.word_space("if");
self.print_expr(cond);
}
PatKind::Err(_) => {
self.popen();
self.word("/*ERROR*/");
3 changes: 3 additions & 0 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
@@ -456,6 +456,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Does not constitute a read.
hir::PatKind::Wild => false,

// Might not constitute a read, since the condition might be false.
hir::PatKind::Guard(_, _) => true,

// This is unnecessarily restrictive when the pattern that doesn't
// constitute a read is unreachable.
//
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
@@ -615,6 +615,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
| PatKind::Box(_)
| PatKind::Deref(_)
| PatKind::Ref(..)
| PatKind::Guard(..)
| PatKind::Wild
| PatKind::Err(_) => {
// If the PatKind is Or, Box, or Ref, the decision is made later
@@ -1737,7 +1738,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
}
}

PatKind::Binding(.., Some(subpat)) => {
PatKind::Binding(.., Some(subpat)) | PatKind::Guard(subpat, _) => {
self.cat_pattern(place_with_id, subpat, op)?;
}

19 changes: 17 additions & 2 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
@@ -147,8 +147,23 @@ fn typeck_with_fallback<'tcx>(
check_abi(tcx, span, fn_sig.abi());

// Compute the function signature from point of view of inside the fn.
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
let fn_sig = fcx.normalize(body.value.span, fn_sig);
let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);

// Normalize the input and output types one at a time, using a different
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
// on the entire `FnSig`, since this would use the same `WellFormedLoc`
// for each type, preventing the HIR wf check from generating
// a nice error message.
let arg_span =
|idx| decl.inputs.get(idx).map_or(decl.output.span(), |arg: &hir::Ty<'_>| arg.span);

fn_sig.inputs_and_output = tcx.mk_type_list_from_iter(
fn_sig
.inputs_and_output
.iter()
.enumerate()
.map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)),
);

check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params());
} else {
10 changes: 9 additions & 1 deletion compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
@@ -284,6 +284,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
}
PatKind::Guard(pat, cond) => {
self.check_pat(pat, expected, pat_info);
self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
expected
}
PatKind::Or(pats) => {
for pat in pats {
self.check_pat(pat, expected, pat_info);
@@ -422,7 +427,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// An OR-pattern just propagates to each individual alternative.
// This is maximally flexible, allowing e.g., `Some(mut x) | &Some(mut x)`.
// In that example, `Some(mut x)` results in `Peel` whereas `&Some(mut x)` in `Reset`.
| PatKind::Or(_) => AdjustMode::Pass,
| PatKind::Or(_)
// Like or-patterns, guard patterns just propogate to their subpatterns.
| PatKind::Guard(..) => AdjustMode::Pass,
}
}

@@ -901,6 +908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
PatKind::Struct(..)
| PatKind::TupleStruct(..)
| PatKind::Or(..)
| PatKind::Guard(..)
| PatKind::Tuple(..)
| PatKind::Slice(..) => "binding",

40 changes: 19 additions & 21 deletions compiler/rustc_middle/src/ty/print/mod.rs
Original file line number Diff line number Diff line change
@@ -45,10 +45,25 @@ pub trait Printer<'tcx>: Sized {
&mut self,
impl_def_id: DefId,
args: &'tcx [GenericArg<'tcx>],
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<(), PrintError> {
self.default_print_impl_path(impl_def_id, args, self_ty, trait_ref)
let tcx = self.tcx();
let self_ty = tcx.type_of(impl_def_id);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
let (self_ty, impl_trait_ref) = if tcx.generics_of(impl_def_id).count() <= args.len() {
(
self_ty.instantiate(tcx, args),
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(tcx, args)),
)
} else {
// We are probably printing a nested item inside of an impl.
// Use the identity substitutions for the impl.
(
self_ty.instantiate_identity(),
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
)
};

self.default_print_impl_path(impl_def_id, self_ty, impl_trait_ref)
}

fn print_region(&mut self, region: ty::Region<'tcx>) -> Result<(), PrintError>;
@@ -107,23 +122,7 @@ pub trait Printer<'tcx>: Sized {
self.path_crate(def_id.krate)
}

DefPathData::Impl => {
let generics = self.tcx().generics_of(def_id);
let self_ty = self.tcx().type_of(def_id);
let impl_trait_ref = self.tcx().impl_trait_ref(def_id);
let (self_ty, impl_trait_ref) = if args.len() >= generics.count() {
(
self_ty.instantiate(self.tcx(), args),
impl_trait_ref.map(|i| i.instantiate(self.tcx(), args)),
)
} else {
(
self_ty.instantiate_identity(),
impl_trait_ref.map(|i| i.instantiate_identity()),
)
};
self.print_impl_path(def_id, args, self_ty, impl_trait_ref)
}
DefPathData::Impl => self.print_impl_path(def_id, args),

_ => {
let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
@@ -201,7 +200,6 @@ pub trait Printer<'tcx>: Sized {
fn default_print_impl_path(
&mut self,
impl_def_id: DefId,
_args: &'tcx [GenericArg<'tcx>],
self_ty: Ty<'tcx>,
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<(), PrintError> {
3 changes: 3 additions & 0 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
@@ -435,6 +435,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {

hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) },

// FIXME(guard_patterns): implement guard pattern lowering
hir::PatKind::Guard(pat, _) => self.lower_pattern(pat).kind,

hir::PatKind::Err(guar) => PatKind::Error(guar),
};

18 changes: 9 additions & 9 deletions compiler/rustc_mir_dataflow/src/elaborate_drops.rs
Original file line number Diff line number Diff line change
@@ -460,13 +460,19 @@ where

if adt.is_box() {
// we need to drop the inside of the box before running the destructor
let succ = self.destructor_call_block(contents_drop);
let destructor = self.destructor_call_block(contents_drop);
let unwind = contents_drop
.1
.map(|unwind| self.destructor_call_block((unwind, Unwind::InCleanup)));

self.open_drop_for_box_contents(adt, args, succ, unwind)
let boxed_drop = self.open_drop_for_box_contents(adt, args, destructor, unwind);

// the drop flag will be at the end of contents_drop
self.drop_flag_test_block(boxed_drop, self.succ, unwind)
} else if adt.has_dtor(self.tcx()) {
// We don't need to test drop flags here because
// this path is only taken with DropShimElaborator
// where testing drop flags is a noop
self.destructor_call_block(contents_drop)
} else {
contents_drop.0
@@ -659,13 +665,7 @@ where
}),
is_cleanup: unwind.is_cleanup(),
};

let destructor_block = self.elaborator.patch().new_block(result);

let block_start = Location { block: destructor_block, statement_index: 0 };
self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow);

self.drop_flag_test_block(destructor_block, succ, unwind)
self.elaborator.patch().new_block(result)
}

/// Create a loop that drops an array:
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/elaborate_drops.rs
Original file line number Diff line number Diff line change
@@ -236,8 +236,8 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
}

impl fmt::Debug for ElaborateDropsCtxt<'_, '_> {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ElaborateDropsCtxt").finish_non_exhaustive()
}
}

4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/shim.rs
Original file line number Diff line number Diff line change
@@ -339,8 +339,8 @@ pub(super) struct DropShimElaborator<'a, 'tcx> {
}

impl fmt::Debug for DropShimElaborator<'_, '_> {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
Ok(())
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_struct("DropShimElaborator").finish_non_exhaustive()
}
}

1 change: 1 addition & 0 deletions compiler/rustc_passes/src/input_stats.rs
Original file line number Diff line number Diff line change
@@ -305,6 +305,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
Deref,
Ref,
Lit,
Guard,
Range,
Slice,
Err
Loading