Skip to content

Commit e64f849

Browse files
committed
Auto merge of #120025 - matthiaskrgr:rollup-e9ai06k, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #118361 (stabilise bound_map) - #119816 (Define hidden types in confirmation) - #119900 (Inline `check_closure`, simplify `deduce_sig_from_projection`) - #119969 (Simplify `closure_env_ty` and `closure_env_param`) - #119990 (Add private `NonZero<T>` type alias.) - #119998 (Update books) - #120002 (Lint `overlapping_ranges_endpoints` directly instead of collecting into a Vec) - #120018 (Don't allow `.html` files in `tests/mir-opt/`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents bf2637f + 9154410 commit e64f849

File tree

21 files changed

+220
-221
lines changed

21 files changed

+220
-221
lines changed

Diff for: compiler/rustc_borrowck/src/universal_regions.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
668668
kind: ty::BrEnv,
669669
};
670670
let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br);
671-
let closure_ty = tcx.closure_env_ty(def_id, args, env_region).unwrap();
671+
let closure_ty = tcx.closure_env_ty(
672+
Ty::new_closure(tcx, def_id, args),
673+
args.as_closure().kind(),
674+
env_region,
675+
);
672676

673677
// The "inputs" of the closure in the
674678
// signature appear as a tuple. The MIR side

Diff for: compiler/rustc_hir_typeck/src/closure.rs

+15-52
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
1414
use rustc_middle::ty::GenericArgs;
1515
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
1616
use rustc_span::def_id::LocalDefId;
17-
use rustc_span::{sym, Span};
17+
use rustc_span::Span;
1818
use rustc_target::spec::abi::Abi;
1919
use rustc_trait_selection::traits;
2020
use rustc_trait_selection::traits::error_reporting::ArgKind;
@@ -49,7 +49,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4949
expr_span: Span,
5050
expected: Expectation<'tcx>,
5151
) -> Ty<'tcx> {
52-
trace!("decl = {:#?}", closure.fn_decl);
52+
let tcx = self.tcx;
53+
let body = tcx.hir().body(closure.body);
54+
let expr_def_id = closure.def_id;
5355

5456
// It's always helpful for inference if we know the kind of
5557
// closure sooner rather than later, so first examine the expected
@@ -61,24 +63,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6163
None => (None, None),
6264
};
6365

64-
self.check_closure(closure, expr_span, expected_kind, expected_sig)
65-
}
66-
67-
#[instrument(skip(self, closure), level = "debug", ret)]
68-
fn check_closure(
69-
&self,
70-
closure: &hir::Closure<'tcx>,
71-
expr_span: Span,
72-
opt_kind: Option<ty::ClosureKind>,
73-
expected_sig: Option<ExpectedSig<'tcx>>,
74-
) -> Ty<'tcx> {
75-
let tcx = self.tcx;
76-
let body = tcx.hir().body(closure.body);
77-
78-
trace!("decl = {:#?}", closure.fn_decl);
79-
let expr_def_id = closure.def_id;
80-
debug!(?expr_def_id);
81-
8266
let ClosureSignatures { bound_sig, liberated_sig } =
8367
self.sig_of_closure(expr_def_id, closure.fn_decl, closure.kind, expected_sig);
8468

@@ -139,9 +123,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
139123
}
140124
};
141125

142-
let mut fcx = FnCtxt::new(self, self.param_env, closure.def_id);
143126
check_fn(
144-
&mut fcx,
127+
&mut FnCtxt::new(self, self.param_env, closure.def_id),
145128
liberated_sig,
146129
coroutine_types,
147130
closure.fn_decl,
@@ -174,9 +157,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
174157
)
175158
});
176159

177-
debug!(?sig, ?opt_kind);
160+
debug!(?sig, ?expected_kind);
178161

179-
let closure_kind_ty = match opt_kind {
162+
let closure_kind_ty = match expected_kind {
180163
Some(kind) => Ty::from_closure_kind(tcx, kind),
181164

182165
// Create a type variable (for now) to represent the closure kind.
@@ -204,11 +187,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
204187
let Some(CoroutineTypes { resume_ty, yield_ty }) = coroutine_types else {
205188
bug!("expected coroutine to have yield/resume types");
206189
};
207-
let interior = fcx.next_ty_var(TypeVariableOrigin {
190+
let interior = self.next_ty_var(TypeVariableOrigin {
208191
kind: TypeVariableOriginKind::MiscVariable,
209192
span: body.value.span,
210193
});
211-
fcx.deferred_coroutine_interiors.borrow_mut().push((
194+
self.deferred_coroutine_interiors.borrow_mut().push((
212195
expr_def_id,
213196
body.id(),
214197
interior,
@@ -364,36 +347,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
364347
let tcx = self.tcx;
365348

366349
let trait_def_id = projection.trait_def_id(tcx);
367-
368-
let is_fn = tcx.is_fn_trait(trait_def_id);
369-
370-
let coroutine_trait = tcx.lang_items().coroutine_trait();
371-
let is_gen = coroutine_trait == Some(trait_def_id);
372-
373-
if !is_fn && !is_gen {
374-
debug!("not fn or coroutine");
350+
// For now, we only do signature deduction based off of the `Fn` traits.
351+
if !tcx.is_fn_trait(trait_def_id) {
375352
return None;
376353
}
377354

378-
// Check that we deduce the signature from the `<_ as std::ops::Coroutine>::Return`
379-
// associated item and not yield.
380-
if is_gen && self.tcx.associated_item(projection.projection_def_id()).name != sym::Return {
381-
debug!("not `Return` assoc item of `Coroutine`");
382-
return None;
383-
}
384-
385-
let input_tys = if is_fn {
386-
let arg_param_ty = projection.skip_binder().projection_ty.args.type_at(1);
387-
let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty);
388-
debug!(?arg_param_ty);
355+
let arg_param_ty = projection.skip_binder().projection_ty.args.type_at(1);
356+
let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty);
357+
debug!(?arg_param_ty);
389358

390-
match arg_param_ty.kind() {
391-
&ty::Tuple(tys) => tys,
392-
_ => return None,
393-
}
394-
} else {
395-
// Coroutines with a `()` resume type may be defined with 0 or 1 explicit arguments,
396-
// else they must have exactly 1 argument. For now though, just give up in this case.
359+
let ty::Tuple(input_tys) = *arg_param_ty.kind() else {
397360
return None;
398361
};
399362

Diff for: compiler/rustc_middle/src/ty/util.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -604,19 +604,15 @@ impl<'tcx> TyCtxt<'tcx> {
604604
/// wrapped in a binder.
605605
pub fn closure_env_ty(
606606
self,
607-
closure_def_id: DefId,
608-
closure_args: GenericArgsRef<'tcx>,
607+
closure_ty: Ty<'tcx>,
608+
closure_kind: ty::ClosureKind,
609609
env_region: ty::Region<'tcx>,
610-
) -> Option<Ty<'tcx>> {
611-
let closure_ty = Ty::new_closure(self, closure_def_id, closure_args);
612-
let closure_kind_ty = closure_args.as_closure().kind_ty();
613-
let closure_kind = closure_kind_ty.to_opt_closure_kind()?;
614-
let env_ty = match closure_kind {
610+
) -> Ty<'tcx> {
611+
match closure_kind {
615612
ty::ClosureKind::Fn => Ty::new_imm_ref(self, env_region, closure_ty),
616613
ty::ClosureKind::FnMut => Ty::new_mut_ref(self, env_region, closure_ty),
617614
ty::ClosureKind::FnOnce => closure_ty,
618-
};
619-
Some(env_ty)
615+
}
620616
}
621617

622618
/// Returns `true` if the node pointed to by `def_id` is a `static` item.

Diff for: compiler/rustc_mir_build/src/thir/cx/mod.rs

+19-37
Original file line numberDiff line numberDiff line change
@@ -117,50 +117,32 @@ impl<'tcx> Cx<'tcx> {
117117
pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p)
118118
}
119119

120-
fn closure_env_param(&self, owner_def: LocalDefId, owner_id: HirId) -> Option<Param<'tcx>> {
121-
match self.tcx.def_kind(owner_def) {
122-
DefKind::Closure if self.tcx.is_coroutine(owner_def.to_def_id()) => {
123-
let coroutine_ty = self.typeck_results.node_type(owner_id);
124-
let coroutine_param = Param {
125-
ty: coroutine_ty,
126-
pat: None,
127-
ty_span: None,
128-
self_kind: None,
129-
hir_id: None,
130-
};
131-
Some(coroutine_param)
120+
fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option<Param<'tcx>> {
121+
if self.tcx.def_kind(owner_def) != DefKind::Closure {
122+
return None;
123+
}
124+
125+
let closure_ty = self.typeck_results.node_type(expr_id);
126+
Some(match *closure_ty.kind() {
127+
ty::Coroutine(..) => {
128+
Param { ty: closure_ty, pat: None, ty_span: None, self_kind: None, hir_id: None }
132129
}
133-
DefKind::Closure => {
134-
let closure_ty = self.typeck_results.node_type(owner_id);
135-
136-
let ty::Closure(closure_def_id, closure_args) = *closure_ty.kind() else {
137-
bug!("closure expr does not have closure type: {:?}", closure_ty);
138-
};
139-
140-
let bound_vars =
141-
self.tcx.mk_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]);
142-
let br = ty::BoundRegion {
143-
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
144-
kind: ty::BrEnv,
145-
};
146-
let env_region = ty::Region::new_bound(self.tcx, ty::INNERMOST, br);
147-
let closure_env_ty =
148-
self.tcx.closure_env_ty(closure_def_id, closure_args, env_region).unwrap();
149-
let liberated_closure_env_ty = self.tcx.instantiate_bound_regions_with_erased(
150-
ty::Binder::bind_with_vars(closure_env_ty, bound_vars),
130+
ty::Closure(_, closure_args) => {
131+
let closure_env_ty = self.tcx.closure_env_ty(
132+
closure_ty,
133+
closure_args.as_closure().kind(),
134+
self.tcx.lifetimes.re_erased,
151135
);
152-
let env_param = Param {
153-
ty: liberated_closure_env_ty,
136+
Param {
137+
ty: closure_env_ty,
154138
pat: None,
155139
ty_span: None,
156140
self_kind: None,
157141
hir_id: None,
158-
};
159-
160-
Some(env_param)
142+
}
161143
}
162-
_ => None,
163-
}
144+
_ => bug!("unexpected closure type: {closure_ty}"),
145+
})
164146
}
165147

166148
fn explicit_params<'a>(

Diff for: compiler/rustc_pattern_analysis/src/lib.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,9 @@ use rustc_middle::ty::Ty;
2727
#[cfg(feature = "rustc")]
2828
use rustc_span::ErrorGuaranteed;
2929

30-
use crate::constructor::{Constructor, ConstructorSet};
30+
use crate::constructor::{Constructor, ConstructorSet, IntRange};
3131
#[cfg(feature = "rustc")]
32-
use crate::lints::{
33-
lint_nonexhaustive_missing_variants, lint_overlapping_range_endpoints, PatternColumn,
34-
};
32+
use crate::lints::{lint_nonexhaustive_missing_variants, PatternColumn};
3533
use crate::pat::DeconstructedPat;
3634
#[cfg(feature = "rustc")]
3735
use crate::rustc::RustcMatchCheckCtxt;
@@ -77,6 +75,17 @@ pub trait TypeCx: Sized + fmt::Debug {
7775

7876
/// Raise a bug.
7977
fn bug(&self, fmt: fmt::Arguments<'_>) -> !;
78+
79+
/// Lint that the range `pat` overlapped with all the ranges in `overlaps_with`, where the range
80+
/// they overlapped over is `overlaps_on`. We only detect singleton overlaps.
81+
/// The default implementation does nothing.
82+
fn lint_overlapping_range_endpoints(
83+
&self,
84+
_pat: &DeconstructedPat<'_, Self>,
85+
_overlaps_on: IntRange,
86+
_overlaps_with: &[&DeconstructedPat<'_, Self>],
87+
) {
88+
}
8089
}
8190

8291
/// Context that provides information global to a match.
@@ -111,16 +120,10 @@ pub fn analyze_match<'p, 'tcx>(
111120

112121
let report = compute_match_usefulness(cx, arms, scrut_ty, scrut_validity)?;
113122

114-
let pat_column = PatternColumn::new(arms);
115-
116-
// Lint ranges that overlap on their endpoints, which is likely a mistake.
117-
if !report.overlapping_range_endpoints.is_empty() {
118-
lint_overlapping_range_endpoints(cx, &report.overlapping_range_endpoints);
119-
}
120-
121123
// Run the non_exhaustive_omitted_patterns lint. Only run on refutable patterns to avoid hitting
122124
// `if let`s. Only run if the match is exhaustive otherwise the error is redundant.
123125
if tycx.refutable && report.non_exhaustiveness_witnesses.is_empty() {
126+
let pat_column = PatternColumn::new(arms);
124127
lint_nonexhaustive_missing_variants(cx, arms, &pat_column, scrut_ty)?;
125128
}
126129

Diff for: compiler/rustc_pattern_analysis/src/lints.rs

+3-29
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
use rustc_session::lint;
21
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
32
use rustc_span::ErrorGuaranteed;
43

5-
use crate::errors::{
6-
self, NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Uncovered,
7-
};
4+
use crate::errors::{NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Uncovered};
85
use crate::pat::PatOrWild;
96
use crate::rustc::{
10-
self, Constructor, DeconstructedPat, MatchArm, MatchCtxt, PlaceCtxt, RevealedTy,
11-
RustcMatchCheckCtxt, SplitConstructorSet, WitnessPat,
7+
Constructor, DeconstructedPat, MatchArm, MatchCtxt, PlaceCtxt, RevealedTy, RustcMatchCheckCtxt,
8+
SplitConstructorSet, WitnessPat,
129
};
1310

1411
/// A column of patterns in the matrix, where a column is the intuitive notion of "subpatterns that
@@ -196,26 +193,3 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
196193
}
197194
Ok(())
198195
}
199-
200-
pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>(
201-
cx: MatchCtxt<'a, 'p, 'tcx>,
202-
overlapping_range_endpoints: &[rustc::OverlappingRanges<'p, 'tcx>],
203-
) {
204-
let rcx = cx.tycx;
205-
for overlap in overlapping_range_endpoints {
206-
let overlap_as_pat = rcx.hoist_pat_range(&overlap.overlaps_on, overlap.pat.ty());
207-
let overlaps: Vec<_> = overlap
208-
.overlaps_with
209-
.iter()
210-
.map(|pat| pat.data().unwrap().span)
211-
.map(|span| errors::Overlap { range: overlap_as_pat.clone(), span })
212-
.collect();
213-
let pat_span = overlap.pat.data().unwrap().span;
214-
rcx.tcx.emit_spanned_lint(
215-
lint::builtin::OVERLAPPING_RANGE_ENDPOINTS,
216-
rcx.match_lint_level,
217-
pat_span,
218-
errors::OverlappingRangeEndpoints { overlap: overlaps, range: pat_span },
219-
);
220-
}
221-
}

Diff for: compiler/rustc_pattern_analysis/src/rustc.rs

+27-10
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
1+
use smallvec::SmallVec;
12
use std::fmt;
23
use std::iter::once;
34

45
use rustc_arena::{DroplessArena, TypedArena};
56
use rustc_data_structures::captures::Captures;
67
use rustc_hir::def_id::DefId;
78
use rustc_hir::HirId;
8-
use rustc_index::Idx;
9-
use rustc_index::IndexVec;
9+
use rustc_index::{Idx, IndexVec};
1010
use rustc_middle::middle::stability::EvalResult;
1111
use rustc_middle::mir::interpret::Scalar;
1212
use rustc_middle::mir::{self, Const};
1313
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange, PatRangeBoundary};
1414
use rustc_middle::ty::layout::IntegerExt;
15-
use rustc_middle::ty::TypeVisitableExt;
16-
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, VariantDef};
17-
use rustc_span::ErrorGuaranteed;
18-
use rustc_span::{Span, DUMMY_SP};
15+
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeVisitableExt, VariantDef};
16+
use rustc_session::lint;
17+
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
1918
use rustc_target::abi::{FieldIdx, Integer, VariantIdx, FIRST_VARIANT};
20-
use smallvec::SmallVec;
2119

2220
use crate::constructor::{
2321
IntRange, MaybeInfiniteInt, OpaqueId, RangeEnd, Slice, SliceKind, VariantVisibility,
2422
};
25-
use crate::TypeCx;
23+
use crate::{errors, TypeCx};
2624

2725
use crate::constructor::Constructor::*;
2826

@@ -34,8 +32,6 @@ pub type DeconstructedPat<'p, 'tcx> =
3432
crate::pat::DeconstructedPat<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
3533
pub type MatchArm<'p, 'tcx> = crate::MatchArm<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
3634
pub type MatchCtxt<'a, 'p, 'tcx> = crate::MatchCtxt<'a, RustcMatchCheckCtxt<'p, 'tcx>>;
37-
pub type OverlappingRanges<'p, 'tcx> =
38-
crate::usefulness::OverlappingRanges<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
3935
pub(crate) type PlaceCtxt<'a, 'p, 'tcx> =
4036
crate::usefulness::PlaceCtxt<'a, RustcMatchCheckCtxt<'p, 'tcx>>;
4137
pub(crate) type SplitConstructorSet<'p, 'tcx> =
@@ -991,6 +987,27 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
991987
fn bug(&self, fmt: fmt::Arguments<'_>) -> ! {
992988
span_bug!(self.scrut_span, "{}", fmt)
993989
}
990+
991+
fn lint_overlapping_range_endpoints(
992+
&self,
993+
pat: &crate::pat::DeconstructedPat<'_, Self>,
994+
overlaps_on: IntRange,
995+
overlaps_with: &[&crate::pat::DeconstructedPat<'_, Self>],
996+
) {
997+
let overlap_as_pat = self.hoist_pat_range(&overlaps_on, pat.ty());
998+
let overlaps: Vec<_> = overlaps_with
999+
.iter()
1000+
.map(|pat| pat.data().unwrap().span)
1001+
.map(|span| errors::Overlap { range: overlap_as_pat.clone(), span })
1002+
.collect();
1003+
let pat_span = pat.data().unwrap().span;
1004+
self.tcx.emit_spanned_lint(
1005+
lint::builtin::OVERLAPPING_RANGE_ENDPOINTS,
1006+
self.match_lint_level,
1007+
pat_span,
1008+
errors::OverlappingRangeEndpoints { overlap: overlaps, range: pat_span },
1009+
);
1010+
}
9941011
}
9951012

9961013
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.

0 commit comments

Comments
 (0)