Skip to content

Commit 37f6ccc

Browse files
authored
Unrolled build for #155047
Rollup merge of #155047 - jdonszelmann:lint-against-eq-typing-mode, r=lcnr Always exhaustively match on typing mode r? @lcnr Unimplements Eq/PartialEq for TypingMode, adds TypingModeEqWrapper for the few cases where we need it (mainly in the query system), and adds a new rustc internal lint to detect cases where we non-exhaustively match on typing mode.
2 parents 8317fef + 18d118a commit 37f6ccc

39 files changed

Lines changed: 465 additions & 78 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,3 +1349,12 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcIntrinsicConstStableIndirectPar
13491349
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
13501350
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect;
13511351
}
1352+
1353+
pub(crate) struct RustcExhaustiveParser;
1354+
1355+
impl<S: Stage> NoArgsAttributeParser<S> for RustcExhaustiveParser {
1356+
const PATH: &'static [Symbol] = &[sym::rustc_must_match_exhaustively];
1357+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
1358+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Enum)]);
1359+
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcMustMatchExhaustively;
1360+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ attribute_parsers!(
297297
Single<WithoutArgs<RustcEffectiveVisibilityParser>>,
298298
Single<WithoutArgs<RustcEiiForeignItemParser>>,
299299
Single<WithoutArgs<RustcEvaluateWhereClausesParser>>,
300+
Single<WithoutArgs<RustcExhaustiveParser>>,
300301
Single<WithoutArgs<RustcHasIncoherentInherentImplsParser>>,
301302
Single<WithoutArgs<RustcHiddenTypeOfOpaquesParser>>,
302303
Single<WithoutArgs<RustcInheritOverflowChecksParser>>,

compiler/rustc_const_eval/src/check_consts/qualifs.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,10 @@ impl Qualif for HasMutInterior {
103103
// FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR
104104
// typeck results without causing query cycles, we should use this here instead of defining
105105
// opaque types.
106-
let typing_env = ty::TypingEnv {
107-
typing_mode: ty::TypingMode::analysis_in_body(
108-
cx.tcx,
109-
cx.body.source.def_id().expect_local(),
110-
),
111-
param_env: cx.typing_env.param_env,
112-
};
106+
let typing_env = ty::TypingEnv::new(
107+
cx.typing_env.param_env,
108+
ty::TypingMode::analysis_in_body(cx.tcx, cx.body.source.def_id().expect_local()),
109+
);
113110
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(typing_env);
114111
let ocx = ObligationCtxt::new(&infcx);
115112
let obligation = Obligation::new(

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,20 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
371371
// This shouldn't be used for statics, since statics are conceptually places,
372372
// not values -- so what we do here could break pointer identity.
373373
assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));
374-
// Const eval always happens in PostAnalysis mode . See the comment in
375-
// `InterpCx::new` for more details.
376-
debug_assert_eq!(key.typing_env.typing_mode, ty::TypingMode::PostAnalysis);
374+
377375
if cfg!(debug_assertions) {
376+
match key.typing_env.typing_mode() {
377+
ty::TypingMode::PostAnalysis => {}
378+
ty::TypingMode::Coherence
379+
| ty::TypingMode::Analysis { .. }
380+
| ty::TypingMode::Borrowck { .. }
381+
| ty::TypingMode::PostBorrowckAnalysis { .. } => {
382+
bug!(
383+
"Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details."
384+
)
385+
}
386+
}
387+
378388
// Make sure we format the instance even if we do not print it.
379389
// This serves as a regression test against an ICE on printing.
380390
// The next two lines concatenated contain some discussion:

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,19 @@ pub(crate) fn eval_to_valtree<'tcx>(
236236
typing_env: ty::TypingEnv<'tcx>,
237237
cid: GlobalId<'tcx>,
238238
) -> EvalToValTreeResult<'tcx> {
239-
// Const eval always happens in PostAnalysis mode . See the comment in
240-
// `InterpCx::new` for more details.
241-
debug_assert_eq!(typing_env.typing_mode, ty::TypingMode::PostAnalysis);
239+
if cfg!(debug_assertions) {
240+
match typing_env.typing_mode() {
241+
ty::TypingMode::PostAnalysis => {}
242+
ty::TypingMode::Coherence
243+
| ty::TypingMode::Analysis { .. }
244+
| ty::TypingMode::Borrowck { .. }
245+
| ty::TypingMode::PostBorrowckAnalysis { .. } => {
246+
bug!(
247+
"Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details."
248+
)
249+
}
250+
}
251+
}
242252
let const_alloc = tcx.eval_to_allocation_raw(typing_env.as_query_input(cid))?;
243253

244254
// FIXME Need to provide a span to `eval_to_valtree`

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::debug_assert_matches;
2-
31
use either::{Left, Right};
42
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout};
53
use rustc_hir::def_id::DefId;
@@ -11,9 +9,10 @@ use rustc_middle::ty::layout::{
119
LayoutOfHelpers, TyAndLayout,
1210
};
1311
use rustc_middle::ty::{
14-
self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingEnv, Variance,
12+
self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingEnv, TypingMode,
13+
Variance,
1514
};
16-
use rustc_middle::{mir, span_bug};
15+
use rustc_middle::{bug, mir, span_bug};
1716
use rustc_span::Span;
1817
use rustc_target::callconv::FnAbi;
1918
use tracing::{debug, trace};
@@ -243,7 +242,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
243242
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
244243
// types that are not specified in the opaque type. We also use MIR bodies whose opaque types have
245244
// already been revealed, so we'd be able to at least partially observe the hidden types anyways.
246-
debug_assert_matches!(typing_env.typing_mode, ty::TypingMode::PostAnalysis);
245+
if cfg!(debug_assertions) {
246+
match typing_env.typing_mode() {
247+
TypingMode::PostAnalysis => {}
248+
TypingMode::Coherence
249+
| TypingMode::Analysis { .. }
250+
| TypingMode::Borrowck { .. }
251+
| TypingMode::PostBorrowckAnalysis { .. } => {
252+
bug!("Const eval should always happens in PostAnalysis mode.");
253+
}
254+
}
255+
}
256+
247257
InterpCx {
248258
machine,
249259
tcx: tcx.at(root_span),

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,6 +1414,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
14141414
rustc_scalable_vector, Normal, template!(List: &["count"]), WarnFollowing, EncodeCrossCrate::Yes,
14151415
"`#[rustc_scalable_vector]` defines a scalable vector type"
14161416
),
1417+
rustc_attr!(
1418+
rustc_must_match_exhaustively, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
1419+
"enums with `#[rustc_must_match_exhaustively]` must be matched on with a match block that mentions all variants explicitly"
1420+
),
14171421

14181422
// ==========================================================================
14191423
// Internal attributes, Testing:

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,9 @@ pub enum AttributeKind {
14711471
fn_names: ThinVec<Ident>,
14721472
},
14731473

1474+
/// Represents `#[rustc_must_match_exhaustively]`
1475+
RustcMustMatchExhaustively(Span),
1476+
14741477
/// Represents `#[rustc_never_returns_null_ptr]`
14751478
RustcNeverReturnsNullPtr,
14761479

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ impl AttributeKind {
156156
RustcMain => No,
157157
RustcMir(..) => Yes,
158158
RustcMustImplementOneOf { .. } => No,
159+
RustcMustMatchExhaustively(..) => Yes,
159160
RustcNeverReturnsNullPtr => Yes,
160161
RustcNeverTypeOptions { .. } => No,
161162
RustcNoImplicitAutorefs => Yes,

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_middle::ty::{
1313
self, BoundVar, GenericArg, InferConst, List, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeFolder,
1414
TypeSuperFoldable, TypeVisitableExt,
1515
};
16+
use rustc_type_ir::TypingModeEqWrapper;
1617
use smallvec::SmallVec;
1718
use tracing::debug;
1819

@@ -72,7 +73,7 @@ impl<'tcx> InferCtxt<'tcx> {
7273
query_state,
7374
)
7475
.unchecked_map(|(param_env, value)| param_env.and(value));
75-
CanonicalQueryInput { canonical, typing_mode: self.typing_mode() }
76+
CanonicalQueryInput { canonical, typing_mode: TypingModeEqWrapper(self.typing_mode()) }
7677
}
7778

7879
/// Canonicalizes a query *response* `V`. When we canonicalize a

0 commit comments

Comments
 (0)