Skip to content

Commit 50ab4b9

Browse files
committed
Auto merge of #135213 - matthiaskrgr:rollup-jgjnmel, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #131146 (Stop clearing box's drop flags early) - #133810 (remove unnecessary `eval_verify_bound`) - #134745 (Normalize each signature input/output in `typeck_with_fallback` with its own span) - #134989 (Lower Guard Patterns to HIR.) - #135149 (Use a post-monomorphization typing env when mangling components that come from impls) - #135171 (rustdoc: use stable paths as preferred canonical paths) - #135200 (rustfmt: drop nightly-gating of the `--style-edition` flag registration) r? `@ghost` `@rustbot` modify labels: rollup
2 parents ad211ce + bd9744d commit 50ab4b9

File tree

49 files changed

+569
-194
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+569
-194
lines changed

compiler/rustc_ast_lowering/src/pat.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
120120
self.lower_range_end(end, e2.is_some()),
121121
);
122122
}
123-
// FIXME(guard_patterns): lower pattern guards to HIR
124-
PatKind::Guard(inner, _) => pattern = inner,
123+
PatKind::Guard(inner, cond) => {
124+
break hir::PatKind::Guard(self.lower_pat(inner), self.lower_expr(cond));
125+
}
125126
PatKind::Slice(pats) => break self.lower_pat_slice(pats),
126127
PatKind::Rest => {
127128
// If we reach here the `..` pattern is not semantically allowed.

compiler/rustc_borrowck/src/region_infer/mod.rs

+8-18
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
978978
propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
979979
) -> bool {
980980
let tcx = infcx.tcx;
981-
let TypeTest { generic_kind, lower_bound, span: blame_span, ref verify_bound } = *type_test;
981+
let TypeTest { generic_kind, lower_bound, span: blame_span, verify_bound: _ } = *type_test;
982982

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

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

compiler/rustc_hir/src/hir.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1387,7 +1387,7 @@ impl<'hir> Pat<'hir> {
13871387
use PatKind::*;
13881388
match self.kind {
13891389
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => true,
1390-
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
1390+
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
13911391
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
13921392
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
13931393
Slice(before, slice, after) => {
@@ -1414,7 +1414,7 @@ impl<'hir> Pat<'hir> {
14141414
use PatKind::*;
14151415
match self.kind {
14161416
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => {}
1417-
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
1417+
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
14181418
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
14191419
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
14201420
Slice(before, slice, after) => {
@@ -1566,6 +1566,9 @@ pub enum PatKind<'hir> {
15661566
/// A literal.
15671567
Lit(&'hir Expr<'hir>),
15681568

1569+
/// A guard pattern (e.g., `x if guard(x)`).
1570+
Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
1571+
15691572
/// A range pattern (e.g., `1..=2` or `1..2`).
15701573
Range(Option<&'hir Expr<'hir>>, Option<&'hir Expr<'hir>>, RangeEnd),
15711574

compiler/rustc_hir/src/intravisit.rs

+4
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,10 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
696696
visit_opt!(visitor, visit_pat, slice_pattern);
697697
walk_list!(visitor, visit_pat, postpatterns);
698698
}
699+
PatKind::Guard(subpat, condition) => {
700+
try_visit!(visitor.visit_pat(subpat));
701+
try_visit!(visitor.visit_expr(condition));
702+
}
699703
}
700704
V::Result::output()
701705
}

compiler/rustc_hir_analysis/src/check/region.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ fn resolve_local<'tcx>(
654654
/// | ( ..., P&, ... )
655655
/// | ... "|" P& "|" ...
656656
/// | box P&
657+
/// | P& if ...
657658
/// ```
658659
fn is_binding_pat(pat: &hir::Pat<'_>) -> bool {
659660
// Note that the code below looks for *explicit* refs only, that is, it won't
@@ -694,7 +695,9 @@ fn resolve_local<'tcx>(
694695
| PatKind::TupleStruct(_, subpats, _)
695696
| PatKind::Tuple(subpats, _) => subpats.iter().any(|p| is_binding_pat(p)),
696697

697-
PatKind::Box(subpat) | PatKind::Deref(subpat) => is_binding_pat(subpat),
698+
PatKind::Box(subpat) | PatKind::Deref(subpat) | PatKind::Guard(subpat, _) => {
699+
is_binding_pat(subpat)
700+
}
698701

699702
PatKind::Ref(_, _)
700703
| PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)

compiler/rustc_hir_pretty/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1999,6 +1999,12 @@ impl<'a> State<'a> {
19991999
self.commasep(Inconsistent, after, |s, p| s.print_pat(p));
20002000
self.word("]");
20012001
}
2002+
PatKind::Guard(inner, cond) => {
2003+
self.print_pat(inner);
2004+
self.space();
2005+
self.word_space("if");
2006+
self.print_expr(cond);
2007+
}
20022008
PatKind::Err(_) => {
20032009
self.popen();
20042010
self.word("/*ERROR*/");

compiler/rustc_hir_typeck/src/expr.rs

+3
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
456456
// Does not constitute a read.
457457
hir::PatKind::Wild => false,
458458

459+
// Might not constitute a read, since the condition might be false.
460+
hir::PatKind::Guard(_, _) => true,
461+
459462
// This is unnecessarily restrictive when the pattern that doesn't
460463
// constitute a read is unreachable.
461464
//

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
615615
| PatKind::Box(_)
616616
| PatKind::Deref(_)
617617
| PatKind::Ref(..)
618+
| PatKind::Guard(..)
618619
| PatKind::Wild
619620
| PatKind::Err(_) => {
620621
// 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
17371738
}
17381739
}
17391740

1740-
PatKind::Binding(.., Some(subpat)) => {
1741+
PatKind::Binding(.., Some(subpat)) | PatKind::Guard(subpat, _) => {
17411742
self.cat_pattern(place_with_id, subpat, op)?;
17421743
}
17431744

compiler/rustc_hir_typeck/src/lib.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,23 @@ fn typeck_with_fallback<'tcx>(
147147
check_abi(tcx, span, fn_sig.abi());
148148

149149
// Compute the function signature from point of view of inside the fn.
150-
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
151-
let fn_sig = fcx.normalize(body.value.span, fn_sig);
150+
let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
151+
152+
// Normalize the input and output types one at a time, using a different
153+
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
154+
// on the entire `FnSig`, since this would use the same `WellFormedLoc`
155+
// for each type, preventing the HIR wf check from generating
156+
// a nice error message.
157+
let arg_span =
158+
|idx| decl.inputs.get(idx).map_or(decl.output.span(), |arg: &hir::Ty<'_>| arg.span);
159+
160+
fn_sig.inputs_and_output = tcx.mk_type_list_from_iter(
161+
fn_sig
162+
.inputs_and_output
163+
.iter()
164+
.enumerate()
165+
.map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)),
166+
);
152167

153168
check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params());
154169
} else {

compiler/rustc_hir_typeck/src/pat.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
284284
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
285285
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
286286
}
287+
PatKind::Guard(pat, cond) => {
288+
self.check_pat(pat, expected, pat_info);
289+
self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
290+
expected
291+
}
287292
PatKind::Or(pats) => {
288293
for pat in pats {
289294
self.check_pat(pat, expected, pat_info);
@@ -422,7 +427,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
422427
// An OR-pattern just propagates to each individual alternative.
423428
// This is maximally flexible, allowing e.g., `Some(mut x) | &Some(mut x)`.
424429
// In that example, `Some(mut x)` results in `Peel` whereas `&Some(mut x)` in `Reset`.
425-
| PatKind::Or(_) => AdjustMode::Pass,
430+
| PatKind::Or(_)
431+
// Like or-patterns, guard patterns just propogate to their subpatterns.
432+
| PatKind::Guard(..) => AdjustMode::Pass,
426433
}
427434
}
428435

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

compiler/rustc_middle/src/ty/print/mod.rs

+19-21
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,25 @@ pub trait Printer<'tcx>: Sized {
4545
&mut self,
4646
impl_def_id: DefId,
4747
args: &'tcx [GenericArg<'tcx>],
48-
self_ty: Ty<'tcx>,
49-
trait_ref: Option<ty::TraitRef<'tcx>>,
5048
) -> Result<(), PrintError> {
51-
self.default_print_impl_path(impl_def_id, args, self_ty, trait_ref)
49+
let tcx = self.tcx();
50+
let self_ty = tcx.type_of(impl_def_id);
51+
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
52+
let (self_ty, impl_trait_ref) = if tcx.generics_of(impl_def_id).count() <= args.len() {
53+
(
54+
self_ty.instantiate(tcx, args),
55+
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(tcx, args)),
56+
)
57+
} else {
58+
// We are probably printing a nested item inside of an impl.
59+
// Use the identity substitutions for the impl.
60+
(
61+
self_ty.instantiate_identity(),
62+
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
63+
)
64+
};
65+
66+
self.default_print_impl_path(impl_def_id, self_ty, impl_trait_ref)
5267
}
5368

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

110-
DefPathData::Impl => {
111-
let generics = self.tcx().generics_of(def_id);
112-
let self_ty = self.tcx().type_of(def_id);
113-
let impl_trait_ref = self.tcx().impl_trait_ref(def_id);
114-
let (self_ty, impl_trait_ref) = if args.len() >= generics.count() {
115-
(
116-
self_ty.instantiate(self.tcx(), args),
117-
impl_trait_ref.map(|i| i.instantiate(self.tcx(), args)),
118-
)
119-
} else {
120-
(
121-
self_ty.instantiate_identity(),
122-
impl_trait_ref.map(|i| i.instantiate_identity()),
123-
)
124-
};
125-
self.print_impl_path(def_id, args, self_ty, impl_trait_ref)
126-
}
125+
DefPathData::Impl => self.print_impl_path(def_id, args),
127126

128127
_ => {
129128
let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
@@ -201,7 +200,6 @@ pub trait Printer<'tcx>: Sized {
201200
fn default_print_impl_path(
202201
&mut self,
203202
impl_def_id: DefId,
204-
_args: &'tcx [GenericArg<'tcx>],
205203
self_ty: Ty<'tcx>,
206204
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
207205
) -> Result<(), PrintError> {

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
435435

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

438+
// FIXME(guard_patterns): implement guard pattern lowering
439+
hir::PatKind::Guard(pat, _) => self.lower_pattern(pat).kind,
440+
438441
hir::PatKind::Err(guar) => PatKind::Error(guar),
439442
};
440443

compiler/rustc_mir_dataflow/src/elaborate_drops.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -460,13 +460,19 @@ where
460460

461461
if adt.is_box() {
462462
// we need to drop the inside of the box before running the destructor
463-
let succ = self.destructor_call_block(contents_drop);
463+
let destructor = self.destructor_call_block(contents_drop);
464464
let unwind = contents_drop
465465
.1
466466
.map(|unwind| self.destructor_call_block((unwind, Unwind::InCleanup)));
467467

468-
self.open_drop_for_box_contents(adt, args, succ, unwind)
468+
let boxed_drop = self.open_drop_for_box_contents(adt, args, destructor, unwind);
469+
470+
// the drop flag will be at the end of contents_drop
471+
self.drop_flag_test_block(boxed_drop, self.succ, unwind)
469472
} else if adt.has_dtor(self.tcx()) {
473+
// We don't need to test drop flags here because
474+
// this path is only taken with DropShimElaborator
475+
// where testing drop flags is a noop
470476
self.destructor_call_block(contents_drop)
471477
} else {
472478
contents_drop.0
@@ -659,13 +665,7 @@ where
659665
}),
660666
is_cleanup: unwind.is_cleanup(),
661667
};
662-
663-
let destructor_block = self.elaborator.patch().new_block(result);
664-
665-
let block_start = Location { block: destructor_block, statement_index: 0 };
666-
self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow);
667-
668-
self.drop_flag_test_block(destructor_block, succ, unwind)
668+
self.elaborator.patch().new_block(result)
669669
}
670670

671671
/// Create a loop that drops an array:

compiler/rustc_mir_transform/src/elaborate_drops.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
236236
}
237237

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

compiler/rustc_mir_transform/src/shim.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,8 @@ pub(super) struct DropShimElaborator<'a, 'tcx> {
339339
}
340340

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

compiler/rustc_passes/src/input_stats.rs

+1
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
305305
Deref,
306306
Ref,
307307
Lit,
308+
Guard,
308309
Range,
309310
Slice,
310311
Err

0 commit comments

Comments
 (0)