From ff2f7a7a834843ea74b1e7d6511eb4ad06f43981 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Wed, 6 Nov 2024 19:46:54 +0000 Subject: Point at `const` definition when used instead of a binding in a `let` statement After: ``` error[E0005]: refutable pattern in local binding --> $DIR/bad-pattern.rs:19:13 | LL | const PAT: u32 = 0; | -------------- missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable ... LL | let PAT = v1; | ^^^ | | | pattern `1_u32..=u32::MAX` not covered | help: introduce a variable instead: `PAT_var` | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `u32` ``` Before: ``` error[E0005]: refutable pattern in local binding --> $DIR/bad-pattern.rs:19:13 | LL | let PAT = v1; | ^^^ | | | pattern `1_u32..=u32::MAX` not covered | missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable | help: introduce a variable instead: `PAT_var` | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `u32` ``` --- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_pattern_analysis/src') diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 9ea5023064c..6496d9fd73d 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -536,7 +536,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { ), } } - PatKind::Constant { value } => { + PatKind::Constant { value } | PatKind::NamedConstant { value, span: _ } => { match ty.kind() { ty::Bool => { ctor = match value.try_eval_bool(cx.tcx, cx.param_env) { -- cgit 1.4.1-3-g733a5 From c25b44bee96e4489dab8f44409ba347bfeb328b9 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Wed, 6 Nov 2024 21:10:31 +0000 Subject: Fold `PatKind::NamedConstant` into `PatKind::Constant` --- compiler/rustc_middle/src/thir.rs | 9 ++------- compiler/rustc_middle/src/thir/visit.rs | 2 +- .../rustc_mir_build/src/build/custom/parse/instruction.rs | 4 +--- compiler/rustc_mir_build/src/build/matches/match_pair.rs | 4 +--- compiler/rustc_mir_build/src/build/matches/mod.rs | 1 - compiler/rustc_mir_build/src/check_unsafety.rs | 1 - compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 5 +++-- compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 7 ++++++- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 13 ++++--------- compiler/rustc_mir_build/src/thir/print.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_ty_utils/src/consts.rs | 4 +--- 12 files changed, 21 insertions(+), 33 deletions(-) (limited to 'compiler/rustc_pattern_analysis/src') diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 821f8c99704..84f5f3a4611 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -640,7 +640,6 @@ impl<'tcx> Pat<'tcx> { | Range(..) | Binding { subpattern: None, .. } | Constant { .. } - | NamedConstant { .. } | Error(_) => {} AscribeUserType { subpattern, .. } | Binding { subpattern: Some(subpattern), .. } @@ -787,12 +786,8 @@ pub enum PatKind<'tcx> { /// * `String`, if `string_deref_patterns` is enabled. Constant { value: mir::Const<'tcx>, - }, - - /// Same as `Constant`, but that came from a `const` that we can point at in diagnostics. - NamedConstant { - value: mir::Const<'tcx>, - span: Span, + /// The `const` item this constant came from, if any. + opt_def: Option, }, /// Inline constant found while lowering a pattern. diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 759ed77dbcb..92c0add65ba 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -246,7 +246,7 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor.visit_pat(&subpattern.pattern); } } - Constant { value: _ } | NamedConstant { value: _, span: _ } => {} + Constant { value: _, opt_def: _ } => {} InlineConstant { def: _, subpattern } => visitor.visit_pat(subpattern), Range(_) => {} Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => { diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 049586fd6a0..60624855fea 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -144,9 +144,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { let mut targets = Vec::new(); for arm in rest { let arm = &self.thir[*arm]; - let (PatKind::Constant { value } | PatKind::NamedConstant { value, span: _ }) = - arm.pattern.kind - else { + let PatKind::Constant { value, opt_def: _ } = arm.pattern.kind else { return Err(ParseError { span: arm.pattern.span, item_description: format!("{:?}", arm.pattern.kind), diff --git a/compiler/rustc_mir_build/src/build/matches/match_pair.rs b/compiler/rustc_mir_build/src/build/matches/match_pair.rs index 83a1e021484..df3cf53eb17 100644 --- a/compiler/rustc_mir_build/src/build/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/build/matches/match_pair.rs @@ -129,9 +129,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> { } } - PatKind::Constant { value } | PatKind::NamedConstant { value, span: _ } => { - TestCase::Constant { value } - } + PatKind::Constant { value, opt_def: _ } => TestCase::Constant { value }, PatKind::AscribeUserType { ascription: thir::Ascription { ref annotation, variance }, diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index ac5be665654..a62d4e9d873 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -882,7 +882,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } PatKind::Constant { .. } - | PatKind::NamedConstant { .. } | PatKind::Range { .. } | PatKind::Wild | PatKind::Never diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index d073cbdd877..33e194fa246 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -316,7 +316,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { PatKind::Binding { .. } // match is conditional on having this value | PatKind::Constant { .. } - | PatKind::NamedConstant { .. } | PatKind::Variant { .. } | PatKind::Leaf { .. } | PatKind::Deref { .. } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index b54e1c2b552..f3cfc8b1a22 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -670,13 +670,14 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let mut interpreted_as_const = None; let mut interpreted_as_const_sugg = None; - if let PatKind::NamedConstant { span, .. } + if let PatKind::Constant { opt_def: Some(def_id), .. } | PatKind::AscribeUserType { - subpattern: box Pat { kind: PatKind::NamedConstant { span, .. }, .. }, + subpattern: box Pat { kind: PatKind::Constant { opt_def: Some(def_id), .. }, .. }, .. } = pat.kind && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span) { + let span = self.tcx.def_span(def_id); // When we encounter a constant as the binding name, point at the `const` definition. interpreted_as_const = Some(span); interpreted_as_const_sugg = diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 82632350af5..06b13274efc 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -266,6 +266,7 @@ impl<'tcx> ConstToPat<'tcx> { // optimization for now. ty::Str => PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), + opt_def: None, }, // All other references are converted into deref patterns and then recursively // convert the dereferenced constant to a pattern that is the sub-pattern of the @@ -311,13 +312,17 @@ impl<'tcx> ConstToPat<'tcx> { } else { PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), + opt_def: None, } } } ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => { // The raw pointers we see here have been "vetted" by valtree construction to be // just integers, so we simply allow them. - PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)) } + PatKind::Constant { + value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), + opt_def: None, + } } ty::FnPtr(..) => { unreachable!( diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 260ace55fba..11d06e5a1cc 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -157,9 +157,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } kind => (kind, None, None), }; - let value = if let PatKind::Constant { value } - | PatKind::NamedConstant { value, span: _ } = kind - { + let value = if let PatKind::Constant { value, opt_def: _ } = kind { value } else { let msg = format!( @@ -253,7 +251,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { (RangeEnd::Included, Some(Ordering::Less)) => {} // `x..=y` where `x == y` and `x` and `y` are finite. (RangeEnd::Included, Some(Ordering::Equal)) if lo.is_finite() && hi.is_finite() => { - kind = PatKind::Constant { value: lo.as_finite().unwrap() }; + kind = PatKind::Constant { value: lo.as_finite().unwrap(), opt_def: None }; } // `..=x` where `x == ty::MIN`. (RangeEnd::Included, Some(Ordering::Equal)) if !lo.is_finite() => {} @@ -562,15 +560,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => return pat_from_kind(self.lower_variant_or_leaf(res, id, span, ty, vec![])), }; - // HERE let args = self.typeck_results.node_args(id); let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args }); - let def_span = self.tcx.def_span(def_id); let mut pattern = self.const_to_pat(c, ty, id, span); - if let PatKind::Constant { value } = pattern.kind { - pattern.kind = PatKind::NamedConstant { value, span: def_span }; + if let PatKind::Constant { value, opt_def: None } = pattern.kind { + pattern.kind = PatKind::Constant { value, opt_def: Some(def_id) }; } - tracing::info!("pattern {pattern:#?} {c:?} {ty:?} {id:?}"); if !is_associated_const { return pattern; diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 3fe75439339..43bca812bbd 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -702,7 +702,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.print_pat(subpattern, depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } - PatKind::Constant { value } | PatKind::NamedConstant { value, span: _ } => { + PatKind::Constant { value, opt_def: _ } => { print_indented!(self, "Constant {", depth_lvl + 1); print_indented!(self, format!("value: {:?}", value), depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 6496d9fd73d..ec671150c40 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -536,7 +536,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { ), } } - PatKind::Constant { value } | PatKind::NamedConstant { value, span: _ } => { + PatKind::Constant { value, opt_def: _ } => { match ty.kind() { ty::Bool => { ctor = match value.try_eval_bool(cx.tcx, cx.param_env) { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 3a0eb8143cd..12f169d718c 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -370,9 +370,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> { } match pat.kind { - thir::PatKind::Constant { value } | thir::PatKind::NamedConstant { value, span: _ } => { - value.has_non_region_param() - } + thir::PatKind::Constant { value, opt_def: _ } => value.has_non_region_param(), thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => { lo.has_non_region_param() || hi.has_non_region_param() } -- cgit 1.4.1-3-g733a5 From f563efec156319d726095a82ea3d0f167c7edac7 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 7 Nov 2024 19:34:23 +0000 Subject: Unify expanded constants and named constants in `PatKind` --- compiler/rustc_middle/src/thir.rs | 22 ++++--- compiler/rustc_middle/src/thir/visit.rs | 4 +- .../src/build/custom/parse/instruction.rs | 2 +- .../src/build/matches/match_pair.rs | 10 ++- compiler/rustc_mir_build/src/build/matches/mod.rs | 2 +- compiler/rustc_mir_build/src/check_unsafety.rs | 10 ++- .../src/thir/pattern/check_match.rs | 8 ++- .../src/thir/pattern/const_to_pat.rs | 7 +-- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 37 ++++++++--- compiler/rustc_mir_build/src/thir/print.rs | 9 +-- compiler/rustc_pattern_analysis/src/rustc.rs | 4 +- compiler/rustc_ty_utils/src/consts.rs | 2 +- tests/ui/consts/const-pattern-irrefutable.rs | 21 ++++++- tests/ui/consts/const-pattern-irrefutable.stderr | 39 +++++++++--- .../const_in_pattern/incomplete-slice.stderr | 12 ++++ .../pattern/usefulness/match-arm-statics-2.stderr | 12 ++++ .../slice-patterns-exhaustiveness.stderr | 72 ++++++++++++++++++++++ 17 files changed, 215 insertions(+), 58 deletions(-) (limited to 'compiler/rustc_pattern_analysis/src') diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 84f5f3a4611..f37c8486df5 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -645,7 +645,7 @@ impl<'tcx> Pat<'tcx> { | Binding { subpattern: Some(subpattern), .. } | Deref { subpattern } | DerefPattern { subpattern, .. } - | InlineConstant { subpattern, .. } => subpattern.walk_(it), + | ExpandedConstant { subpattern, .. } => subpattern.walk_(it), Leaf { subpatterns } | Variant { subpatterns, .. } => { subpatterns.iter().for_each(|field| field.pattern.walk_(it)) } @@ -786,16 +786,18 @@ pub enum PatKind<'tcx> { /// * `String`, if `string_deref_patterns` is enabled. Constant { value: mir::Const<'tcx>, - /// The `const` item this constant came from, if any. - opt_def: Option, }, - /// Inline constant found while lowering a pattern. - InlineConstant { - /// [LocalDefId] of the constant, we need this so that we have a + /// Inline or named constant found while lowering a pattern. + ExpandedConstant { + /// [DefId] of the constant, we need this so that we have a /// reference that can be used by unsafety checking to visit nested - /// unevaluated constants. - def: LocalDefId, + /// unevaluated constants. If the `DefId` doesn't correspond to a local + /// crate, it points at the `const` item. + def_id: DefId, + /// If `false`, then `def_id` points at a `const` item, otherwise it + /// corresponds to a local inline const. + is_inline: bool, /// If the inline constant is used in a range pattern, this subpattern /// represents the range (if both ends are inline constants, there will /// be multiple InlineConstant wrappers). @@ -1086,8 +1088,8 @@ mod size_asserts { static_assert_size!(Block, 48); static_assert_size!(Expr<'_>, 64); static_assert_size!(ExprKind<'_>, 40); - static_assert_size!(Pat<'_>, 72); - static_assert_size!(PatKind<'_>, 56); + static_assert_size!(Pat<'_>, 64); + static_assert_size!(PatKind<'_>, 48); static_assert_size!(Stmt<'_>, 48); static_assert_size!(StmtKind<'_>, 48); // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 92c0add65ba..81202a6eaad 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -246,8 +246,8 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor.visit_pat(&subpattern.pattern); } } - Constant { value: _, opt_def: _ } => {} - InlineConstant { def: _, subpattern } => visitor.visit_pat(subpattern), + Constant { value: _ } => {} + ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern), Range(_) => {} Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => { for subpattern in prefix.iter() { diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 60624855fea..07964e304b9 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -144,7 +144,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { let mut targets = Vec::new(); for arm in rest { let arm = &self.thir[*arm]; - let PatKind::Constant { value, opt_def: _ } = arm.pattern.kind else { + let PatKind::Constant { value } = arm.pattern.kind else { return Err(ParseError { span: arm.pattern.span, item_description: format!("{:?}", arm.pattern.kind), diff --git a/compiler/rustc_mir_build/src/build/matches/match_pair.rs b/compiler/rustc_mir_build/src/build/matches/match_pair.rs index df3cf53eb17..6beabb5ccdb 100644 --- a/compiler/rustc_mir_build/src/build/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/build/matches/match_pair.rs @@ -129,7 +129,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> { } } - PatKind::Constant { value, opt_def: _ } => TestCase::Constant { value }, + PatKind::Constant { value } => TestCase::Constant { value }, PatKind::AscribeUserType { ascription: thir::Ascription { ref annotation, variance }, @@ -162,7 +162,11 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> { TestCase::Irrefutable { ascription: None, binding } } - PatKind::InlineConstant { subpattern: ref pattern, def, .. } => { + PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => { + subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx)); + default_irrefutable() + } + PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => { // Apply a type ascription for the inline constant to the value at `match_pair.place` let ascription = place.map(|source| { let span = pattern.span; @@ -173,7 +177,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> { }) .args; let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf( - def.to_def_id(), + def_id, ty::UserArgs { args, user_self_ty: None }, )); let annotation = ty::CanonicalUserTypeAnnotation { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index a62d4e9d873..9f81e1052d6 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -917,7 +917,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.visit_primary_bindings(subpattern, subpattern_user_ty, f) } - PatKind::InlineConstant { ref subpattern, .. } => { + PatKind::ExpandedConstant { ref subpattern, .. } => { self.visit_primary_bindings(subpattern, pattern_user_ty, f) } diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 33e194fa246..52e5f2950a5 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -332,7 +332,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { PatKind::Wild | // these just wrap other patterns, which we recurse on below. PatKind::Or { .. } | - PatKind::InlineConstant { .. } | + PatKind::ExpandedConstant { .. } | PatKind::AscribeUserType { .. } | PatKind::Error(_) => {} } @@ -386,8 +386,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { visit::walk_pat(self, pat); self.inside_adt = old_inside_adt; } - PatKind::InlineConstant { def, .. } => { - self.visit_inner_body(*def); + PatKind::ExpandedConstant { def_id, is_inline, .. } => { + if let Some(def) = def_id.as_local() + && *is_inline + { + self.visit_inner_body(def); + } visit::walk_pat(self, pat); } _ => { diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index edd51b521fa..1cab055864d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -670,11 +670,13 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let mut interpreted_as_const = None; let mut interpreted_as_const_sugg = None; - if let PatKind::Constant { opt_def: Some(def_id), .. } + if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } | PatKind::AscribeUserType { - subpattern: box Pat { kind: PatKind::Constant { opt_def: Some(def_id), .. }, .. }, + subpattern: + box Pat { kind: PatKind::ExpandedConstant { def_id, is_inline: false, .. }, .. }, .. } = pat.kind + && let DefKind::Const = self.tcx.def_kind(def_id) { let span = self.tcx.def_span(def_id); let variable = self.tcx.item_name(def_id).to_string(); @@ -1145,7 +1147,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( for &arm in arms { let arm = &thir.arms[arm]; - if let PatKind::Constant { opt_def: Some(def_id), .. } = arm.pattern.kind { + if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = arm.pattern.kind { let const_name = cx.tcx.item_name(def_id); err.span_label( arm.pattern.span, diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 06b13274efc..82632350af5 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -266,7 +266,6 @@ impl<'tcx> ConstToPat<'tcx> { // optimization for now. ty::Str => PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), - opt_def: None, }, // All other references are converted into deref patterns and then recursively // convert the dereferenced constant to a pattern that is the sub-pattern of the @@ -312,17 +311,13 @@ impl<'tcx> ConstToPat<'tcx> { } else { PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), - opt_def: None, } } } ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => { // The raw pointers we see here have been "vetted" by valtree construction to be // just integers, so we simply allow them. - PatKind::Constant { - value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), - opt_def: None, - } + PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)) } } ty::FnPtr(..) => { unreachable!( diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 11d06e5a1cc..c732eeb40a2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -149,15 +149,18 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { None => Ok((None, None, None)), Some(expr) => { let (kind, ascr, inline_const) = match self.lower_lit(expr) { - PatKind::InlineConstant { subpattern, def } => { - (subpattern.kind, None, Some(def)) + PatKind::ExpandedConstant { subpattern, def_id, is_inline: true } => { + (subpattern.kind, None, def_id.as_local()) + } + PatKind::ExpandedConstant { subpattern, is_inline: false, .. } => { + (subpattern.kind, None, None) } PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => { (kind, Some(ascription), None) } kind => (kind, None, None), }; - let value = if let PatKind::Constant { value, opt_def: _ } = kind { + let value = if let PatKind::Constant { value } = kind { value } else { let msg = format!( @@ -251,7 +254,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { (RangeEnd::Included, Some(Ordering::Less)) => {} // `x..=y` where `x == y` and `x` and `y` are finite. (RangeEnd::Included, Some(Ordering::Equal)) if lo.is_finite() && hi.is_finite() => { - kind = PatKind::Constant { value: lo.as_finite().unwrap(), opt_def: None }; + kind = PatKind::Constant { value: lo.as_finite().unwrap() }; } // `..=x` where `x == ty::MIN`. (RangeEnd::Included, Some(Ordering::Equal)) if !lo.is_finite() => {} @@ -288,7 +291,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { }; } for def in [lo_inline, hi_inline].into_iter().flatten() { - kind = PatKind::InlineConstant { def, subpattern: Box::new(Pat { span, ty, kind }) }; + kind = PatKind::ExpandedConstant { + def_id: def.to_def_id(), + is_inline: true, + subpattern: Box::new(Pat { span, ty, kind }), + }; } Ok(kind) } @@ -562,10 +569,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let args = self.typeck_results.node_args(id); let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args }); - let mut pattern = self.const_to_pat(c, ty, id, span); - if let PatKind::Constant { value, opt_def: None } = pattern.kind { - pattern.kind = PatKind::Constant { value, opt_def: Some(def_id) }; - } + let subpattern = self.const_to_pat(c, ty, id, span); + let pattern = if let hir::QPath::Resolved(None, path) = qpath + && path.segments.len() == 1 + { + // We only want to mark constants when referenced as bare names that could have been + // new bindings if the `const` didn't exist. + Box::new(Pat { + span, + ty, + kind: PatKind::ExpandedConstant { subpattern, def_id, is_inline: false }, + }) + } else { + subpattern + }; if !is_associated_const { return pattern; @@ -640,7 +657,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args }; let subpattern = self.const_to_pat(ty::Const::new_unevaluated(self.tcx, ct), ty, id, span); - PatKind::InlineConstant { subpattern, def: def_id } + PatKind::ExpandedConstant { subpattern, def_id: def_id.to_def_id(), is_inline: true } } /// Converts literals, paths and negation of literals to patterns. diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 43bca812bbd..6be0ed5fb31 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -702,14 +702,15 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.print_pat(subpattern, depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } - PatKind::Constant { value, opt_def: _ } => { + PatKind::Constant { value } => { print_indented!(self, "Constant {", depth_lvl + 1); print_indented!(self, format!("value: {:?}", value), depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } - PatKind::InlineConstant { def, subpattern } => { - print_indented!(self, "InlineConstant {", depth_lvl + 1); - print_indented!(self, format!("def: {:?}", def), depth_lvl + 2); + PatKind::ExpandedConstant { def_id, is_inline, subpattern } => { + print_indented!(self, "ExpandedConstant {", depth_lvl + 1); + print_indented!(self, format!("def_id: {def_id:?}"), depth_lvl + 2); + print_indented!(self, format!("is_inline: {is_inline:?}"), depth_lvl + 2); print_indented!(self, "subpattern:", depth_lvl + 2); self.print_pat(subpattern, depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index ec671150c40..7cc6ba24450 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -453,7 +453,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let fields: Vec<_>; match &pat.kind { PatKind::AscribeUserType { subpattern, .. } - | PatKind::InlineConstant { subpattern, .. } => return self.lower_pat(subpattern), + | PatKind::ExpandedConstant { subpattern, .. } => return self.lower_pat(subpattern), PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat), PatKind::Binding { subpattern: None, .. } | PatKind::Wild => { ctor = Wildcard; @@ -536,7 +536,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { ), } } - PatKind::Constant { value, opt_def: _ } => { + PatKind::Constant { value } => { match ty.kind() { ty::Bool => { ctor = match value.try_eval_bool(cx.tcx, cx.param_env) { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 12f169d718c..637e239a570 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -370,7 +370,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> { } match pat.kind { - thir::PatKind::Constant { value, opt_def: _ } => value.has_non_region_param(), + thir::PatKind::Constant { value } => value.has_non_region_param(), thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => { lo.has_non_region_param() || hi.has_non_region_param() } diff --git a/tests/ui/consts/const-pattern-irrefutable.rs b/tests/ui/consts/const-pattern-irrefutable.rs index c590ec8fcd3..759d2e8b2ed 100644 --- a/tests/ui/consts/const-pattern-irrefutable.rs +++ b/tests/ui/consts/const-pattern-irrefutable.rs @@ -1,7 +1,7 @@ mod foo { pub const b: u8 = 2; //~^ missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable - pub const d: u8 = 2; + pub const d: (u8, u8) = (2, 1); //~^ missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable } @@ -11,6 +11,15 @@ use foo::d; const a: u8 = 2; //~^ missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable +#[derive(PartialEq)] +struct S { + foo: u8, +} + +const e: S = S { + foo: 0, +}; + fn main() { let a = 4; //~^ ERROR refutable pattern in local binding @@ -20,9 +29,15 @@ fn main() { //~^ ERROR refutable pattern in local binding //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered //~| HELP introduce a variable instead - let d = 4; + let d = (4, 4); //~^ ERROR refutable pattern in local binding - //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered + //~| patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered + //~| HELP introduce a variable instead + let e = S { + //~^ ERROR refutable pattern in local binding + //~| pattern `S { foo: 1_u8..=u8::MAX }` not covered //~| HELP introduce a variable instead + foo: 1, + }; fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115). } diff --git a/tests/ui/consts/const-pattern-irrefutable.stderr b/tests/ui/consts/const-pattern-irrefutable.stderr index c118ce9e48f..4206e3fe704 100644 --- a/tests/ui/consts/const-pattern-irrefutable.stderr +++ b/tests/ui/consts/const-pattern-irrefutable.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:15:9 + --> $DIR/const-pattern-irrefutable.rs:24:9 | LL | const a: u8 = 2; | ----------- missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable @@ -15,7 +15,7 @@ LL | let a = 4; = note: the matched value is of type `u8` error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:19:9 + --> $DIR/const-pattern-irrefutable.rs:28:9 | LL | pub const b: u8 = 2; | --------------- missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable @@ -31,21 +31,42 @@ LL | let c = 4; = note: the matched value is of type `u8` error[E0005]: refutable pattern in local binding - --> $DIR/const-pattern-irrefutable.rs:23:9 + --> $DIR/const-pattern-irrefutable.rs:32:9 | -LL | pub const d: u8 = 2; - | --------------- missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable +LL | pub const d: (u8, u8) = (2, 1); + | --------------------- missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable ... -LL | let d = 4; +LL | let d = (4, 4); | ^ | | - | patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered + | patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered | help: introduce a variable instead: `d_var` | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html - = note: the matched value is of type `u8` + = note: the matched value is of type `(u8, u8)` + +error[E0005]: refutable pattern in local binding + --> $DIR/const-pattern-irrefutable.rs:36:9 + | +LL | const e: S = S { + | ---------- missing patterns are not covered because `e` is interpreted as a constant pattern, not a new variable +... +LL | let e = S { + | ^ + | | + | pattern `S { foo: 1_u8..=u8::MAX }` not covered + | help: introduce a variable instead: `e_var` + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +note: `S` defined here + --> $DIR/const-pattern-irrefutable.rs:15:8 + | +LL | struct S { + | ^ + = note: the matched value is of type `S` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0005`. diff --git a/tests/ui/consts/const_in_pattern/incomplete-slice.stderr b/tests/ui/consts/const_in_pattern/incomplete-slice.stderr index bd61f43727b..c73d1f05900 100644 --- a/tests/ui/consts/const_in_pattern/incomplete-slice.stderr +++ b/tests/ui/consts/const_in_pattern/incomplete-slice.stderr @@ -3,8 +3,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered | LL | match &[][..] { | ^^^^^^^ patterns `&[]` and `&[_, _, ..]` not covered +LL | +LL | E_SL => {} + | ---- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `E_SL` | = note: the matched value is of type `&[E]` +note: constant `E_SL` defined here + --> $DIR/incomplete-slice.rs:6:1 + | +LL | const E_SL: &[E] = &[E::A]; + | ^^^^^^^^^^^^^^^^ +help: if you meant to introduce a binding, use a different name + | +LL | E_SL_var => {} + | ++++ help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL ~ E_SL => {}, diff --git a/tests/ui/pattern/usefulness/match-arm-statics-2.stderr b/tests/ui/pattern/usefulness/match-arm-statics-2.stderr index e4dd35a5995..60b4fcca286 100644 --- a/tests/ui/pattern/usefulness/match-arm-statics-2.stderr +++ b/tests/ui/pattern/usefulness/match-arm-statics-2.stderr @@ -3,8 +3,20 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered | LL | match (true, false) { | ^^^^^^^^^^^^^ pattern `(true, false)` not covered +LL | +LL | TRUE_TRUE => (), + | --------- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `TRUE_TRUE` | = note: the matched value is of type `(bool, bool)` +note: constant `TRUE_TRUE` defined here + --> $DIR/match-arm-statics-2.rs:14:1 + | +LL | const TRUE_TRUE: (bool, bool) = (true, true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: if you meant to introduce a binding, use a different name + | +LL | TRUE_TRUE_var => (), + | ++++ help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ (false, true) => (), diff --git a/tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr b/tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr index a8786d02414..0a3991fe3d1 100644 --- a/tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr +++ b/tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr @@ -199,8 +199,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered | LL | match s { | ^ patterns `&[]` and `&[_, _, ..]` not covered +LL | +LL | CONST => {} + | ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST` | = note: the matched value is of type `&[bool]` +note: constant `CONST` defined here + --> $DIR/slice-patterns-exhaustiveness.rs:88:5 + | +LL | const CONST: &[bool] = &[true]; + | ^^^^^^^^^^^^^^^^^^^^ +help: if you meant to introduce a binding, use a different name + | +LL | CONST_var => {} + | ++++ help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL ~ CONST => {}, @@ -212,8 +224,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered | LL | match s { | ^ patterns `&[]` and `&[_, _, ..]` not covered +LL | +LL | CONST => {} + | ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST` | = note: the matched value is of type `&[bool]` +note: constant `CONST` defined here + --> $DIR/slice-patterns-exhaustiveness.rs:88:5 + | +LL | const CONST: &[bool] = &[true]; + | ^^^^^^^^^^^^^^^^^^^^ +help: if you meant to introduce a binding, use a different name + | +LL | CONST_var => {} + | ++++ help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL ~ &[false] => {}, @@ -225,8 +249,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered | LL | match s { | ^ patterns `&[]` and `&[_, _, ..]` not covered +... +LL | CONST => {} + | ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST` | = note: the matched value is of type `&[bool]` +note: constant `CONST` defined here + --> $DIR/slice-patterns-exhaustiveness.rs:88:5 + | +LL | const CONST: &[bool] = &[true]; + | ^^^^^^^^^^^^^^^^^^^^ +help: if you meant to introduce a binding, use a different name + | +LL | CONST_var => {} + | ++++ help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL ~ CONST => {}, @@ -238,8 +274,20 @@ error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered | LL | match s { | ^ pattern `&[_, _, ..]` not covered +... +LL | CONST => {} + | ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST` | = note: the matched value is of type `&[bool]` +note: constant `CONST` defined here + --> $DIR/slice-patterns-exhaustiveness.rs:88:5 + | +LL | const CONST: &[bool] = &[true]; + | ^^^^^^^^^^^^^^^^^^^^ +help: if you meant to introduce a binding, use a different name + | +LL | CONST_var => {} + | ++++ help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ CONST => {}, @@ -251,8 +299,20 @@ error[E0004]: non-exhaustive patterns: `&[false]` not covered | LL | match s { | ^ pattern `&[false]` not covered +... +LL | CONST => {} + | ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST` | = note: the matched value is of type `&[bool]` +note: constant `CONST` defined here + --> $DIR/slice-patterns-exhaustiveness.rs:88:5 + | +LL | const CONST: &[bool] = &[true]; + | ^^^^^^^^^^^^^^^^^^^^ +help: if you meant to introduce a binding, use a different name + | +LL | CONST_var => {} + | ++++ help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ &[_, _, ..] => {}, @@ -264,8 +324,20 @@ error[E0004]: non-exhaustive patterns: `&[false]` not covered | LL | match s1 { | ^^ pattern `&[false]` not covered +LL | +LL | CONST1 => {} + | ------ this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST1` | = note: the matched value is of type `&[bool; 1]` +note: constant `CONST1` defined here + --> $DIR/slice-patterns-exhaustiveness.rs:124:5 + | +LL | const CONST1: &[bool; 1] = &[true]; + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: if you meant to introduce a binding, use a different name + | +LL | CONST1_var => {} + | ++++ help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ CONST1 => {}, -- cgit 1.4.1-3-g733a5 From 9cba14b95bb07a5b31ed1aac2bf4eadd248232da Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 15 Nov 2024 13:53:31 +0100 Subject: use `TypingEnv` when no `infcx` is available the behavior of the type system not only depends on the current assumptions, but also the currentnphase of the compiler. This is mostly necessary as we need to decide whether and how to reveal opaque types. We track this via the `TypingMode`. --- .../src/diagnostics/conflict_errors.rs | 19 +++- compiler/rustc_borrowck/src/diagnostics/mod.rs | 2 +- .../src/diagnostics/region_errors.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +- compiler/rustc_codegen_cranelift/src/abi/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/base.rs | 10 +- compiler/rustc_codegen_cranelift/src/common.rs | 18 ++-- compiler/rustc_codegen_cranelift/src/constant.rs | 11 +- .../rustc_codegen_cranelift/src/debuginfo/mod.rs | 8 +- compiler/rustc_codegen_cranelift/src/inline_asm.rs | 10 +- .../rustc_codegen_cranelift/src/intrinsics/mod.rs | 9 +- compiler/rustc_codegen_cranelift/src/lib.rs | 2 +- compiler/rustc_codegen_cranelift/src/main_shim.rs | 6 +- compiler/rustc_codegen_cranelift/src/unsize.rs | 3 +- .../rustc_codegen_cranelift/src/value_and_place.rs | 18 ++-- compiler/rustc_codegen_gcc/src/builder.rs | 10 +- compiler/rustc_codegen_gcc/src/consts.rs | 2 +- compiler/rustc_codegen_gcc/src/context.rs | 16 +-- compiler/rustc_codegen_gcc/src/int.rs | 7 +- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 6 +- compiler/rustc_codegen_gcc/src/intrinsic/simd.rs | 10 +- compiler/rustc_codegen_gcc/src/mono_item.rs | 9 +- compiler/rustc_codegen_llvm/src/builder.rs | 10 +- compiler/rustc_codegen_llvm/src/callee.rs | 9 +- compiler/rustc_codegen_llvm/src/consts.rs | 6 +- compiler/rustc_codegen_llvm/src/context.rs | 10 +- .../src/debuginfo/create_scope_map.rs | 4 +- .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 19 ++-- .../src/debuginfo/metadata/type_map.rs | 26 +++-- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 11 +- compiler/rustc_codegen_llvm/src/debuginfo/utils.rs | 4 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 13 ++- compiler/rustc_codegen_llvm/src/mono_item.rs | 9 +- .../rustc_codegen_ssa/src/back/symbol_export.rs | 6 +- compiler/rustc_codegen_ssa/src/base.rs | 13 ++- .../rustc_codegen_ssa/src/debuginfo/type_names.rs | 31 +++--- compiler/rustc_codegen_ssa/src/mir/block.rs | 14 +-- compiler/rustc_codegen_ssa/src/mir/constant.rs | 6 +- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 6 +- compiler/rustc_codegen_ssa/src/traits/type_.rs | 16 +-- .../rustc_const_eval/src/check_consts/check.rs | 11 +- compiler/rustc_const_eval/src/check_consts/mod.rs | 8 +- compiler/rustc_const_eval/src/check_consts/ops.rs | 8 +- .../src/check_consts/post_drop_elaboration.rs | 8 +- .../rustc_const_eval/src/check_consts/qualifs.rs | 24 +++-- .../rustc_const_eval/src/check_consts/resolver.rs | 5 +- .../src/const_eval/eval_queries.rs | 6 +- .../rustc_const_eval/src/const_eval/machine.rs | 3 +- .../rustc_const_eval/src/const_eval/valtrees.rs | 11 +- compiler/rustc_const_eval/src/interpret/call.rs | 58 +++++------ compiler/rustc_const_eval/src/interpret/cast.rs | 4 +- .../rustc_const_eval/src/interpret/eval_context.rs | 52 ++++------ .../rustc_const_eval/src/interpret/intrinsics.rs | 9 +- compiler/rustc_const_eval/src/interpret/memory.rs | 2 +- compiler/rustc_const_eval/src/interpret/operand.rs | 21 ++-- .../rustc_const_eval/src/interpret/operator.rs | 2 +- compiler/rustc_const_eval/src/interpret/place.rs | 12 +-- compiler/rustc_const_eval/src/interpret/stack.rs | 15 ++- compiler/rustc_const_eval/src/interpret/step.rs | 3 +- .../rustc_const_eval/src/interpret/validity.rs | 6 +- compiler/rustc_const_eval/src/lib.rs | 2 +- compiler/rustc_const_eval/src/util/alignment.rs | 6 +- .../src/util/check_validity_requirement.rs | 10 +- .../rustc_const_eval/src/util/compare_types.rs | 13 +-- compiler/rustc_hir_analysis/src/check/check.rs | 22 ++-- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 5 +- .../rustc_hir_analysis/src/coherence/builtin.rs | 4 +- .../rustc_hir_analysis/src/hir_ty_lowering/cmse.rs | 10 +- compiler/rustc_hir_typeck/src/expr.rs | 6 +- compiler/rustc_hir_typeck/src/intrinsicck.rs | 4 +- compiler/rustc_hir_typeck/src/upvar.rs | 15 ++- compiler/rustc_hir_typeck/src/writeback.rs | 4 +- compiler/rustc_infer/src/infer/mod.rs | 46 ++++++++- compiler/rustc_lint/src/builtin.rs | 6 +- compiler/rustc_lint/src/context.rs | 14 ++- .../rustc_lint/src/for_loops_over_fallibles.rs | 4 +- compiler/rustc_lint/src/foreign_modules.rs | 30 +++--- compiler/rustc_lint/src/if_let_rescope.rs | 2 +- compiler/rustc_lint/src/internal.rs | 5 +- compiler/rustc_lint/src/let_underscore.rs | 2 +- compiler/rustc_lint/src/non_fmt_panic.rs | 16 +-- compiler/rustc_lint/src/noop_method_call.rs | 4 +- compiler/rustc_lint/src/tail_expr_drop_order.rs | 11 +- compiler/rustc_lint/src/types.rs | 45 ++++---- compiler/rustc_lint/src/unused.rs | 4 +- compiler/rustc_metadata/src/native_libs.rs | 4 +- compiler/rustc_middle/src/mir/consts.rs | 61 ++++++----- compiler/rustc_middle/src/mir/interpret/mod.rs | 8 +- compiler/rustc_middle/src/mir/interpret/queries.rs | 17 ++- compiler/rustc_middle/src/mir/mod.rs | 27 +++-- compiler/rustc_middle/src/mir/statement.rs | 4 +- compiler/rustc_middle/src/mir/syntax.rs | 9 +- compiler/rustc_middle/src/query/keys.rs | 14 ++- compiler/rustc_middle/src/query/mod.rs | 26 ++--- compiler/rustc_middle/src/thir.rs | 29 +++--- compiler/rustc_middle/src/ty/adt.rs | 5 +- compiler/rustc_middle/src/ty/consts.rs | 27 +++-- compiler/rustc_middle/src/ty/context.rs | 12 ++- .../src/ty/inhabitedness/inhabited_predicate.rs | 37 ++++--- compiler/rustc_middle/src/ty/inhabitedness/mod.rs | 8 +- compiler/rustc_middle/src/ty/instance.rs | 41 ++++---- compiler/rustc_middle/src/ty/layout.rs | 115 +++++++++++---------- compiler/rustc_middle/src/ty/mod.rs | 100 +++++++++++++++++- .../src/ty/normalize_erasing_regions.rs | 49 +++++---- compiler/rustc_middle/src/ty/util.rs | 58 ++++++----- compiler/rustc_middle/src/ty/vtable.rs | 4 +- compiler/rustc_middle/src/util/call_kind.rs | 8 +- compiler/rustc_mir_build/src/build/custom/mod.rs | 6 +- .../src/build/custom/parse/instruction.rs | 4 +- .../rustc_mir_build/src/build/expr/as_constant.rs | 3 +- .../rustc_mir_build/src/build/expr/as_operand.rs | 2 +- .../rustc_mir_build/src/build/expr/as_rvalue.rs | 18 ++-- compiler/rustc_mir_build/src/build/expr/into.rs | 6 +- compiler/rustc_mir_build/src/build/expr/stmt.rs | 2 +- .../src/build/matches/match_pair.rs | 2 +- compiler/rustc_mir_build/src/build/matches/test.rs | 17 +-- compiler/rustc_mir_build/src/build/misc.rs | 2 +- compiler/rustc_mir_build/src/build/mod.rs | 4 + compiler/rustc_mir_build/src/build/scope.rs | 2 +- compiler/rustc_mir_build/src/check_unsafety.rs | 4 +- compiler/rustc_mir_build/src/errors.rs | 2 +- compiler/rustc_mir_build/src/lints.rs | 13 ++- compiler/rustc_mir_build/src/thir/constant.rs | 5 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 7 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 12 +++ .../src/thir/pattern/check_match.rs | 6 +- .../src/thir/pattern/const_to_pat.rs | 15 ++- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 2 +- compiler/rustc_mir_dataflow/src/elaborate_drops.rs | 13 ++- compiler/rustc_mir_dataflow/src/value_analysis.rs | 16 +-- .../src/add_moves_for_packed_drops.rs | 10 +- .../rustc_mir_transform/src/check_packed_ref.rs | 9 +- compiler/rustc_mir_transform/src/coroutine.rs | 12 +-- compiler/rustc_mir_transform/src/cost_checker.rs | 10 +- .../rustc_mir_transform/src/dataflow_const_prop.rs | 43 ++++---- .../rustc_mir_transform/src/deduce_param_attrs.rs | 6 +- .../rustc_mir_transform/src/elaborate_drops.rs | 22 ++-- compiler/rustc_mir_transform/src/gvn.rs | 13 ++- compiler/rustc_mir_transform/src/inline.rs | 55 ++++------ compiler/rustc_mir_transform/src/inline/cycle.rs | 15 ++- compiler/rustc_mir_transform/src/instsimplify.rs | 12 ++- compiler/rustc_mir_transform/src/jump_threading.rs | 14 +-- .../rustc_mir_transform/src/known_panics_lint.rs | 31 +++--- compiler/rustc_mir_transform/src/large_enums.rs | 11 +- compiler/rustc_mir_transform/src/lib.rs | 18 ++-- compiler/rustc_mir_transform/src/match_branches.rs | 56 +++++----- compiler/rustc_mir_transform/src/promote_consts.rs | 6 +- .../rustc_mir_transform/src/remove_uninit_drops.rs | 22 ++-- .../src/remove_unneeded_drops.rs | 10 +- compiler/rustc_mir_transform/src/remove_zsts.rs | 8 +- compiler/rustc_mir_transform/src/reveal_all.rs | 12 ++- compiler/rustc_mir_transform/src/shim.rs | 14 +-- .../src/shim/async_destructor_ctor.rs | 8 +- .../rustc_mir_transform/src/simplify_branches.rs | 8 +- .../src/simplify_comparison_integral.rs | 4 +- compiler/rustc_mir_transform/src/sroa.rs | 14 +-- .../src/unreachable_enum_branching.rs | 4 +- compiler/rustc_mir_transform/src/validate.rs | 54 +++++----- compiler/rustc_monomorphize/src/collector.rs | 49 ++++++--- compiler/rustc_monomorphize/src/lib.rs | 4 +- .../src/mono_checks/abi_check.rs | 17 +-- .../src/mono_checks/move_check.rs | 6 +- compiler/rustc_monomorphize/src/partitioning.rs | 2 +- compiler/rustc_monomorphize/src/util.rs | 10 +- .../src/solve/trait_goals.rs | 6 +- compiler/rustc_passes/src/abi_test.rs | 36 ++++--- compiler/rustc_passes/src/dead.rs | 11 +- compiler/rustc_passes/src/layout_test.rs | 37 +++---- compiler/rustc_passes/src/liveness.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc.rs | 36 ++++--- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 4 +- .../src/cfi/typeid/itanium_cxx_abi/mod.rs | 4 +- .../src/cfi/typeid/itanium_cxx_abi/transform.rs | 18 ++-- compiler/rustc_smir/src/rustc_smir/alloc.rs | 8 +- compiler/rustc_smir/src/rustc_smir/builder.rs | 4 +- compiler/rustc_smir/src/rustc_smir/context.rs | 48 ++++++--- compiler/rustc_symbol_mangling/src/v0.rs | 9 +- .../infer/nice_region_error/static_impl_trait.rs | 2 +- .../error_reporting/traits/fulfillment_errors.rs | 2 +- .../src/traits/dyn_compatibility.rs | 6 +- compiler/rustc_trait_selection/src/traits/mod.rs | 5 +- .../src/traits/query/dropck_outlives.rs | 23 +++-- .../src/traits/select/candidate_assembly.rs | 14 ++- .../rustc_trait_selection/src/traits/vtable.rs | 8 +- compiler/rustc_traits/src/codegen.rs | 9 +- compiler/rustc_traits/src/dropck_outlives.rs | 6 +- .../rustc_traits/src/normalize_erasing_regions.rs | 8 +- .../rustc_transmute/src/maybe_transmutable/mod.rs | 4 +- compiler/rustc_ty_utils/src/abi.rs | 38 +++---- compiler/rustc_ty_utils/src/instance.rs | 30 +++--- compiler/rustc_ty_utils/src/layout.rs | 44 ++++---- compiler/rustc_ty_utils/src/layout/invariant.rs | 2 +- compiler/rustc_ty_utils/src/needs_drop.rs | 46 +++++---- compiler/rustc_type_ir/src/infer_ctxt.rs | 2 + compiler/rustc_type_ir/src/interner.rs | 9 +- src/librustdoc/clean/mod.rs | 6 +- src/librustdoc/clean/types.rs | 6 +- src/librustdoc/clean/utils.rs | 5 +- src/librustdoc/core.rs | 9 +- src/librustdoc/html/render/type_layout.rs | 6 +- .../clippy/clippy_lints/src/assigning_clones.rs | 2 +- .../clippy_lints/src/bool_assert_comparison.rs | 2 +- src/tools/clippy/clippy_lints/src/dereference.rs | 9 +- .../clippy/clippy_lints/src/drop_forget_ref.rs | 4 +- .../src/iter_not_returning_iterator.rs | 2 +- .../clippy_lints/src/iter_without_into_iter.rs | 2 +- .../clippy/clippy_lints/src/large_const_arrays.rs | 4 +- src/tools/clippy/clippy_lints/src/large_futures.rs | 2 +- .../clippy/clippy_lints/src/large_stack_frames.rs | 4 +- .../clippy_lints/src/loops/explicit_iter_loop.rs | 12 +-- .../clippy_lints/src/methods/needless_collect.rs | 6 +- .../src/methods/unnecessary_min_or_max.rs | 2 +- .../src/methods/unnecessary_to_owned.rs | 2 +- .../clippy/clippy_lints/src/methods/zst_offset.rs | 2 +- .../src/needless_borrows_for_generic_args.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 18 ++-- .../src/operators/const_comparisons.rs | 2 +- .../clippy_lints/src/operators/erasing_op.rs | 2 +- .../clippy/clippy_lints/src/operators/float_cmp.rs | 3 +- .../clippy/clippy_lints/src/redundant_slicing.rs | 2 +- src/tools/clippy/clippy_lints/src/returns.rs | 2 +- .../src/significant_drop_tightening.rs | 2 +- .../clippy_lints/src/trailing_empty_array.rs | 2 +- .../clippy_lints/src/transmute/eager_transmute.rs | 4 +- .../src/transmute/transmute_undefined_repr.rs | 6 +- .../clippy/clippy_lints/src/transmute/utils.rs | 9 +- .../clippy_lints/src/uninhabited_references.rs | 4 +- src/tools/clippy/clippy_utils/src/consts.rs | 12 +-- src/tools/clippy/clippy_utils/src/eager_or_lazy.rs | 2 +- src/tools/clippy/clippy_utils/src/hir_utils.rs | 6 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- .../clippy_utils/src/qualify_min_const_fn.rs | 10 +- src/tools/clippy/clippy_utils/src/ty.rs | 17 +-- .../miri/src/borrow_tracker/stacked_borrows/mod.rs | 2 +- .../miri/src/borrow_tracker/tree_borrows/mod.rs | 2 +- src/tools/miri/src/eval.rs | 14 ++- src/tools/miri/src/helpers.rs | 4 +- src/tools/miri/src/machine.rs | 4 +- 240 files changed, 1739 insertions(+), 1340 deletions(-) (limited to 'compiler/rustc_pattern_analysis/src') diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 51c2282422e..2afd52964dc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -682,8 +682,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Normalize before comparing to see through type aliases and projections. let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args); let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args); - if let Ok(old_ty) = tcx.try_normalize_erasing_regions(self.param_env, old_ty) - && let Ok(new_ty) = tcx.try_normalize_erasing_regions(self.param_env, new_ty) + if let Ok(old_ty) = + tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), old_ty) + && let Ok(new_ty) = tcx.try_normalize_erasing_regions( + self.infcx.typing_env(self.param_env), + new_ty, + ) { old_ty == new_ty } else { @@ -3831,11 +3835,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if tcx.is_diagnostic_item(sym::deref_method, method_did) { let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { - Instance::try_resolve(tcx, self.param_env, deref_target, method_args) - .transpose() + Instance::try_resolve( + tcx, + self.infcx.typing_env(self.param_env), + deref_target, + method_args, + ) + .transpose() }); if let Some(Ok(instance)) = deref_target { - let deref_target_ty = instance.ty(tcx, self.param_env); + let deref_target_ty = instance.ty(tcx, self.infcx.typing_env(self.param_env)); err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`")); err.span_note(tcx.def_span(instance.def_id()), "deref defined here"); } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 0797bb49bf9..6c63da819c7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -864,7 +864,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let kind = call_kind( self.infcx.tcx, - self.param_env, + self.infcx.typing_env(self.param_env), method_did, method_args, *fn_span, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 807b5576976..d4660d8af43 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -952,7 +952,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let Ok(Some(instance)) = ty::Instance::try_resolve( tcx, - self.param_env, + self.infcx.typing_env(self.param_env), *fn_did, self.infcx.resolve_vars_if_possible(args), ) { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 0fe6a4b5fce..ac0219684d8 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1527,7 +1527,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // The signature in this call can reference region variables, // so erase them before calling a query. let output_ty = self.tcx().erase_regions(sig.output()); - if !output_ty.is_privately_uninhabited(self.tcx(), self.param_env) { + if !output_ty + .is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.param_env)) + { span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); } } diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index f647ee36c48..7dd2139cf90 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -376,7 +376,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() { let instance = ty::Instance::expect_resolve( fx.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), def_id, fn_args, source_info.span, diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index da3818ca25e..1b91d251bfd 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -666,7 +666,7 @@ fn codegen_stmt<'tcx>( let func_ref = fx.get_function_ref( Instance::resolve_for_fn_ptr( fx.tcx, - ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), def_id, args, ) @@ -841,14 +841,18 @@ fn codegen_stmt<'tcx>( lval.write_cvalue(fx, CValue::by_val(operand, box_layout)); } Rvalue::NullaryOp(ref null_op, ty) => { - assert!(lval.layout().ty.is_sized(fx.tcx, ParamEnv::reveal_all())); + assert!(lval.layout().ty.is_sized(fx.tcx, ty::ParamEnv::reveal_all())); let layout = fx.layout_of(fx.monomorphize(ty)); let val = match null_op { NullOp::SizeOf => layout.size.bytes(), NullOp::AlignOf => layout.align.abi.bytes(), NullOp::OffsetOf(fields) => fx .tcx - .offset_of_subfield(ParamEnv::reveal_all(), layout, fields.iter()) + .offset_of_subfield( + ty::TypingEnv::fully_monomorphized(), + layout, + fields.iter(), + ) .bytes(), NullOp::UbChecks => { let val = fx.tcx.sess.ub_checks(); diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 27e71b92561..add081bc795 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -103,11 +103,11 @@ fn clif_pair_type_from_ty<'tcx>( /// Is a pointer to this type a wide ptr? pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { - if ty.is_sized(tcx, ParamEnv::reveal_all()) { + if ty.is_sized(tcx, ty::ParamEnv::reveal_all()) { return false; } - let tail = tcx.struct_tail_for_codegen(ty, ParamEnv::reveal_all()); + let tail = tcx.struct_tail_for_codegen(ty, ty::TypingEnv::fully_monomorphized()); match tail.kind() { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, @@ -339,9 +339,9 @@ impl<'tcx> rustc_abi::HasDataLayout for FunctionCx<'_, '_, 'tcx> { } } -impl<'tcx> layout::HasParamEnv<'tcx> for FunctionCx<'_, '_, 'tcx> { - fn param_env(&self) -> ParamEnv<'tcx> { - ParamEnv::reveal_all() +impl<'tcx> layout::HasTypingEnv<'tcx> for FunctionCx<'_, '_, 'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv::fully_monomorphized() } } @@ -358,7 +358,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { { self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(value), ) } @@ -497,9 +497,9 @@ impl<'tcx> rustc_abi::HasDataLayout for RevealAllLayoutCx<'tcx> { } } -impl<'tcx> layout::HasParamEnv<'tcx> for RevealAllLayoutCx<'tcx> { - fn param_env(&self) -> ParamEnv<'tcx> { - ParamEnv::reveal_all() +impl<'tcx> layout::HasTypingEnv<'tcx> for RevealAllLayoutCx<'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv::fully_monomorphized() } } diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index ab78584332a..5311547309c 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -78,7 +78,7 @@ pub(crate) fn eval_mir_constant<'tcx>( let cv = fx.monomorphize(constant.const_); // This cannot fail because we checked all required_consts in advance. let val = cv - .eval(fx.tcx, ty::ParamEnv::reveal_all(), constant.span) + .eval(fx.tcx, ty::TypingEnv::fully_monomorphized(), constant.span) .expect("erroneous constant missed by mono item collection"); (val, cv.ty()) } @@ -265,8 +265,13 @@ fn data_id_for_static( assert!(!definition); assert!(!tcx.is_mutable_static(def_id)); - let ty = instance.ty(tcx, ParamEnv::reveal_all()); - let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes(); + let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); + let align = tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .unwrap() + .align + .pref + .bytes(); let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak || import_linkage == rustc_middle::mir::mono::Linkage::WeakAny diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 9025ea97b81..f3a8623e216 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -210,7 +210,7 @@ impl DebugContext { type_names::push_generic_params( tcx, - tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args), + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args), &mut name, ); @@ -275,8 +275,10 @@ impl DebugContext { let span = tcx.def_span(def_id); let (file_id, line, _column) = self.get_span_loc(tcx, span, span); - let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::ParamEnv::reveal_all()); - let static_layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(static_type)).unwrap(); + let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::TypingEnv::fully_monomorphized()); + let static_layout = tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(static_type)) + .unwrap(); // FIXME use the actual type layout let type_id = self.debug_type(tcx, type_dbg, static_type); diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index a3f816f70a9..0df1a30fc0a 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -92,7 +92,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( if let ty::FnDef(def_id, args) = *const_.ty().kind() { let instance = ty::Instance::resolve_for_fn_ptr( fx.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), def_id, args, ) @@ -227,11 +227,11 @@ pub(crate) fn codegen_naked_asm<'tcx>( InlineAsmOperand::Const { ref value } => { let cv = instance.instantiate_mir_and_normalize_erasing_regions( tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(value.const_), ); let const_value = cv - .eval(tcx, ty::ParamEnv::reveal_all(), value.span) + .eval(tcx, ty::TypingEnv::fully_monomorphized(), value.span) .expect("erroneous constant missed by mono item collection"); let value = rustc_codegen_ssa::common::asm_const_to_str( @@ -250,13 +250,13 @@ pub(crate) fn codegen_naked_asm<'tcx>( let const_ = instance.instantiate_mir_and_normalize_erasing_regions( tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(value.const_), ); if let ty::FnDef(def_id, args) = *const_.ty().kind() { let instance = ty::Instance::resolve_for_fn_ptr( tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), def_id, args, ) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index b92885cc1a7..1afe252ff04 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -20,7 +20,7 @@ mod simd; use cranelift_codegen::ir::AtomicRmwOp; use rustc_middle::ty; use rustc_middle::ty::GenericArgsRef; -use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement}; +use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{Symbol, sym}; @@ -682,7 +682,10 @@ fn codegen_regular_intrinsic_call<'tcx>( if let Some(requirement) = requirement { let do_panic = !fx .tcx - .check_validity_requirement((requirement, fx.param_env().and(ty))) + .check_validity_requirement(( + requirement, + ty::TypingEnv::fully_monomorphized().as_query_input(ty), + )) .expect("expect to have layout during codegen"); if do_panic { @@ -741,7 +744,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let const_val = fx .tcx - .const_eval_instance(ParamEnv::reveal_all(), instance, source_info.span) + .const_eval_instance(ty::ParamEnv::reveal_all(), instance, source_info.span) .unwrap(); let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty); ret.write_cvalue(fx, val); diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index b506b1f5731..e6f6ae30581 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -98,7 +98,7 @@ mod prelude { pub(crate) use rustc_middle::mir::{self, *}; pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ - self, FloatTy, Instance, InstanceKind, IntTy, ParamEnv, Ty, TyCtxt, UintTy, + self, FloatTy, Instance, InstanceKind, IntTy, Ty, TyCtxt, UintTy, }; pub(crate) use rustc_span::Span; diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index df92bc58bf5..2ee4ff5cec7 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -49,7 +49,7 @@ pub(crate) fn maybe_create_entry_wrapper( // regions must appear in the argument // listing. let main_ret_ty = tcx.normalize_erasing_regions( - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), main_ret_ty.no_bound_vars().unwrap(), ); @@ -113,7 +113,7 @@ pub(crate) fn maybe_create_entry_wrapper( .unwrap(); let report = Instance::expect_resolve( tcx, - ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), report.def_id, tcx.mk_args(&[GenericArg::from(main_ret_ty)]), DUMMY_SP, @@ -139,7 +139,7 @@ pub(crate) fn maybe_create_entry_wrapper( let start_def_id = tcx.require_lang_item(LangItem::Start, None); let start_instance = Instance::expect_resolve( tcx, - ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), start_def_id, tcx.mk_args(&[main_ret_ty.into()]), DUMMY_SP, diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index 336934354e1..2843e5bbdfb 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -3,6 +3,7 @@ //! [`PointerCoercion::Unsize`]: `rustc_middle::ty::adjustment::PointerCoercion::Unsize` use rustc_codegen_ssa::base::validate_trivial_unsize; +use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use crate::base::codegen_panic_nounwind; @@ -23,7 +24,7 @@ pub(crate) fn unsized_info<'tcx>( old_info: Option, ) -> Value { let (source, target) = - fx.tcx.struct_lockstep_tails_for_codegen(source, target, ParamEnv::reveal_all()); + fx.tcx.struct_lockstep_tails_for_codegen(source, target, fx.typing_env()); match (&source.kind(), &target.kind()) { (&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst( fx.pointer_type, diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 900d7e69714..6676e684ca0 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -4,6 +4,7 @@ use cranelift_codegen::entity::EntityRef; use cranelift_codegen::ir::immediates::Offset32; use cranelift_frontend::Variable; use rustc_middle::ty::FnSig; +use rustc_middle::ty::layout::HasTypingEnv; use crate::prelude::*; @@ -884,19 +885,17 @@ pub(crate) fn assert_assignable<'tcx>( assert_assignable(fx, *a, *b, limit - 1); } (ty::FnPtr(..), ty::FnPtr(..)) => { - let from_sig = fx.tcx.normalize_erasing_late_bound_regions( - ParamEnv::reveal_all(), - from_ty.fn_sig(fx.tcx), - ); + let from_sig = fx + .tcx + .normalize_erasing_late_bound_regions(fx.typing_env(), from_ty.fn_sig(fx.tcx)); let FnSig { inputs_and_output: types_from, c_variadic: c_variadic_from, safety: unsafety_from, abi: abi_from, } = from_sig; - let to_sig = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_ty.fn_sig(fx.tcx)); + let to_sig = + fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to_ty.fn_sig(fx.tcx)); let FnSig { inputs_and_output: types_to, c_variadic: c_variadic_to, @@ -932,9 +931,8 @@ pub(crate) fn assert_assignable<'tcx>( (&ty::Dynamic(from_traits, _, _from_kind), &ty::Dynamic(to_traits, _, _to_kind)) => { // FIXME(dyn-star): Do the right thing with DynKinds for (from, to) in from_traits.iter().zip(to_traits) { - let from = - fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from); - let to = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to); + let from = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), from); + let to = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to); assert_eq!( from, to, "Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}", diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index e6ae7cf174d..9a142326ad1 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -24,9 +24,9 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{ - FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, + FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers, }; -use rustc_middle::ty::{Instance, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_span::Span; use rustc_span::def_id::DefId; use rustc_target::abi::call::FnAbi; @@ -2319,9 +2319,9 @@ impl<'a, 'gcc, 'tcx> StaticBuilderMethods for Builder<'a, 'gcc, 'tcx> { } } -impl<'tcx> HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> { - fn param_env(&self) -> ParamEnv<'tcx> { - self.cx.param_env() +impl<'tcx> HasTypingEnv<'tcx> for Builder<'_, '_, 'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.cx.typing_env() } } diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 07c7a54de1c..6dc2f4ed668 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -215,7 +215,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let gcc_type = if nested { self.type_i8() } else { - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + let ty = instance.ty(self.tcx, ty::TypingEnv::fully_monomorphized()); self.layout_of(ty).gcc_type(self) }; diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 707b35967a6..3846d025537 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -11,10 +11,10 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::span_bug; use rustc_middle::ty::layout::{ - FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, + FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers, }; -use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_session::Session; use rustc_span::source_map::respan; use rustc_span::{DUMMY_SP, Span}; @@ -144,7 +144,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { supports_f128_type: bool, ) -> Self { let create_type = |ctype, rust_type| { - let layout = tcx.layout_of(ParamEnv::reveal_all().and(rust_type)).unwrap(); + let layout = tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type)) + .unwrap(); let align = layout.align.abi.bytes(); #[cfg(feature = "master")] { @@ -459,7 +461,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { Some(def_id) if !wants_msvc_seh(self.sess()) => { let instance = ty::Instance::expect_resolve( tcx, - ty::ParamEnv::reveal_all(), + self.typing_env(), def_id, ty::List::empty(), DUMMY_SP, @@ -583,9 +585,9 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { } } -impl<'tcx, 'gcc> HasParamEnv<'tcx> for CodegenCx<'gcc, 'tcx> { - fn param_env(&self) -> ParamEnv<'tcx> { - ParamEnv::reveal_all() +impl<'tcx, 'gcc> HasTypingEnv<'tcx> for CodegenCx<'gcc, 'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv::fully_monomorphized() } } diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs index 5ca440f4c9b..02b760dc733 100644 --- a/compiler/rustc_codegen_gcc/src/int.rs +++ b/compiler/rustc_codegen_gcc/src/int.rs @@ -5,7 +5,7 @@ use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp}; -use rustc_middle::ty::{ParamEnv, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_target::abi::Endian; use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode}; use rustc_target::spec; @@ -380,7 +380,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let overflow_field = self.context.new_field(self.location, self.bool_type, "overflow"); let ret_ty = Ty::new_tup(self.tcx, &[self.tcx.types.i128, self.tcx.types.bool]); - let layout = self.tcx.layout_of(ParamEnv::reveal_all().and(ret_ty)).unwrap(); + let layout = self + .tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ret_ty)) + .unwrap(); let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) }; let mut fn_abi = FnAbi { diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 225f294e1e4..69326f409bb 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -21,7 +21,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, MiscCodegenMethods}; use rustc_middle::bug; use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] -use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; +use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv}; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; use rustc_target::abi::HasDataLayout; @@ -107,7 +107,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc span: Span, ) -> Result<(), Instance<'tcx>> { let tcx = self.tcx; - let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); + let callee_ty = instance.ty(tcx, self.typing_env()); let (def_id, fn_args) = match *callee_ty.kind() { ty::FnDef(def_id, fn_args) => (def_id, fn_args), @@ -115,7 +115,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc }; let sig = callee_ty.fn_sig(tcx); - let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig); + let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig); let arg_tys = sig.inputs(); let ret_ty = sig.output(); let name = tcx.item_name(def_id); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 43dbfafa871..604678a9af4 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -55,8 +55,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } let tcx = bx.tcx(); - let sig = - tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx)); + let sig = tcx.normalize_erasing_late_bound_regions( + ty::TypingEnv::fully_monomorphized(), + callee_ty.fn_sig(tcx), + ); let arg_tys = sig.inputs(); if name == sym::simd_select_bitmask { @@ -478,7 +480,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match *in_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) }); require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer { span, @@ -493,7 +495,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match *out_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) }); require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer { span, diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs index b7b282bf2a6..239902df7f0 100644 --- a/compiler/rustc_codegen_gcc/src/mono_item.rs +++ b/compiler/rustc_codegen_gcc/src/mono_item.rs @@ -6,7 +6,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{Linkage, Visibility}; -use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; +use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use crate::context::CodegenCx; @@ -27,11 +27,8 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out // the gcc type from the actual evaluated initializer. - let ty = if nested { - self.tcx.types.unit - } else { - instance.ty(self.tcx, ty::ParamEnv::reveal_all()) - }; + let ty = + if nested { self.tcx.types.unit } else { instance.ty(self.tcx, self.typing_env()) }; let gcc_type = self.layout_of(ty).gcc_type(self); let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index ac76b781218..b5bb7630ca6 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -14,7 +14,7 @@ use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{ - FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers, + FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers, TyAndLayout, }; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; @@ -81,9 +81,9 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> { } } -impl<'tcx> ty::layout::HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> { - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.cx.param_env() +impl<'tcx> ty::layout::HasTypingEnv<'tcx> for Builder<'_, '_, 'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.cx.typing_env() } } @@ -472,7 +472,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { #[instrument(level = "trace", skip(self))] fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> { if place.layout.is_unsized() { - let tail = self.tcx.struct_tail_for_codegen(place.layout.ty, self.param_env()); + let tail = self.tcx.struct_tail_for_codegen(place.layout.ty, self.typing_env()); if matches!(tail.kind(), ty::Foreign(..)) { // Unsized locals and, at least conceptually, even unsized arguments must be copied // around, which requires dynamically determining their size. Therefore, we cannot diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index dcea9d3b391..e0a2de3366c 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -5,7 +5,7 @@ //! closure. use rustc_codegen_ssa::common; -use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; +use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use tracing::debug; @@ -28,12 +28,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t } let sym = tcx.symbol_name(instance).name; - debug!( - "get_fn({:?}: {:?}) => {}", - instance, - instance.ty(cx.tcx(), ty::ParamEnv::reveal_all()), - sym - ); + debug!("get_fn({:?}: {:?}) => {}", instance, instance.ty(cx.tcx(), cx.typing_env()), sym); let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty()); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 7ab4f45cd73..6f5ffbb4b34 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -13,8 +13,8 @@ use rustc_middle::mir::interpret::{ read_target_uint, }; use rustc_middle::mir::mono::MonoItem; -use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, Instance}; +use rustc_middle::ty::Instance; +use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::{bug, span_bug}; use rustc_session::config::Lto; use tracing::{debug, instrument, trace}; @@ -244,7 +244,7 @@ impl<'ll> CodegenCx<'ll, '_> { let llty = if nested { self.type_i8() } else { - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + let ty = instance.ty(self.tcx, self.typing_env()); trace!(?ty); self.layout_of(ty).llvm_type(self) }; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 3a7c7efe03b..841c110b3c8 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -15,7 +15,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry; use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::ty::layout::{ - FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers, + FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers, }; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; @@ -658,7 +658,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let llfn = match tcx.lang_items().eh_personality() { Some(def_id) if name.is_none() => self.get_fn_addr(ty::Instance::expect_resolve( tcx, - ty::ParamEnv::reveal_all(), + self.typing_env(), def_id, ty::List::empty(), DUMMY_SP, @@ -1162,9 +1162,9 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for CodegenCx<'_, 'tcx> { } } -impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> { - fn param_env(&self) -> ty::ParamEnv<'tcx> { - ty::ParamEnv::reveal_all() +impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv::fully_monomorphized() } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 0f1909486ec..4a68bdea85e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_index::Idx; use rustc_index::bit_set::BitSet; use rustc_middle::mir::{Body, SourceScope}; -use rustc_middle::ty::layout::FnAbiOf; +use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv}; use rustc_middle::ty::{self, Instance}; use rustc_session::config::DebugInfo; use rustc_span::BytePos; @@ -118,7 +118,7 @@ fn make_mir_scope<'ll, 'tcx>( // if this is moved to `rustc_codegen_ssa::mir::debuginfo`. let callee = cx.tcx.instantiate_and_normalize_erasing_regions( instance.args, - ty::ParamEnv::reveal_all(), + cx.typing_env(), ty::EarlyBinder::bind(callee), ); debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 151923a3bd2..ef16e5bb459 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -11,10 +11,9 @@ use rustc_codegen_ssa::traits::*; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; -use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{ - self, AdtKind, CoroutineArgsExt, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, - Visibility, + self, AdtKind, CoroutineArgsExt, Instance, PolyExistentialTraitRef, Ty, TyCtxt, Visibility, }; use rustc_session::config::{self, DebugInfo, Lto}; use rustc_span::symbol::Symbol; @@ -301,9 +300,8 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( .insert(unique_type_id, recursion_marker_type_di_node(cx)); let fn_ty = unique_type_id.expect_ty(); - let signature = cx - .tcx - .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), fn_ty.fn_sig(cx.tcx)); + let signature = + cx.tcx.normalize_erasing_late_bound_regions(cx.typing_env(), fn_ty.fn_sig(cx.tcx)); let signature_di_nodes: SmallVec<_> = iter::once( // return type @@ -1109,9 +1107,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>( } }; - assert!( - up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)) - ); + assert!(up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(cx.typing_env(), t))); let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let layout = cx.layout_of(closure_or_coroutine_ty); @@ -1272,8 +1268,7 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>( let template_params: SmallVec<_> = iter::zip(args, names) .filter_map(|(kind, name)| { kind.as_type().map(|ty| { - let actual_type = - cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); + let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); let actual_type_di_node = type_di_node(cx, actual_type); let name = name.as_str(); unsafe { @@ -1341,7 +1336,7 @@ pub(crate) fn build_global_var_di_node<'ll>( if nested { return; } - let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all()); + let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, cx.typing_env()); let type_di_node = type_di_node(cx, variable_type); let var_name = tcx.item_name(def_id); let var_name = var_name.as_str(); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index 5120b63d173..4e461476040 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; use rustc_middle::bug; -use rustc_middle::ty::{ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt}; use super::{SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; use crate::common::{AsCCharPtr, CodegenCx}; @@ -49,12 +49,15 @@ pub(super) enum UniqueTypeId<'tcx> { impl<'tcx> UniqueTypeId<'tcx> { pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self { - assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)); + assert_eq!(t, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t)); UniqueTypeId::Ty(t, private::HiddenZst) } pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self { - assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty)); + assert_eq!( + enum_ty, + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) + ); UniqueTypeId::VariantPart(enum_ty, private::HiddenZst) } @@ -63,7 +66,10 @@ impl<'tcx> UniqueTypeId<'tcx> { enum_ty: Ty<'tcx>, variant_idx: VariantIdx, ) -> Self { - assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty)); + assert_eq!( + enum_ty, + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) + ); UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst) } @@ -72,7 +78,10 @@ impl<'tcx> UniqueTypeId<'tcx> { enum_ty: Ty<'tcx>, variant_idx: VariantIdx, ) -> Self { - assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty)); + assert_eq!( + enum_ty, + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) + ); UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst) } @@ -81,10 +90,13 @@ impl<'tcx> UniqueTypeId<'tcx> { self_type: Ty<'tcx>, implemented_trait: Option>, ) -> Self { - assert_eq!(self_type, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), self_type)); + assert_eq!( + self_type, + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), self_type) + ); assert_eq!( implemented_trait, - tcx.normalize_erasing_regions(ParamEnv::reveal_all(), implemented_trait) + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), implemented_trait) ); UniqueTypeId::VTableTy(self_type, implemented_trait, private::HiddenZst) } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 89492e4b9fe..4b650b00bee 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -15,8 +15,8 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_index::IndexVec; use rustc_middle::mir; -use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, GenericArgsRef, Instance, ParamEnv, Ty, TypeVisitableExt}; +use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; +use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt}; use rustc_session::Session; use rustc_session::config::{self, DebugInfo}; use rustc_span::symbol::Symbol; @@ -344,7 +344,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { type_names::push_generic_params( tcx, - tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args), + tcx.normalize_erasing_regions(self.typing_env(), args), &mut name, ); @@ -481,8 +481,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { iter::zip(args, names) .filter_map(|(kind, name)| { kind.as_type().map(|ty| { - let actual_type = - cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); + let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); let actual_type_metadata = type_di_node(cx, actual_type); let name = name.as_str(); unsafe { @@ -526,7 +525,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions( instance.args, - ty::ParamEnv::reveal_all(), + cx.typing_env(), cx.tcx.type_of(impl_def_id), ); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs index 960487ada16..6e841293477 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs @@ -1,7 +1,7 @@ // Utility Functions. use rustc_hir::def_id::DefId; -use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; +use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Ty}; use tracing::trace; @@ -62,7 +62,7 @@ pub(crate) fn wide_pointer_kind<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, pointee_ty: Ty<'tcx>, ) -> Option { - let pointee_tail_ty = cx.tcx.struct_tail_for_codegen(pointee_ty, cx.param_env()); + let pointee_tail_ty = cx.tcx.struct_tail_for_codegen(pointee_ty, cx.typing_env()); let layout = cx.layout_of(pointee_tail_ty); trace!( "wide_pointer_kind: {:?} has layout {:?} (is_unsized? {})", diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index b56f464975d..da7f94e8cf7 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -10,7 +10,7 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::*; use rustc_hir as hir; use rustc_middle::mir::BinOp; -use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf}; +use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; @@ -163,14 +163,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { span: Span, ) -> Result<(), ty::Instance<'tcx>> { let tcx = self.tcx; - let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); + let callee_ty = instance.ty(tcx, self.typing_env()); let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else { bug!("expected fn item type, found {}", callee_ty); }; let sig = callee_ty.fn_sig(tcx); - let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig); + let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig); let arg_tys = sig.inputs(); let ret_ty = sig.output(); let name = tcx.item_name(def_id); @@ -1152,8 +1152,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } let tcx = bx.tcx(); - let sig = - tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx)); + let sig = tcx.normalize_erasing_late_bound_regions(bx.typing_env(), callee_ty.fn_sig(tcx)); let arg_tys = sig.inputs(); // Sanity-check: all vector arguments must be immediates. @@ -2187,7 +2186,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( match in_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + bx.tcx.normalize_erasing_regions(bx.typing_env(), ty) }); require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer { span, @@ -2202,7 +2201,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( match out_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + bx.tcx.normalize_erasing_regions(bx.typing_env(), ty) }); require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer { span, diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index ea8857b4739..33789c6261f 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -3,7 +3,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; use rustc_middle::mir::mono::{Linkage, Visibility}; -use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; +use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_session::config::CrateType; use rustc_target::spec::RelocModel; @@ -26,11 +26,8 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure // out the llvm type from the actual evaluated initializer. - let ty = if nested { - self.tcx.types.unit - } else { - instance.ty(self.tcx, ty::ParamEnv::reveal_all()) - }; + let ty = + if nested { self.tcx.types.unit } else { instance.ty(self.tcx, self.typing_env()) }; let llty = self.layout_of(ty).llvm_type(self); let g = self.define_global(symbol_name, llty).unwrap_or_else(|| { diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 850d36872dd..d9152c5d080 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -595,8 +595,10 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>( let (conv, args) = instance .map(|i| { - tcx.fn_abi_of_instance(ty::ParamEnv::reveal_all().and((i, ty::List::empty()))) - .unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed")) + tcx.fn_abi_of_instance( + ty::TypingEnv::fully_monomorphized().as_query_input((i, ty::List::empty())), + ) + .unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed")) }) .map(|fnabi| (fnabi.conv, &fnabi.args[..])) .unwrap_or((Conv::Rust, &[])); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index ef95ab94062..c8b3b30218a 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -21,7 +21,7 @@ use rustc_middle::middle::{exported_symbols, lang_items}; use rustc_middle::mir::BinOp; use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem}; use rustc_middle::query::Providers; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypingMode}; use rustc_session::Session; use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType}; @@ -165,7 +165,7 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ) -> Bx::Value { let cx = bx.cx(); let (source, target) = - cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.param_env()); + cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.typing_env()); match (source.kind(), target.kind()) { (&ty::Array(_, len), &ty::Slice(_)) => cx.const_usize( len.try_to_target_usize(cx.tcx()).expect("expected monomorphic const in codegen"), @@ -466,10 +466,9 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // late-bound regions, since late-bound // regions must appear in the argument // listing. - let main_ret_ty = cx.tcx().normalize_erasing_regions( - ty::ParamEnv::reveal_all(), - main_ret_ty.no_bound_vars().unwrap(), - ); + let main_ret_ty = cx + .tcx() + .normalize_erasing_regions(cx.typing_env(), main_ret_ty.no_bound_vars().unwrap()); let Some(llfn) = cx.declare_c_main(llfty) else { // FIXME: We should be smart and show a better diagnostic here. @@ -495,7 +494,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None); let start_instance = ty::Instance::expect_resolve( cx.tcx(), - ty::ParamEnv::reveal_all(), + cx.typing_env(), start_def_id, cx.tcx().mk_args(&[main_ret_ty.into()]), DUMMY_SP, diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 27bc58516c0..6c4f6d37972 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -21,9 +21,7 @@ use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathD use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability}; use rustc_middle::bug; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; -use rustc_middle::ty::{ - self, ExistentialProjection, GenericArgKind, GenericArgsRef, ParamEnv, Ty, TyCtxt, -}; +use rustc_middle::ty::{self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt}; use smallvec::SmallVec; use crate::debuginfo::wants_c_like_enum_debuginfo; @@ -82,7 +80,7 @@ fn push_debuginfo_type_name<'tcx>( ty::Adt(def, args) => { // `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding. let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() { - match tcx.layout_of(ParamEnv::reveal_all().and(t)) { + match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(t)) { Ok(layout) => { if !wants_c_like_enum_debuginfo(tcx, layout) { Some(layout) @@ -248,8 +246,10 @@ fn push_debuginfo_type_name<'tcx>( }; if let Some(principal) = trait_data.principal() { - let principal = - tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal); + let principal = tcx.normalize_erasing_late_bound_regions( + ty::TypingEnv::fully_monomorphized(), + principal, + ); push_item_name(tcx, principal.def_id, qualified, output); let principal_has_generic_params = push_generic_params_internal(tcx, principal.args, output, visited); @@ -350,8 +350,10 @@ fn push_debuginfo_type_name<'tcx>( return; } - let sig = - tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), t.fn_sig(tcx)); + let sig = tcx.normalize_erasing_late_bound_regions( + ty::TypingEnv::fully_monomorphized(), + t.fn_sig(tcx), + ); if cpp_like_debuginfo { // Format as a C++ function pointer: return_type (*)(params...) @@ -415,7 +417,8 @@ fn push_debuginfo_type_name<'tcx>( // In the case of cpp-like debuginfo, the name additionally gets wrapped inside of // an artificial `enum2$<>` type, as defined in msvc_enum_fallback(). if cpp_like_debuginfo && t.is_coroutine() { - let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap(); + let ty_and_layout = + tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(t)).unwrap(); msvc_enum_fallback( tcx, ty_and_layout, @@ -529,8 +532,8 @@ pub fn compute_debuginfo_vtable_name<'tcx>( } if let Some(trait_ref) = trait_ref { - let trait_ref = - tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref); + let trait_ref = tcx + .normalize_erasing_late_bound_regions(ty::TypingEnv::fully_monomorphized(), trait_ref); push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name); visited.clear(); push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited); @@ -639,7 +642,7 @@ fn push_generic_params_internal<'tcx>( output: &mut String, visited: &mut FxHashSet>, ) -> bool { - assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args)); + assert_eq!(args, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args)); let mut args = args.non_erasable_generics().peekable(); if args.peek().is_none() { return false; @@ -678,14 +681,14 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S // FIXME: directly extract the bits from a valtree instead of evaluating an // already evaluated `Const` in order to get the bits. let bits = ct - .try_to_bits(tcx, ty::ParamEnv::reveal_all()) + .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected monomorphic const in codegen"); let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128; write!(output, "{val}") } ty::Uint(_) => { let val = ct - .try_to_bits(tcx, ty::ParamEnv::reveal_all()) + .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected monomorphic const in codegen"); write!(output, "{val}") } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 097d37bb70c..e3ed12b5ce6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -777,7 +777,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let do_panic = !bx .tcx() - .check_validity_requirement((requirement, bx.param_env().and(ty))) + .check_validity_requirement((requirement, bx.typing_env().as_query_input(ty))) .expect("expect to have layout during codegen"); let layout = bx.layout_of(ty); @@ -848,14 +848,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (instance, mut llfn) = match *callee.layout.ty.kind() { ty::FnDef(def_id, args) => ( Some( - ty::Instance::expect_resolve( - bx.tcx(), - ty::ParamEnv::reveal_all(), - def_id, - args, - fn_span, - ) - .polymorphize(bx.tcx()), + ty::Instance::expect_resolve(bx.tcx(), bx.typing_env(), def_id, args, fn_span) + .polymorphize(bx.tcx()), ), None, ), @@ -1191,7 +1185,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let ty::FnDef(def_id, args) = *const_.ty().kind() { let instance = ty::Instance::resolve_for_fn_ptr( bx.tcx(), - ty::ParamEnv::reveal_all(), + bx.typing_env(), def_id, args, ) diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 54b9c9cc89f..7676e1e171a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -1,6 +1,6 @@ use rustc_abi::BackendRepr; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::layout::HasTyCtxt; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv}; use rustc_middle::ty::{self, Ty}; use rustc_middle::{bug, mir, span_bug}; @@ -24,7 +24,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // `MirUsedCollector` visited all required_consts before codegen began, so if we got here // there can be no more constants that fail to evaluate. self.monomorphize(constant.const_) - .eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), constant.span) + .eval(self.cx.tcx(), self.cx.typing_env(), constant.span) .expect("erroneous constant missed by mono item collection") } @@ -57,7 +57,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { other => span_bug!(constant.span, "{other:#?}"), }; let uv = self.monomorphize(uv); - self.cx.tcx().const_eval_resolve_for_typeck(ty::ParamEnv::reveal_all(), uv, constant.span) + self.cx.tcx().const_eval_resolve_for_typeck(self.cx.typing_env(), uv, constant.span) } /// process constant containing SIMD shuffle indices & constant vectors diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 2a1b9e28c1e..c35d0b90706 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -59,14 +59,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llresult: Bx::Value, span: Span, ) -> Result<(), ty::Instance<'tcx>> { - let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all()); + let callee_ty = instance.ty(bx.tcx(), bx.typing_env()); let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else { bug!("expected fn item type, found {}", callee_ty); }; let sig = callee_ty.fn_sig(bx.tcx()); - let sig = bx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig); + let sig = bx.tcx().normalize_erasing_late_bound_regions(bx.typing_env(), sig); let arg_tys = sig.inputs(); let ret_ty = sig.output(); let name = bx.tcx().item_name(def_id); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index f19e3b72141..0cbc5c45736 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -4,7 +4,7 @@ use rustc_index::IndexVec; use rustc_index::bit_set::BitSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::{UnwindTerminateReason, traversal}; -use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout}; +use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_middle::{bug, mir, span_bug}; use rustc_target::callconv::{FnAbi, PassMode}; @@ -128,7 +128,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { debug!("monomorphize: self.instance={:?}", self.instance); self.instance.instantiate_mir_and_normalize_erasing_regions( self.cx.tcx(), - ty::ParamEnv::reveal_all(), + self.cx.typing_env(), ty::EarlyBinder::bind(value), ) } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 0e1cd662f91..f63b2d139c5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -474,7 +474,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ty::FnDef(def_id, args) => { let instance = ty::Instance::resolve_for_fn_ptr( bx.tcx(), - ty::ParamEnv::reveal_all(), + bx.typing_env(), def_id, args, ) @@ -709,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::NullOp::OffsetOf(fields) => { let val = bx .tcx() - .offset_of_subfield(bx.param_env(), layout, fields.iter()) + .offset_of_subfield(bx.typing_env(), layout, fields.iter()) .bytes(); bx.cx().const_usize(val) } @@ -727,7 +727,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::ThreadLocalRef(def_id) => { assert!(bx.cx().tcx().is_static(def_id)); - let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id)); + let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id, bx.typing_env())); let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id) { let instance = ty::Instance { diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 44ba2262149..3810c609fd4 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -1,6 +1,6 @@ use rustc_abi::{AddressSpace, Float, Integer}; use rustc_middle::bug; -use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout}; use rustc_middle::ty::{self, Ty}; use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi, Reg}; @@ -41,7 +41,7 @@ pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes { } pub trait DerivedTypeCodegenMethods<'tcx>: - BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx> { fn type_int(&self) -> Self::Type { match &self.sess().target.c_int_width[..] { @@ -74,7 +74,7 @@ pub trait DerivedTypeCodegenMethods<'tcx>: } fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { - ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all()) + ty.needs_drop(self.tcx(), self.typing_env()) } fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { @@ -86,12 +86,11 @@ pub trait DerivedTypeCodegenMethods<'tcx>: } fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { - let param_env = ty::ParamEnv::reveal_all(); - if ty.is_sized(self.tcx(), param_env) { + if ty.is_sized(self.tcx(), self.param_env()) { return false; } - let tail = self.tcx().struct_tail_for_codegen(ty, param_env); + let tail = self.tcx().struct_tail_for_codegen(ty, self.typing_env()); match tail.kind() { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, @@ -101,7 +100,10 @@ pub trait DerivedTypeCodegenMethods<'tcx>: } impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where - Self: BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + Self: BaseTypeCodegenMethods<'tcx> + + MiscCodegenMethods<'tcx> + + HasTyCtxt<'tcx> + + HasTypingEnv<'tcx> { } diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index ffe32acb316..50e8a168eeb 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -388,7 +388,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { return false; } - let infcx = tcx.infer_ctxt().build(self.body.typing_mode(tcx)); + let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx)); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let body_id = self.body.source.def_id().expect_local(); @@ -398,11 +398,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { ty::BoundConstness::Const } }; - let const_conditions = ocx.normalize( - &ObligationCause::misc(call_span, body_id), - self.param_env, - const_conditions, - ); + let const_conditions = + ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, const_conditions); ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| { Obligation::new( tcx, @@ -411,7 +408,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { body_id, ObligationCauseCode::WhereClause(callee, span), ), - self.param_env, + param_env, trait_ref.to_host_effect_clause(tcx, host_polarity), ) })); diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index ebdd55a4f70..80d3c6448aa 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -24,17 +24,15 @@ mod resolver; pub struct ConstCx<'mir, 'tcx> { pub body: &'mir mir::Body<'tcx>, pub tcx: TyCtxt<'tcx>, - pub param_env: ty::ParamEnv<'tcx>, + pub typing_env: ty::TypingEnv<'tcx>, pub const_kind: Option, } impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self { - let def_id = body.source.def_id().expect_local(); - let param_env = tcx.param_env(def_id); - + let typing_env = body.typing_env(tcx); let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local()); - ConstCx { body, tcx, param_env, const_kind } + ConstCx { body, tcx, typing_env, const_kind } } pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> { diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index ca95e42dd2b..8ba6b89aad4 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -120,7 +120,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { #[allow(rustc::untranslatable_diagnostic)] fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> { let FnCallNonConst { callee, args, span, call_source } = *self; - let ConstCx { tcx, param_env, .. } = *ccx; + let ConstCx { tcx, typing_env, .. } = *ccx; let caller = ccx.def_id(); let diag_trait = |err, self_ty: Ty<'_>, trait_id| { @@ -146,13 +146,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { } } ty::Adt(..) => { + let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); - - let infcx = tcx.infer_ctxt().build(ccx.body.typing_mode(tcx)); let mut selcx = SelectionContext::new(&infcx); let implsrc = selcx.select(&obligation); - if let Ok(Some(ImplSource::UserDefined(data))) = implsrc { // FIXME(const_trait_impl) revisit this if !tcx.is_const_trait_impl(data.impl_def_id) { @@ -166,7 +164,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { }; let call_kind = - call_kind(tcx, ccx.param_env, callee, args, span, call_source.from_hir_call(), None); + call_kind(tcx, ccx.typing_env, callee, args, span, call_source.from_hir_call(), None); debug!(?call_kind); diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index 0173a528c22..f6eb130fbd3 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -32,17 +32,15 @@ pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool { /// This is separate from the rest of the const checking logic because it must run after drop /// elaboration. pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) { - let def_id = body.source.def_id().expect_local(); - let const_kind = tcx.hir().body_const_context(def_id); - if const_kind.is_none() { + let ccx = ConstCx::new(tcx, body); + if ccx.const_kind.is_none() { return; } - if tcx.has_attr(def_id, sym::rustc_do_not_const_check) { + if tcx.has_attr(body.source.def_id(), sym::rustc_do_not_const_check) { return; } - let ccx = ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def_id) }; if !checking_enabled(&ccx) { return; } diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 29a08579175..bc416acc58d 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -106,20 +106,24 @@ impl Qualif for HasMutInterior { // Instead we invoke an obligation context manually, and provide the opaque type inference settings // that allow the trait solver to just error out instead of cycling. let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span)); - + // FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR + // typeck results without causing query cycles, we should use this here instead of defining + // opaque types. + let typing_env = ty::TypingEnv { + typing_mode: ty::TypingMode::analysis_in_body( + cx.tcx, + cx.body.source.def_id().expect_local(), + ), + param_env: cx.typing_env.param_env, + }; + let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(typing_env); + let ocx = ObligationCtxt::new(&infcx); let obligation = Obligation::new( cx.tcx, ObligationCause::dummy_with_span(cx.body.span), - cx.param_env, + param_env, ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]), ); - - // FIXME(#132279): This should eventually use the already defined hidden types. - let infcx = cx.tcx.infer_ctxt().build(ty::TypingMode::analysis_in_body( - cx.tcx, - cx.body.source.def_id().expect_local(), - )); - let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(obligation); let errors = ocx.select_all_or_error(); !errors.is_empty() @@ -156,7 +160,7 @@ impl Qualif for NeedsDrop { } fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.needs_drop(cx.tcx, cx.param_env) + ty.needs_drop(cx.tcx, cx.typing_env) } fn in_adt_inherently<'tcx>( diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs index 74eb6b37fbb..03624a2ce50 100644 --- a/compiler/rustc_const_eval/src/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs @@ -120,7 +120,10 @@ where /// /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134 fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool { - !place.ty(self.ccx.body, self.ccx.tcx).ty.is_freeze(self.ccx.tcx, self.ccx.param_env) + !place + .ty(self.ccx.body, self.ccx.tcx) + .ty + .is_freeze(self.ccx.tcx, self.ccx.typing_env.param_env) } } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index a430d9dc797..ca3ee6773a0 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -221,7 +221,7 @@ pub(super) fn op_to_const<'tcx>( let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); // `false` = no raw ptrs debug_assert!( matches!( - ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.param_env).kind(), + ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env()).kind(), ty::Str | ty::Slice(..), ), "`ConstValue::Slice` is for slice-tailed types only, but got {}", @@ -280,11 +280,13 @@ pub fn eval_to_const_value_raw_provider<'tcx>( // opaque types. This is needed for trivial things like `size_of`, but also for using associated // types that are not specified in the opaque type. assert_eq!(key.param_env.reveal(), Reveal::All); + let typing_env = + ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: key.param_env }; // We call `const_eval` for zero arg intrinsics, too, in order to cache their value. // Catch such calls and evaluate them instead of trying to load a constant's MIR. if let ty::InstanceKind::Intrinsic(def_id) = key.value.instance.def { - let ty = key.value.instance.ty(tcx, key.param_env); + let ty = key.value.instance.ty(tcx, typing_env); let ty::FnDef(_, args) = ty.kind() else { bug!("intrinsic with type {:?}", ty); }; diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index f12320cb851..19c3195aaa4 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -249,9 +249,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { } else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) { // For panic_fmt, call const_panic_fmt instead. let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None); + // FIXME(@lcnr): why does this use an empty env if we've got a `param_env` right here. let new_instance = ty::Instance::expect_resolve( *self.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), const_def_id, instance.args, self.cur_span(), diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index ea88b2ed22e..64bedea3b3f 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -2,6 +2,7 @@ use rustc_abi::{BackendRepr, VariantIdx}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; +use rustc_middle::ty::solve::Reveal; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_span::DUMMY_SP; @@ -281,8 +282,9 @@ pub fn valtree_to_const_value<'tcx>( // the `ValTree` and using `place_projection` and `place_field` to // create inner `MPlace`s which are filled recursively. // FIXME Does this need an example? - let (param_env, ty) = param_env_ty.into_parts(); + debug_assert_eq!(param_env.reveal(), Reveal::All); + let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env }; match *ty.kind() { ty::FnDef(..) => { @@ -302,11 +304,12 @@ pub fn valtree_to_const_value<'tcx>( let mut ecx = mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No); let imm = valtree_to_ref(&mut ecx, valtree, inner_ty); - let imm = ImmTy::from_immediate(imm, tcx.layout_of(param_env_ty).unwrap()); + let imm = + ImmTy::from_immediate(imm, tcx.layout_of(typing_env.as_query_input(ty)).unwrap()); op_to_const(&ecx, &imm.into(), /* for diagnostics */ false) } ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => { - let layout = tcx.layout_of(param_env_ty).unwrap(); + let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap(); if layout.is_zst() { // Fast path to avoid some allocations. return mir::ConstValue::ZeroSized; @@ -319,7 +322,7 @@ pub fn valtree_to_const_value<'tcx>( let branches = valtree.unwrap_branch(); // Find the non-ZST field. (There can be aligned ZST!) for (i, &inner_valtree) in branches.iter().enumerate() { - let field = layout.field(&LayoutCx::new(tcx, param_env), i); + let field = layout.field(&LayoutCx::new(tcx, typing_env), i); if !field.is_zst() { return valtree_to_const_value(tcx, param_env.and(field.ty), inner_valtree); } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index ef0902e4226..6cfe4b21907 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -215,7 +215,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Even if `ty` is normalized, the search for the unsized tail will project // to fields, which can yield non-normalized types. So we need to provide a // normalization function. - let normalize = |ty| self.tcx.normalize_erasing_regions(self.param_env, ty); + let normalize = |ty| self.tcx.normalize_erasing_regions(self.typing_env(), ty); ty.ptr_metadata_ty(*self.tcx, normalize) }; return interp_ok(meta_ty(caller) == meta_ty(callee)); @@ -652,35 +652,35 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; // Obtain the underlying trait we are working on, and the adjusted receiver argument. - let (trait_, dyn_ty, adjusted_recv) = if let ty::Dynamic(data, _, ty::DynStar) = - receiver_place.layout.ty.kind() - { - let recv = self.unpack_dyn_star(&receiver_place, data)?; + let (trait_, dyn_ty, adjusted_recv) = + if let ty::Dynamic(data, _, ty::DynStar) = receiver_place.layout.ty.kind() { + let recv = self.unpack_dyn_star(&receiver_place, data)?; - (data.principal(), recv.layout.ty, recv.ptr()) - } else { - // Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`. - // (For that reason we also cannot use `unpack_dyn_trait`.) - let receiver_tail = - self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.param_env); - let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else { - span_bug!( - self.cur_span(), - "dynamic call on non-`dyn` type {}", - receiver_tail - ) + (data.principal(), recv.layout.ty, recv.ptr()) + } else { + // Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`. + // (For that reason we also cannot use `unpack_dyn_trait`.) + let receiver_tail = self + .tcx + .struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env()); + let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else { + span_bug!( + self.cur_span(), + "dynamic call on non-`dyn` type {}", + receiver_tail + ) + }; + assert!(receiver_place.layout.is_unsized()); + + // Get the required information from the vtable. + let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?; + let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?; + + // It might be surprising that we use a pointer as the receiver even if this + // is a by-val case; this works because by-val passing of an unsized `dyn + // Trait` to a function is actually desugared to a pointer. + (receiver_trait.principal(), dyn_ty, receiver_place.ptr()) }; - assert!(receiver_place.layout.is_unsized()); - - // Get the required information from the vtable. - let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?; - let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?; - - // It might be surprising that we use a pointer as the receiver even if this - // is a by-val case; this works because by-val passing of an unsized `dyn - // Trait` to a function is actually desugared to a pointer. - (receiver_trait.principal(), dyn_ty, receiver_place.ptr()) - }; // Now determine the actual method to call. Usually we use the easy way of just // looking up the method at index `idx`. @@ -704,7 +704,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let concrete_method = Instance::expect_resolve_for_vtable( tcx, - self.param_env, + self.typing_env(), def_id, instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args), self.cur_span(), diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 49559059265..2d1bb5c9551 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -83,7 +83,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ty::FnDef(def_id, args) => { let instance = ty::Instance::resolve_for_fn_ptr( *self.tcx, - self.param_env, + self.typing_env(), def_id, args, ) @@ -384,7 +384,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) -> InterpResult<'tcx> { // A -> A conversion let (src_pointee_ty, dest_pointee_ty) = - self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.param_env); + self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.typing_env()); match (src_pointee_ty.kind(), dest_pointee_ty.kind()) { (&ty::Array(_, length), &ty::Slice(_)) => { diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index ff6d5b28b3b..70a696e3e3e 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -10,9 +10,7 @@ use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout, }; -use rustc_middle::ty::{ - self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypingMode, Variance, -}; +use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance}; use rustc_middle::{mir, span_bug}; use rustc_session::Limit; use rustc_span::Span; @@ -65,12 +63,12 @@ where } } -impl<'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'tcx, M> +impl<'tcx, M> layout::HasTypingEnv<'tcx> for InterpCx<'tcx, M> where M: Machine<'tcx>, { - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.typing_env() } } @@ -116,8 +114,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> { /// This test should be symmetric, as it is primarily about layout compatibility. pub(super) fn mir_assign_valid_types<'tcx>( tcx: TyCtxt<'tcx>, - typing_mode: TypingMode<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, src: TyAndLayout<'tcx>, dest: TyAndLayout<'tcx>, ) -> bool { @@ -125,7 +122,7 @@ pub(super) fn mir_assign_valid_types<'tcx>( // all normal lifetimes are erased, higher-ranked types with their // late-bound lifetimes are still around and can lead to type // differences. - if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) { + if util::relate_types(tcx, typing_env, Variance::Covariant, src.ty, dest.ty) { // Make sure the layout is equal, too -- just to be safe. Miri really // needs layout equality. For performance reason we skip this check when // the types are equal. Equal types *can* have different layouts when @@ -145,8 +142,7 @@ pub(super) fn mir_assign_valid_types<'tcx>( #[cfg_attr(not(debug_assertions), inline(always))] pub(super) fn from_known_layout<'tcx>( tcx: TyCtxtAt<'tcx>, - typing_mode: TypingMode<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, known_layout: Option>, compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>, ) -> InterpResult<'tcx, TyAndLayout<'tcx>> { @@ -155,13 +151,7 @@ pub(super) fn from_known_layout<'tcx>( Some(known_layout) => { if cfg!(debug_assertions) { let check_layout = compute()?; - if !mir_assign_valid_types( - tcx.tcx, - typing_mode, - param_env, - check_layout, - known_layout, - ) { + if !mir_assign_valid_types(tcx.tcx, typing_env, check_layout, known_layout) { span_bug!( tcx.span, "expected type differs from actual type.\nexpected: {}\nactual: {}", @@ -211,9 +201,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - pub fn typing_mode(&self) -> TypingMode<'tcx> { + /// During CTFE we're always in `PostAnalysis` mode. + #[inline(always)] + pub fn typing_env(&self) -> ty::TypingEnv<'tcx> { debug_assert_eq!(self.param_env.reveal(), Reveal::All); - TypingMode::PostAnalysis + ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env } } /// Returns the span of the currently executed statement/terminator. @@ -304,13 +296,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .instance .try_instantiate_mir_and_normalize_erasing_regions( *self.tcx, - self.param_env, + self.typing_env(), ty::EarlyBinder::bind(value), ) .map_err(|_| ErrorHandled::TooGeneric(self.cur_span())) } - /// The `args` are assumed to already be in our interpreter "universe" (param_env). + /// The `args` are assumed to already be in our interpreter "universe". pub(super) fn resolve( &self, def: DefId, @@ -319,7 +311,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { trace!("resolve: {:?}, {:#?}", def, args); trace!("param_env: {:#?}", self.param_env); trace!("args: {:#?}", args); - match ty::Instance::try_resolve(*self.tcx, self.param_env, def, args) { + match ty::Instance::try_resolve(*self.tcx, self.typing_env(), def, args) { Ok(Some(instance)) => interp_ok(instance), Ok(None) => throw_inval!(TooGeneric), @@ -328,7 +320,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - /// Check if the two things are equal in the current param_env, using an infctx to get proper + /// Check if the two things are equal in the current param_env, using an infcx to get proper /// equality checks. #[instrument(level = "trace", skip(self), ret)] pub(super) fn eq_in_param_env(&self, a: T, b: T) -> bool @@ -340,14 +332,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return true; } // Slow path: spin up an inference context to check if these traits are sufficiently equal. - let infcx = self.tcx.infer_ctxt().build(self.typing_mode()); + let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env()); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy_with_span(self.cur_span()); // equate the two trait refs after normalization - let a = ocx.normalize(&cause, self.param_env, a); - let b = ocx.normalize(&cause, self.param_env, b); + let a = ocx.normalize(&cause, param_env, a); + let b = ocx.normalize(&cause, param_env, b); - if let Err(terr) = ocx.eq(&cause, self.param_env, a, b) { + if let Err(terr) = ocx.eq(&cause, param_env, a, b) { trace!(?terr); return false; } @@ -572,7 +564,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let val = if self.tcx.is_static(gid.instance.def_id()) { let alloc_id = self.tcx.reserve_and_set_static_alloc(gid.instance.def_id()); - let ty = instance.ty(self.tcx.tcx, self.param_env); + let ty = instance.ty(self.tcx.tcx, self.typing_env()); mir::ConstAlloc { alloc_id, ty } } else { self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(self.param_env.and(gid)))? @@ -587,7 +579,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| { - let const_val = val.eval(*ecx.tcx, ecx.param_env, span).map_err(|err| { + let const_val = val.eval(*ecx.tcx, ecx.typing_env(), span).map_err(|err| { if M::ALL_CONSTS_ARE_PRECHECKED { match err { ErrorHandled::TooGeneric(..) => {}, diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index d89d73824aa..fc6a1c4bbc5 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -40,6 +40,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( ) -> InterpResult<'tcx, ConstValue<'tcx>> { let tp_ty = args.type_at(0); let name = tcx.item_name(def_id); + let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env }; interp_ok(match name { sym::type_name => { ensure_monomorphic_enough(tcx, tp_ty)?; @@ -48,11 +49,13 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( } sym::needs_drop => { ensure_monomorphic_enough(tcx, tp_ty)?; - ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)) + ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env)) } sym::pref_align_of => { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. - let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(*e)))?; + let layout = tcx + .layout_of(typing_env.as_query_input(tp_ty)) + .map_err(|e| err_inval!(Layout(*e)))?; ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx) } sym::type_id => { @@ -355,7 +358,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let should_panic = !self .tcx - .check_validity_requirement((requirement, self.param_env.and(ty))) + .check_validity_requirement((requirement, self.typing_env().as_query_input(ty))) .map_err(|_| err_inval!(TooGeneric))?; if should_panic { diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 09635c96e57..07566e9fda2 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -859,7 +859,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // # Global allocations if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) { - let (size, align) = global_alloc.size_and_align(*self.tcx, self.param_env); + let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env()); let mutbl = global_alloc.mutability(*self.tcx, self.param_env); let kind = match global_alloc { GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData, diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index a130ae89bcb..0157e6c2125 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -8,7 +8,7 @@ use rustc_abi as abi; use rustc_abi::{BackendRepr, HasDataLayout, Size}; use rustc_hir::def::Namespace; use rustc_middle::mir::interpret::ScalarSizeMismatch; -use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, mir, span_bug, ty}; @@ -297,21 +297,25 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { #[inline] pub fn from_bool(b: bool, tcx: TyCtxt<'tcx>) -> Self { - let layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(tcx.types.bool)).unwrap(); + let layout = tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.bool)) + .unwrap(); Self::from_scalar(Scalar::from_bool(b), layout) } #[inline] pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self { let ty = tcx.ty_ordering_enum(None); - let layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap(); + let layout = + tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap(); Self::from_scalar(Scalar::from_i8(c as i8), layout) } pub fn from_pair(a: Self, b: Self, tcx: TyCtxt<'tcx>) -> Self { let layout = tcx .layout_of( - ty::ParamEnv::reveal_all().and(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])), + ty::TypingEnv::fully_monomorphized() + .as_query_input(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])), ) .unwrap(); Self::from_scalar_pair(a.to_scalar(), b.to_scalar(), layout) @@ -341,7 +345,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { #[inline] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) - pub fn to_pair(self, cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>)) -> (Self, Self) { + pub fn to_pair(self, cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>)) -> (Self, Self) { let layout = self.layout; let (val0, val1) = self.to_scalar_pair(); ( @@ -773,8 +777,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { )?; if !mir_assign_valid_types( *self.tcx, - self.typing_mode(), - self.param_env, + self.typing_env(), self.layout_of(normalized_place_ty)?, op.layout, ) { @@ -833,9 +836,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }) }; let layout = - from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || { - self.layout_of(ty).into() - })?; + from_known_layout(self.tcx, self.typing_env(), layout, || self.layout_of(ty).into())?; let imm = match val_val { mir::ConstValue::Indirect { alloc_id, offset } => { // This is const data, no mutation allowed. diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index fbc85d37953..201f1b5dc62 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -533,7 +533,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } OffsetOf(fields) => { let val = - self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes(); + self.tcx.offset_of_subfield(self.typing_env(), layout, fields.iter()).bytes(); ImmTy::from_uint(val, usize_layout()) } UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx), diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index cc8d1db6cfb..13fcccca76b 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -540,8 +540,7 @@ where )?; if !mir_assign_valid_types( *self.tcx, - self.typing_mode(), - self.param_env, + self.typing_env(), self.layout_of(normalized_place_ty)?, place.layout, ) { @@ -871,13 +870,8 @@ where ) -> InterpResult<'tcx> { // We do NOT compare the types for equality, because well-typed code can // actually "transmute" `&mut T` to `&T` in an assignment without a cast. - let layout_compat = mir_assign_valid_types( - *self.tcx, - self.typing_mode(), - self.param_env, - src.layout(), - dest.layout(), - ); + let layout_compat = + mir_assign_valid_types(*self.tcx, self.typing_env(), src.layout(), dest.layout()); if !allow_transmute && !layout_compat { span_bug!( self.cur_span(), diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 50c0446b3cd..037c1a233ee 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -379,7 +379,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { for &const_ in body.required_consts() { let c = self.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?; - c.eval(*self.tcx, self.param_env, const_.span).map_err(|err| { + c.eval(*self.tcx, self.typing_env(), const_.span).map_err(|err| { err.emit_note(*self.tcx); err })?; @@ -596,13 +596,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return interp_ok(layout); } - let layout = - from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || { - let local_ty = frame.body.local_decls[local].ty; - let local_ty = - self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?; - self.layout_of(local_ty).into() - })?; + let layout = from_known_layout(self.tcx, self.typing_env(), layout, || { + let local_ty = frame.body.local_decls[local].ty; + let local_ty = + self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?; + self.layout_of(local_ty).into() + })?; // Layouts of locals are requested a lot, so we cache them. state.layout.set(Some(layout)); diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 18cff2c5e0f..d4525243642 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -418,7 +418,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .collect::>>()?; let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx); - let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder); + let fn_sig = + self.tcx.normalize_erasing_late_bound_regions(self.typing_env(), fn_sig_binder); let extra_args = &args[fn_sig.inputs().len()..]; let extra_args = self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty)); diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3a68db9f7f7..005b430bc8a 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -448,7 +448,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { meta: MemPlaceMeta, pointee: TyAndLayout<'tcx>, ) -> InterpResult<'tcx> { - let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.param_env); + let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.typing_env()); match tail.kind() { ty::Dynamic(data, _, ty::Dyn) => { let vtable = meta.unwrap_meta().to_pointer(self.ecx)?; @@ -568,7 +568,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind }); }; let (size, _align) = - global_alloc.size_and_align(*self.ecx.tcx, self.ecx.param_env); + global_alloc.size_and_align(*self.ecx.tcx, self.ecx.typing_env()); if let GlobalAlloc::Static(did) = global_alloc { let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else { @@ -955,7 +955,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { ) -> Cow<'e, RangeSet> { assert!(layout.ty.is_union()); assert!(layout.is_sized(), "there are no unsized unions"); - let layout_cx = LayoutCx::new(*ecx.tcx, ecx.param_env); + let layout_cx = LayoutCx::new(*ecx.tcx, ecx.typing_env()); return M::cached_union_data_range(ecx, layout.ty, || { let mut out = RangeSet(Vec::new()); union_data_range_uncached(&layout_cx, layout, Size::ZERO, &mut out); diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 0490195caf4..527236b2c22 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -47,7 +47,7 @@ pub fn provide(providers: &mut Providers) { providers.hooks.try_destructure_mir_constant_for_user_output = const_eval::try_destructure_mir_constant_for_user_output; providers.valtree_to_const_val = |tcx, (ty, valtree)| { - const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree) + const_eval::valtree_to_const_value(tcx, ty::ParamEnv::reveal_all().and(ty), valtree) }; providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| { util::check_validity_requirement(tcx, init_kind, param_env_and_ty) diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs index 6fa7d369229..9507b24f603 100644 --- a/compiler/rustc_const_eval/src/util/alignment.rs +++ b/compiler/rustc_const_eval/src/util/alignment.rs @@ -9,7 +9,7 @@ use tracing::debug; pub fn is_disaligned<'tcx, L>( tcx: TyCtxt<'tcx>, local_decls: &L, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, place: Place<'tcx>, ) -> bool where @@ -22,8 +22,8 @@ where }; let ty = place.ty(local_decls, tcx).ty; - let unsized_tail = || tcx.struct_tail_for_codegen(ty, param_env); - match tcx.layout_of(param_env.and(ty)) { + let unsized_tail = || tcx.struct_tail_for_codegen(ty, typing_env); + match tcx.layout_of(typing_env.as_query_input(ty)) { Ok(layout) if layout.align.abi <= pack && (layout.is_sized() diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index f743525f359..1afc910ce8f 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -3,7 +3,7 @@ use rustc_middle::bug; use rustc_middle::ty::layout::{ HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement, }; -use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt}; +use rustc_middle::ty::{PseudoCanonicalInput, Ty, TyCtxt}; use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine}; use crate::interpret::{InterpCx, MemoryKind}; @@ -23,16 +23,16 @@ use crate::interpret::{InterpCx, MemoryKind}; pub fn check_validity_requirement<'tcx>( tcx: TyCtxt<'tcx>, kind: ValidityRequirement, - param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + input: PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> Result> { - let layout = tcx.layout_of(param_env_and_ty)?; + let layout = tcx.layout_of(input)?; // There is nothing strict or lax about inhabitedness. if kind == ValidityRequirement::Inhabited { return Ok(!layout.is_uninhabited()); } - let layout_cx = LayoutCx::new(tcx, param_env_and_ty.param_env); + let layout_cx = LayoutCx::new(tcx, input.typing_env); if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks { check_validity_requirement_strict(layout, &layout_cx, kind) } else { @@ -49,7 +49,7 @@ fn check_validity_requirement_strict<'tcx>( ) -> Result> { let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error); - let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.param_env, machine); + let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env.param_env, machine); let allocated = cx .allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap)) diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index 0cf27d30c36..9eed1a20f15 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -5,18 +5,17 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, TypingMode, Variance}; +use rustc_middle::ty::{Ty, TyCtxt, TypingEnv, Variance}; use rustc_trait_selection::traits::ObligationCtxt; /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. pub fn sub_types<'tcx>( tcx: TyCtxt<'tcx>, - typing_mode: TypingMode<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, src: Ty<'tcx>, dest: Ty<'tcx>, ) -> bool { - relate_types(tcx, typing_mode, param_env, Variance::Covariant, src, dest) + relate_types(tcx, typing_env, Variance::Covariant, src, dest) } /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. @@ -26,8 +25,7 @@ pub fn sub_types<'tcx>( /// because we want to check for type equality. pub fn relate_types<'tcx>( tcx: TyCtxt<'tcx>, - typing_mode: TypingMode<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, variance: Variance, src: Ty<'tcx>, dest: Ty<'tcx>, @@ -36,8 +34,7 @@ pub fn relate_types<'tcx>( return true; } - let mut builder = tcx.infer_ctxt().ignoring_regions(); - let infcx = builder.build(typing_mode); + let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); let src = ocx.normalize(&cause, param_env, src); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 3080d8b3510..cf8c81c0b08 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -21,8 +21,7 @@ use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt}; use rustc_middle::ty::{ - AdtDef, GenericArgKind, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, + AdtDef, GenericArgKind, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; use rustc_session::lint::builtin::UNINHABITED_STATIC; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; @@ -114,15 +113,15 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b } } - let param_env = tcx.param_env(item_def_id); + let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id); for field in &def.non_enum_variant().fields { - let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args)) + let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args)) else { tcx.dcx().span_delayed_bug(span, "could not normalize field type"); continue; }; - if !allowed_union_field(field_ty, tcx, param_env) { + if !allowed_union_field(field_ty, tcx, typing_env.param_env) { let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) { // We are currently checking the type this field came from, so it must be local. Some(Node::Field(field)) => (field.span, field.ty.span), @@ -137,7 +136,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b note: (), }); return false; - } else if field_ty.needs_drop(tcx, param_env) { + } else if field_ty.needs_drop(tcx, typing_env) { // This should never happen. But we can get here e.g. in case of name resolution errors. tcx.dcx() .span_delayed_bug(span, "we should never accept maybe-dropping union fields"); @@ -158,7 +157,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { // reason to allow any statics to be uninhabited. let ty = tcx.type_of(def_id).instantiate_identity(); let span = tcx.def_span(def_id); - let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) { + let layout = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { Ok(l) => l, // Foreign statics that overflow their allowed size should emit an error Err(LayoutError::SizeOverflow(_)) @@ -237,7 +236,10 @@ pub(super) fn check_opaque_for_cycles<'tcx>( // And also look for cycle errors in the layout of coroutines. if let Err(&LayoutError::Cycle(guar)) = - tcx.layout_of(tcx.param_env(def_id).and(Ty::new_opaque(tcx, def_id.to_def_id(), args))) + tcx.layout_of( + ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) + .as_query_input(Ty::new_opaque(tcx, def_id.to_def_id(), args)), + ) { return Err(guar); } @@ -1307,8 +1309,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) // "known" respecting #[non_exhaustive] attributes. let field_infos = adt.all_fields().map(|field| { let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did)); - let param_env = tcx.param_env(field.did); - let layout = tcx.layout_of(param_env.and(ty)); + let typing_env = ty::TypingEnv::non_body_analysis(tcx, field.did); + let layout = tcx.layout_of(typing_env.as_query_input(ty)); // We are currently checking the type this field came from, so it must be local let span = tcx.hir().span_if_local(field.did).unwrap(); let trivial = layout.is_ok_and(|layout| layout.is_1zst()); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1802f00bc1f..d8bf7fdbb0f 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1126,7 +1126,7 @@ fn check_type_defn<'tcx>( let ty = tcx.type_of(variant.tail().did).instantiate_identity(); let ty = tcx.erase_regions(ty); assert!(!ty.has_infer()); - ty.needs_drop(tcx, tcx.param_env(item.owner_id)) + ty.needs_drop(tcx, ty::TypingEnv::non_body_analysis(tcx, item.owner_id.def_id)) } }; // All fields (except for possibly the last) should be sized. @@ -1281,7 +1281,8 @@ fn check_item_type( UnsizedHandling::Forbid => true, UnsizedHandling::Allow => false, UnsizedHandling::AllowIfForeignTail => { - let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.param_env); + let tail = + tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env)); !matches!(tail.kind(), ty::Foreign(_)) } }; diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 5ff52376837..c2ad61820a7 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -259,7 +259,9 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() let ty_a = field.ty(tcx, args_a); let ty_b = field.ty(tcx, args_b); - if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) { + if let Ok(layout) = + tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a)) + { if layout.is_1zst() { // ignore 1-ZST fields return false; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 92f38a7dde0..39471931461 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -3,7 +3,7 @@ use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err}; use rustc_hir::{self as hir, HirId}; use rustc_middle::bug; use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::{self, ParamEnv, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use crate::errors; @@ -130,7 +130,7 @@ fn is_valid_cmse_inputs<'tcx>( let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig); for (index, ty) in fn_sig.inputs().iter().enumerate() { - let layout = tcx.layout_of(ParamEnv::reveal_all().and(*ty))?; + let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))?; let align = layout.layout.align().abi.bytes(); let size = layout.layout.size().bytes(); @@ -158,8 +158,10 @@ fn is_valid_cmse_output<'tcx>( // this type is only used for layout computation, which does not rely on regions let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig); + let typing_env = ty::TypingEnv::fully_monomorphized(); + let mut ret_ty = fn_sig.output(); - let layout = tcx.layout_of(ParamEnv::reveal_all().and(ret_ty))?; + let layout = tcx.layout_of(typing_env.as_query_input(ret_ty))?; let size = layout.layout.size().bytes(); if size <= 4 { @@ -182,7 +184,7 @@ fn is_valid_cmse_output<'tcx>( for variant_def in adt_def.variants() { for field_def in variant_def.fields.iter() { let ty = field_def.ty(tcx, args); - let layout = tcx.layout_of(ParamEnv::reveal_all().and(ty))?; + let layout = tcx.layout_of(typing_env.as_query_input(ty))?; if !layout.layout.is_1zst() { ret_ty = ty; diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 354993513da..1610848958e 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2357,8 +2357,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Only assoc fns that return `Self` let fn_sig = self.tcx.fn_sig(item.def_id).skip_binder(); let ret_ty = fn_sig.output(); - let ret_ty = - self.tcx.normalize_erasing_late_bound_regions(self.param_env, ret_ty); + let ret_ty = self.tcx.normalize_erasing_late_bound_regions( + self.typing_env(self.param_env), + ret_ty, + ); if !self.can_eq(self.param_env, ret_ty, adt_ty) { return None; } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index a754f7fddc9..789530d35dd 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -46,7 +46,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let span = tcx.hir().span(hir_id); let normalize = |ty| { let ty = self.resolve_vars_if_possible(ty); - self.tcx.normalize_erasing_regions(self.param_env, ty) + self.tcx.normalize_erasing_regions(self.typing_env(self.param_env), ty) }; let from = normalize(from); let to = normalize(to); @@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - let skel = |ty| SizeSkeleton::compute(ty, tcx, self.param_env); + let skel = |ty| SizeSkeleton::compute(ty, tcx, self.typing_env(self.param_env)); let sk_from = skel(from); let sk_to = skel(to); trace!(?sk_from, ?sk_to); diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 175fca327f3..d50eff0deb0 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1257,7 +1257,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option> { let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id)); - if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)) { + // FIXME(#132279): Using `non_body_analysis` here feels wrong. + if !ty.has_significant_drop( + self.tcx, + ty::TypingEnv::non_body_analysis(self.tcx, closure_def_id), + ) { debug!("does not have significant drop"); return None; } @@ -1535,8 +1539,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base_path_ty: Ty<'tcx>, captured_by_move_projs: Vec<&[Projection<'tcx>]>, ) -> bool { - let needs_drop = - |ty: Ty<'tcx>| ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)); + // FIXME(#132279): Using `non_body_analysis` here feels wrong. + let needs_drop = |ty: Ty<'tcx>| { + ty.has_significant_drop( + self.tcx, + ty::TypingEnv::non_body_analysis(self.tcx, closure_def_id), + ) + }; let is_drop_defined_for_ty = |ty: Ty<'tcx>| { let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 391e640f8bc..8694800ac43 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -881,6 +881,8 @@ impl<'tcx> TypeFolder> for EagerlyNormalizeConsts<'tcx> { } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - self.tcx.try_normalize_erasing_regions(self.param_env, ct).unwrap_or(ct) + self.tcx + .try_normalize_erasing_regions(ty::TypingEnv::from_param_env(self.param_env), ct) + .unwrap_or(ct) } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 12df4a10e63..fc3b9863acc 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -38,7 +38,8 @@ use rustc_middle::ty::fold::{ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ self, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef, - GenericParamDefKind, InferConst, IntVid, Ty, TyCtxt, TyVid, TypingMode, + GenericParamDefKind, InferConst, IntVid, PseudoCanonicalInput, Ty, TyCtxt, TyVid, + TypeVisitable, TypingEnv, TypingMode, }; use rustc_span::Span; use rustc_span::symbol::Symbol; @@ -565,6 +566,13 @@ impl<'tcx> InferCtxtBuilder<'tcx> { (infcx, value, args) } + pub fn build_with_typing_env( + mut self, + TypingEnv { typing_mode, param_env }: TypingEnv<'tcx>, + ) -> (InferCtxt<'tcx>, ty::ParamEnv<'tcx>) { + (self.build(typing_mode), param_env) + } + pub fn build(&mut self, typing_mode: TypingMode<'tcx>) -> InferCtxt<'tcx> { let InferCtxtBuilder { tcx, considering_regions, skip_leak_check, next_trait_solver } = *self; @@ -1278,6 +1286,42 @@ impl<'tcx> InferCtxt<'tcx> { u } + /// Extract [ty::TypingMode] of this inference context to get a `TypingEnv` + /// which contains the necessary information to use the trait system without + /// using canonicalization or carrying this inference context around. + pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> { + let typing_mode = match self.typing_mode(param_env) { + ty::TypingMode::Coherence => ty::TypingMode::Coherence, + // FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible + // to handle them without proper canonicalization. This means we may cause cycle + // errors and fail to reveal opaques while inside of bodies. We should rename this + // function and require explicit comments on all use-sites in the future. + ty::TypingMode::Analysis { defining_opaque_types: _ } => { + TypingMode::non_body_analysis() + } + ty::TypingMode::PostAnalysis => ty::TypingMode::PostAnalysis, + }; + ty::TypingEnv { typing_mode, param_env } + } + + /// Similar to [Self::canonicalize_query], except that it returns + /// a [PseudoCanonicalInput] and requires both the `value` and the + /// `param_env` to not contain any inference variables or placeholders. + pub fn pseudo_canonicalize_query( + &self, + param_env: ty::ParamEnv<'tcx>, + value: V, + ) -> PseudoCanonicalInput<'tcx, V> + where + V: TypeVisitable>, + { + debug_assert!(!value.has_infer()); + debug_assert!(!value.has_placeholders()); + debug_assert!(!param_env.has_infer()); + debug_assert!(!param_env.has_placeholders()); + self.typing_env(param_env).as_query_input(value) + } + /// The returned function is used in a fast path. If it returns `true` the variable is /// unchanged, `false` indicates that the status is unknown. #[inline] diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 130f3cb7c2a..f6366ec3b80 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2485,7 +2485,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { }); // Check if this ADT has a constrained layout (like `NonNull` and friends). - if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)) { + if let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty)) { if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) = &layout.backend_repr { @@ -2521,7 +2521,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { ty: Ty<'tcx>, init: InitKind, ) -> Option { - let ty = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty).unwrap_or(ty); + let ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty); use rustc_type_ir::TyKind::*; match ty.kind() { @@ -2568,7 +2568,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { let definitely_inhabited = match variant .inhabited_predicate(cx.tcx, *adt_def) .instantiate(cx.tcx, args) - .apply_any_module(cx.tcx, cx.param_env) + .apply_any_module(cx.tcx, cx.typing_env()) { // Entirely skip uninhabited variants. Some(false) => return None, diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index aa7ec2659d0..6eec32beab0 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -19,7 +19,7 @@ use rustc_middle::bug; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths}; -use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingMode}; +use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode}; use rustc_session::lint::{ BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId, }; @@ -708,6 +708,10 @@ impl<'tcx> LateContext<'tcx> { TypingMode::non_body_analysis() } + pub fn typing_env(&self) -> TypingEnv<'tcx> { + TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } + } + /// Gets the type-checking results for the current body, /// or `None` if outside a body. pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> { @@ -906,7 +910,7 @@ impl<'tcx> LateContext<'tcx> { .find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id) .and_then(|assoc| { let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]); - tcx.try_normalize_erasing_regions(self.param_env, proj).ok() + tcx.try_normalize_erasing_regions(self.typing_env(), proj).ok() }) } @@ -1010,10 +1014,10 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for LateContext<'tcx> { } } -impl<'tcx> ty::layout::HasParamEnv<'tcx> for LateContext<'tcx> { +impl<'tcx> ty::layout::HasTypingEnv<'tcx> for LateContext<'tcx> { #[inline] - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.typing_env() } } diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index cf68e41243f..dbc920ea5ae 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -166,7 +166,7 @@ fn suggest_question_mark<'tcx>( } let ty = args.type_at(0); - let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); + let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env()); let ocx = ObligationCtxt::new(&infcx); let body_def_id = cx.tcx.hir().body_owner_def_id(body_id); @@ -175,7 +175,7 @@ fn suggest_question_mark<'tcx>( ocx.register_bound( cause, - cx.param_env, + param_env, // Erase any region vids from the type, which may not be resolved infcx.tcx.erase_regions(ty), into_iterator_did, diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 394ea798d3e..45b188205d2 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -131,7 +131,7 @@ impl ClashingExternDeclarations { // Check that the declarations match. if !structurally_same_type( tcx, - tcx.param_env(this_fi.owner_id), + ty::TypingEnv::non_body_analysis(tcx, this_fi.owner_id), existing_decl_ty, this_decl_ty, types::CItemKind::Declaration, @@ -205,18 +205,18 @@ fn get_relevant_span(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> Span { /// with the same members (as the declarations shouldn't clash). fn structurally_same_type<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>, ckind: types::CItemKind, ) -> bool { let mut seen_types = UnordSet::default(); - let result = structurally_same_type_impl(&mut seen_types, tcx, param_env, a, b, ckind); + let result = structurally_same_type_impl(&mut seen_types, tcx, typing_env, a, b, ckind); if cfg!(debug_assertions) && result { // Sanity-check: must have same ABI, size and alignment. // `extern` blocks cannot be generic, so we'll always get a layout here. - let a_layout = tcx.layout_of(param_env.and(a)).unwrap(); - let b_layout = tcx.layout_of(param_env.and(b)).unwrap(); + let a_layout = tcx.layout_of(typing_env.as_query_input(a)).unwrap(); + let b_layout = tcx.layout_of(typing_env.as_query_input(b)).unwrap(); assert_eq!(a_layout.backend_repr, b_layout.backend_repr); assert_eq!(a_layout.size, b_layout.size); assert_eq!(a_layout.align, b_layout.align); @@ -227,7 +227,7 @@ fn structurally_same_type<'tcx>( fn structurally_same_type_impl<'tcx>( seen_types: &mut UnordSet<(Ty<'tcx>, Ty<'tcx>)>, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>, ckind: types::CItemKind, @@ -303,7 +303,7 @@ fn structurally_same_type_impl<'tcx>( structurally_same_type_impl( seen_types, tcx, - param_env, + typing_env, tcx.type_of(a_did).instantiate(tcx, a_gen_args), tcx.type_of(b_did).instantiate(tcx, b_gen_args), ckind, @@ -315,23 +315,23 @@ fn structurally_same_type_impl<'tcx>( // For arrays, we also check the length. a_len == b_len && structurally_same_type_impl( - seen_types, tcx, param_env, *a_ty, *b_ty, ckind, + seen_types, tcx, typing_env, *a_ty, *b_ty, ckind, ) } (Slice(a_ty), Slice(b_ty)) => { - structurally_same_type_impl(seen_types, tcx, param_env, *a_ty, *b_ty, ckind) + structurally_same_type_impl(seen_types, tcx, typing_env, *a_ty, *b_ty, ckind) } (RawPtr(a_ty, a_mutbl), RawPtr(b_ty, b_mutbl)) => { a_mutbl == b_mutbl && structurally_same_type_impl( - seen_types, tcx, param_env, *a_ty, *b_ty, ckind, + seen_types, tcx, typing_env, *a_ty, *b_ty, ckind, ) } (Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => { // For structural sameness, we don't need the region to be same. a_mut == b_mut && structurally_same_type_impl( - seen_types, tcx, param_env, *a_ty, *b_ty, ckind, + seen_types, tcx, typing_env, *a_ty, *b_ty, ckind, ) } (FnDef(..), FnDef(..)) => { @@ -346,12 +346,12 @@ fn structurally_same_type_impl<'tcx>( (a_sig.abi, a_sig.safety, a_sig.c_variadic) == (b_sig.abi, b_sig.safety, b_sig.c_variadic) && a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| { - structurally_same_type_impl(seen_types, tcx, param_env, *a, *b, ckind) + structurally_same_type_impl(seen_types, tcx, typing_env, *a, *b, ckind) }) && structurally_same_type_impl( seen_types, tcx, - param_env, + typing_env, a_sig.output(), b_sig.output(), ckind, @@ -379,14 +379,14 @@ fn structurally_same_type_impl<'tcx>( // An Adt and a primitive or pointer type. This can be FFI-safe if non-null // enum layout optimisation is being applied. (Adt(..), _) if is_primitive_or_pointer(b) => { - if let Some(a_inner) = types::repr_nullable_ptr(tcx, param_env, a, ckind) { + if let Some(a_inner) = types::repr_nullable_ptr(tcx, typing_env, a, ckind) { a_inner == b } else { false } } (_, Adt(..)) if is_primitive_or_pointer(a) => { - if let Some(b_inner) = types::repr_nullable_ptr(tcx, param_env, b, ckind) { + if let Some(b_inner) = types::repr_nullable_ptr(tcx, typing_env, b, ckind) { b_inner == a } else { false diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index afcfbebc14b..0e874669043 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -368,7 +368,7 @@ impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> { .cx .typeck_results() .expr_ty(expr) - .has_significant_drop(self.cx.tcx, self.cx.param_env) + .has_significant_drop(self.cx.tcx, self.cx.typing_env()) { return ControlFlow::Break(expr.span); } diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 2f338f42f19..38c38b59bc5 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -103,7 +103,8 @@ declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUE impl LateLintPass<'_> for QueryStability { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return }; - if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, args) { + if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, args) + { let def_id = instance.def_id(); if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { cx.emit_span_lint(POTENTIAL_QUERY_INSTABILITY, span, QueryInstability { @@ -544,7 +545,7 @@ impl Diagnostics { ) { // Is the callee marked with `#[rustc_lint_diagnostics]`? let Some(inst) = - ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args).ok().flatten() + ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, fn_gen_args).ok().flatten() else { return; }; diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs index abee9ee7869..9e4e8333164 100644 --- a/compiler/rustc_lint/src/let_underscore.rs +++ b/compiler/rustc_lint/src/let_underscore.rs @@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { // If the type has a trivial Drop implementation, then it doesn't // matter that we drop the value immediately. - if !ty.needs_drop(cx.tcx, cx.param_env) { + if !ty.needs_drop(cx.tcx, cx.typing_env()) { return; } // Lint for patterns like `mutex.lock()`, which returns `Result` as well. diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index cf25ec99e67..36b1ff59c67 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -157,15 +157,17 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc Some(ty_def) if cx.tcx.is_lang_item(ty_def.did(), LangItem::String), ); - let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); + let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env()); let suggest_display = is_str - || cx.tcx.get_diagnostic_item(sym::Display).is_some_and(|t| { - infcx.type_implements_trait(t, [ty], cx.param_env).may_apply() - }); + || cx + .tcx + .get_diagnostic_item(sym::Display) + .is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply()); let suggest_debug = !suggest_display - && cx.tcx.get_diagnostic_item(sym::Debug).is_some_and(|t| { - infcx.type_implements_trait(t, [ty], cx.param_env).may_apply() - }); + && cx + .tcx + .get_diagnostic_item(sym::Debug) + .is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply()); let suggest_panic_any = !is_str && panic == sym::std_panic_macro; diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 4890a93fa76..76dc96ae00f 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -94,9 +94,9 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { let args = cx .tcx - .normalize_erasing_regions(cx.param_env, cx.typeck_results().node_args(expr.hir_id)); + .normalize_erasing_regions(cx.typing_env(), cx.typeck_results().node_args(expr.hir_id)); // Resolve the trait method instance. - let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, did, args) else { + let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), did, args) else { return; }; // (Re)check that it implements the noop diagnostic. diff --git a/compiler/rustc_lint/src/tail_expr_drop_order.rs b/compiler/rustc_lint/src/tail_expr_drop_order.rs index 89763059877..19763ce1ec5 100644 --- a/compiler/rustc_lint/src/tail_expr_drop_order.rs +++ b/compiler/rustc_lint/src/tail_expr_drop_order.rs @@ -103,7 +103,7 @@ impl TailExprDropOrder { if matches!(fn_kind, hir::intravisit::FnKind::Closure) { for &capture in cx.tcx.closure_captures(def_id) { if matches!(capture.info.capture_kind, ty::UpvarCapture::ByValue) - && capture.place.ty().has_significant_drop(cx.tcx, cx.param_env) + && capture.place.ty().has_significant_drop(cx.tcx, cx.typing_env()) { locals.push(capture.var_ident.span); } @@ -113,7 +113,7 @@ impl TailExprDropOrder { if cx .typeck_results() .node_type(param.hir_id) - .has_significant_drop(cx.tcx, cx.param_env) + .has_significant_drop(cx.tcx, cx.typing_env()) { locals.push(param.span); } @@ -158,7 +158,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LocalCollector<'a, 'tcx> { fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) { if let PatKind::Binding(_binding_mode, id, ident, pat) = pat.kind { let ty = self.cx.typeck_results().node_type(id); - if ty.has_significant_drop(self.cx.tcx, self.cx.param_env) { + if ty.has_significant_drop(self.cx.tcx, self.cx.typing_env()) { self.locals.push(ident.span); } if let Some(pat) = pat { @@ -234,7 +234,10 @@ impl<'a, 'tcx> LintTailExpr<'a, 'tcx> { if Self::expr_eventually_point_into_local(expr) { return false; } - self.cx.typeck_results().expr_ty(expr).has_significant_drop(self.cx.tcx, self.cx.param_env) + self.cx + .typeck_results() + .expr_ty(expr) + .has_significant_drop(self.cx.tcx, self.cx.typing_env()) } } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index be70149b664..2e6cb993842 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -613,10 +613,11 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>( tcx: TyCtxt<'tcx>, variant: &'a ty::VariantDef, ) -> Option<&'a ty::FieldDef> { - let param_env = tcx.param_env(variant.def_id); + let typing_env = ty::TypingEnv::non_body_analysis(tcx, variant.def_id); variant.fields.iter().find(|field| { let field_ty = tcx.type_of(field.did).instantiate_identity(); - let is_1zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_1zst()); + let is_1zst = + tcx.layout_of(typing_env.as_query_input(field_ty)).is_ok_and(|layout| layout.is_1zst()); !is_1zst }) } @@ -624,11 +625,11 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>( /// Is type known to be non-null? fn ty_is_known_nonnull<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, mode: CItemKind, ) -> bool { - let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); match ty.kind() { ty::FnPtr(..) => true, @@ -649,7 +650,7 @@ fn ty_is_known_nonnull<'tcx>( def.variants() .iter() .filter_map(|variant| transparent_newtype_field(tcx, variant)) - .any(|field| ty_is_known_nonnull(tcx, param_env, field.ty(tcx, args), mode)) + .any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args), mode)) } _ => false, } @@ -659,10 +660,10 @@ fn ty_is_known_nonnull<'tcx>( /// If the type passed in was not scalar, returns None. fn get_nullable_type<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> Option> { - let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); Some(match *ty.kind() { ty::Adt(field_def, field_args) => { @@ -679,7 +680,7 @@ fn get_nullable_type<'tcx>( .expect("No non-zst fields in transparent type.") .ty(tcx, field_args) }; - return get_nullable_type(tcx, param_env, inner_field_ty); + return get_nullable_type(tcx, typing_env, inner_field_ty); } ty::Int(ty) => Ty::new_int(tcx, ty), ty::Uint(ty) => Ty::new_uint(tcx, ty), @@ -708,10 +709,10 @@ fn get_nullable_type<'tcx>( /// - Does not have the `#[non_exhaustive]` attribute. fn is_niche_optimization_candidate<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> bool { - if tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| !layout.is_1zst()) { + if tcx.layout_of(typing_env.as_query_input(ty)).is_ok_and(|layout| !layout.is_1zst()) { return false; } @@ -734,7 +735,7 @@ fn is_niche_optimization_candidate<'tcx>( /// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes. pub(crate) fn repr_nullable_ptr<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ckind: CItemKind, ) -> Option> { @@ -747,9 +748,9 @@ pub(crate) fn repr_nullable_ptr<'tcx>( let ty1 = field1.ty(tcx, args); let ty2 = field2.ty(tcx, args); - if is_niche_optimization_candidate(tcx, param_env, ty1) { + if is_niche_optimization_candidate(tcx, typing_env, ty1) { ty2 - } else if is_niche_optimization_candidate(tcx, param_env, ty2) { + } else if is_niche_optimization_candidate(tcx, typing_env, ty2) { ty1 } else { return None; @@ -760,20 +761,20 @@ pub(crate) fn repr_nullable_ptr<'tcx>( _ => return None, }; - if !ty_is_known_nonnull(tcx, param_env, field_ty, ckind) { + if !ty_is_known_nonnull(tcx, typing_env, field_ty, ckind) { return None; } // At this point, the field's type is known to be nonnull and the parent enum is Option-like. // If the computed size for the field and the enum are different, the nonnull optimization isn't // being applied (and we've got a problem somewhere). - let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, param_env).ok(); + let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, typing_env).ok(); if !compute_size_skeleton(ty)?.same_size(compute_size_skeleton(field_ty)?) { bug!("improper_ctypes: Option nonnull optimization not applied?"); } // Return the nullable type this Option-like enum can be safely represented with. - let field_ty_layout = tcx.layout_of(param_env.and(field_ty)); + let field_ty_layout = tcx.layout_of(typing_env.as_query_input(field_ty)); if field_ty_layout.is_err() && !field_ty.has_non_region_param() { bug!("should be able to compute the layout of non-polymorphic type"); } @@ -784,10 +785,10 @@ pub(crate) fn repr_nullable_ptr<'tcx>( WrappingRange { start: 0, end } if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 => { - return Some(get_nullable_type(tcx, param_env, field_ty).unwrap()); + return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap()); } WrappingRange { start: 1, .. } => { - return Some(get_nullable_type(tcx, param_env, field_ty).unwrap()); + return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap()); } WrappingRange { start, end } => { unreachable!("Unhandled start and end range: ({}, {})", start, end) @@ -825,7 +826,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let field_ty = self .cx .tcx - .try_normalize_erasing_regions(self.cx.param_env, field_ty) + .try_normalize_erasing_regions(self.cx.typing_env(), field_ty) .unwrap_or(field_ty); self.check_type_for_ffi(acc, field_ty) } @@ -988,7 +989,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { { // Special-case types like `Option` and `Result` if let Some(ty) = - repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode) + repr_nullable_ptr(self.cx.tcx, self.cx.typing_env(), ty, self.mode) { return self.check_type_for_ffi(acc, ty); } @@ -1196,7 +1197,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { if let Some(ty) = self .cx .tcx - .try_normalize_erasing_regions(self.cx.param_env, ty) + .try_normalize_erasing_regions(self.cx.typing_env(), ty) .unwrap_or(ty) .visit_with(&mut ProhibitOpaqueTypes) .break_value() @@ -1220,7 +1221,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return; } - let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.param_env, ty).unwrap_or(ty); + let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.typing_env(), ty).unwrap_or(ty); // C doesn't really support passing arrays by value - the only way to pass an array by value // is through a struct. So, first test that the top level isn't an array, and then diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 6c13127b04e..5ec920d39f4 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -272,7 +272,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { || !ty.is_inhabited_from( cx.tcx, cx.tcx.parent_module(expr.hir_id).to_def_id(), - cx.param_env, + cx.typing_env(), ) { return Some(MustUsePath::Suppressed); @@ -556,7 +556,7 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements { if let hir::StmtKind::Semi(expr) = s.kind { if let hir::ExprKind::Path(_) = expr.kind { let ty = cx.typeck_results().expr_ty(expr); - if ty.needs_drop(cx.tcx, cx.param_env) { + if ty.needs_drop(cx.tcx, cx.typing_env()) { let sub = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) { PathStatementDropSub::Suggestion { span: s.span, snippet } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 493db498b7c..ace46891f83 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -6,7 +6,7 @@ use rustc_ast::CRATE_NODE_ID; use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_middle::query::LocalCrate; -use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; +use rustc_middle::ty::{self, List, Ty, TyCtxt}; use rustc_session::Session; use rustc_session::config::CrateType; use rustc_session::cstore::{ @@ -613,7 +613,7 @@ impl<'tcx> Collector<'tcx> { .map(|ty| { let layout = self .tcx - .layout_of(ParamEnvAnd { param_env: ParamEnv::empty(), value: ty }) + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .expect("layout") .layout; // In both stdcall and fastcall, we always round up the argument size to the diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index f95635370dc..a51370369b8 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -102,10 +102,11 @@ impl<'tcx> ConstValue<'tcx> { pub fn try_to_bits_for_ty( &self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> Option { - let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; + let size = + tcx.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(ty)).ok()?.size; self.try_to_bits(size) } @@ -314,7 +315,7 @@ impl<'tcx> Const<'tcx> { pub fn eval( self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, span: Span, ) -> Result, ErrorHandled> { match self { @@ -333,7 +334,7 @@ impl<'tcx> Const<'tcx> { } Const::Unevaluated(uneval, _) => { // FIXME: We might want to have a `try_eval`-like function on `Unevaluated` - tcx.const_eval_resolve(param_env, uneval, span) + tcx.const_eval_resolve(typing_env, uneval, span) } Const::Val(val, _) => Ok(val), } @@ -343,7 +344,7 @@ impl<'tcx> Const<'tcx> { pub fn try_eval_scalar( self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> Option { if let Const::Ty(_, c) = self && let ty::ConstKind::Value(ty, val) = c.kind() @@ -354,7 +355,7 @@ impl<'tcx> Const<'tcx> { // pointer here, which valtrees don't represent.) Some(val.unwrap_leaf().into()) } else { - self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar() + self.eval(tcx, typing_env, DUMMY_SP).ok()?.try_to_scalar() } } @@ -362,23 +363,29 @@ impl<'tcx> Const<'tcx> { pub fn try_eval_scalar_int( self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> Option { - self.try_eval_scalar(tcx, param_env)?.try_to_scalar_int().ok() + self.try_eval_scalar(tcx, typing_env)?.try_to_scalar_int().ok() } #[inline] - pub fn try_eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option { - let int = self.try_eval_scalar_int(tcx, param_env)?; - let size = - tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(self.ty())).ok()?.size; + pub fn try_eval_bits( + &self, + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ) -> Option { + let int = self.try_eval_scalar_int(tcx, typing_env)?; + let size = tcx + .layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(self.ty())) + .ok()? + .size; Some(int.to_bits(size)) } /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. #[inline] - pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 { - self.try_eval_bits(tcx, param_env) + pub fn eval_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> u128 { + self.try_eval_bits(tcx, typing_env) .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", self.ty(), self)) } @@ -386,21 +393,21 @@ impl<'tcx> Const<'tcx> { pub fn try_eval_target_usize( self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> Option { - Some(self.try_eval_scalar_int(tcx, param_env)?.to_target_usize(tcx)) + Some(self.try_eval_scalar_int(tcx, typing_env)?.to_target_usize(tcx)) } #[inline] /// Panics if the value cannot be evaluated or doesn't contain a valid `usize`. - pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u64 { - self.try_eval_target_usize(tcx, param_env) + pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> u64 { + self.try_eval_target_usize(tcx, typing_env) .unwrap_or_else(|| bug!("expected usize, got {:#?}", self)) } #[inline] - pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option { - self.try_eval_scalar_int(tcx, param_env)?.try_into().ok() + pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option { + self.try_eval_scalar_int(tcx, typing_env)?.try_into().ok() } #[inline] @@ -411,17 +418,16 @@ impl<'tcx> Const<'tcx> { pub fn from_bits( tcx: TyCtxt<'tcx>, bits: u128, - param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, ) -> Self { let size = tcx - .layout_of(param_env_ty) - .unwrap_or_else(|e| { - bug!("could not compute layout for {:?}: {:?}", param_env_ty.value, e) - }) + .layout_of(typing_env.as_query_input(ty)) + .unwrap_or_else(|e| bug!("could not compute layout for {ty:?}: {e:?}")) .size; let cv = ConstValue::Scalar(Scalar::from_uint(bits, size)); - Self::Val(cv, param_env_ty.value) + Self::Val(cv, ty) } #[inline] @@ -438,7 +444,8 @@ impl<'tcx> Const<'tcx> { pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { let ty = tcx.types.usize; - Self::from_bits(tcx, n as u128, ty::ParamEnv::empty().and(ty)) + let typing_env = ty::TypingEnv::fully_monomorphized(); + Self::from_bits(tcx, n as u128, typing_env, ty) } #[inline] diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index f225ad94aa7..c4b0e6e39cc 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -351,7 +351,11 @@ impl<'tcx> GlobalAlloc<'tcx> { } } - pub fn size_and_align(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> (Size, Align) { + pub fn size_and_align( + &self, + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ) -> (Size, Align) { match self { GlobalAlloc::Static(def_id) => { let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { @@ -374,7 +378,7 @@ impl<'tcx> GlobalAlloc<'tcx> { .type_of(def_id) .no_bound_vars() .expect("statics should not have generic parameters"); - let layout = tcx.layout_of(param_env.and(ty)).unwrap(); + let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap(); assert!(layout.is_sized()); (layout.size, layout.align.abi) } diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 2ecf1d0bcf8..7092f87a7d1 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -58,7 +58,7 @@ impl<'tcx> TyCtxt<'tcx> { #[instrument(level = "debug", skip(self))] pub fn const_eval_resolve( self, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ct: mir::UnevaluatedConst<'tcx>, span: Span, ) -> EvalToConstValueResult<'tcx> { @@ -72,14 +72,11 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::try_resolve( - self, param_env, - // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst? - ct.def, ct.args, - ) { + // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst? + match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: ct.promoted }; - self.const_eval_global_id(param_env, cid, span) + self.const_eval_global_id(typing_env.param_env, cid, span) } // For errors during resolution, we deliberately do not point at the usage site of the constant, // since for these errors the place the constant is used shouldn't matter. @@ -91,7 +88,7 @@ impl<'tcx> TyCtxt<'tcx> { #[instrument(level = "debug", skip(self))] pub fn const_eval_resolve_for_typeck( self, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ct: ty::UnevaluatedConst<'tcx>, span: Span, ) -> EvalToValTreeResult<'tcx> { @@ -105,10 +102,10 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::try_resolve(self, param_env, ct.def, ct.args) { + match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: None }; - self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| { + self.const_eval_global_id_for_typeck(typing_env.param_env, cid, span).inspect(|_| { // We are emitting the lint here instead of in `is_const_evaluatable` // as we normalize obligations before checking them, and normalization // uses this function to evaluate this constant. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 260c6543f98..425cb059e57 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -39,7 +39,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; use crate::ty::visit::TypeVisitableExt; use crate::ty::{ - self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode, + self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingEnv, UserTypeAnnotationIndex, }; @@ -452,12 +452,17 @@ impl<'tcx> Body<'tcx> { self.basic_blocks.as_mut() } - pub fn typing_mode(&self, _tcx: TyCtxt<'tcx>) -> TypingMode<'tcx> { + pub fn typing_env(&self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { match self.phase { - // FIXME(#132279): the MIR is quite clearly inside of a body, so we - // should instead reveal opaques defined by that body here. - MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(), - MirPhase::Runtime(_) => TypingMode::PostAnalysis, + // FIXME(#132279): we should reveal the opaques defined in the body during analysis. + MirPhase::Built | MirPhase::Analysis(_) => TypingEnv { + typing_mode: ty::TypingMode::non_body_analysis(), + param_env: tcx.param_env(self.source.def_id()), + }, + MirPhase::Runtime(_) => TypingEnv { + typing_mode: ty::TypingMode::PostAnalysis, + param_env: tcx.param_env_reveal_all_normalized(self.source.def_id()), + }, } } @@ -618,7 +623,7 @@ impl<'tcx> Body<'tcx> { } /// If this basic block ends with a [`TerminatorKind::SwitchInt`] for which we can evaluate the - /// dimscriminant in monomorphization, we return the discriminant bits and the + /// discriminant in monomorphization, we return the discriminant bits and the /// [`SwitchTargets`], just so the caller doesn't also have to match on the terminator. fn try_const_mono_switchint<'a>( tcx: TyCtxt<'tcx>, @@ -627,13 +632,15 @@ impl<'tcx> Body<'tcx> { ) -> Option<(u128, &'a SwitchTargets)> { // There are two places here we need to evaluate a constant. let eval_mono_const = |constant: &ConstOperand<'tcx>| { - let env = ty::ParamEnv::reveal_all(); + // FIXME(#132279): what is this, why are we using an empty environment with + // `RevealAll` here. + let typing_env = ty::TypingEnv::fully_monomorphized(); let mono_literal = instance.instantiate_mir_and_normalize_erasing_regions( tcx, - env, + typing_env, crate::ty::EarlyBinder::bind(constant.const_), ); - mono_literal.try_eval_bits(tcx, env) + mono_literal.try_eval_bits(tcx, typing_env) }; let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else { diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 88ed90c3114..1ce735cec63 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -332,9 +332,9 @@ impl<'tcx> Operand<'tcx> { span: Span, ) -> Operand<'tcx> { debug_assert!({ - let param_env_and_ty = ty::ParamEnv::empty().and(ty); + let typing_env = ty::TypingEnv::fully_monomorphized(); let type_size = tcx - .layout_of(param_env_and_ty) + .layout_of(typing_env.as_query_input(ty)) .unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}")) .size; let scalar_size = match val { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index f01ac305d3f..2083279e128 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -20,7 +20,7 @@ use smallvec::SmallVec; use super::{BasicBlock, Const, Local, UserTypeProjection}; use crate::mir::coverage::CoverageKind; use crate::ty::adjustment::PointerCoercion; -use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex}; +use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex}; /// Represents the "flavors" of MIR. /// @@ -100,13 +100,6 @@ impl MirPhase { MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized", } } - - pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> { - match self { - MirPhase::Built | MirPhase::Analysis(_) => tcx.param_env(body_def_id), - MirPhase::Runtime(_) => tcx.param_env_reveal_all_normalized(body_def_id), - } - } } /// See [`MirPhase::Analysis`]. diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index c5def5fc65b..9cb11cdd3b7 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -467,6 +467,18 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> { } } +impl<'tcx, T: Key> Key for ty::PseudoCanonicalInput<'tcx, T> { + type Cache = DefaultCache; + + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.value.default_span(tcx) + } + + fn ty_def_id(&self) -> Option { + self.value.ty_def_id() + } +} + impl Key for Symbol { type Cache = DefaultCache; @@ -575,7 +587,7 @@ impl Key for (LocalDefId, HirId) { } } -impl<'tcx> Key for (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) { +impl<'tcx> Key for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) { type Cache = DefaultCache; // Just forward to `Ty<'tcx>` diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4068d06f6df..684d5b6c2a7 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -81,8 +81,8 @@ use crate::ty::layout::ValidityRequirement; use crate::ty::print::{PrintTraitRefExt, describe_as_module}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::{ - self, CrateInherentImpls, GenericArg, GenericArgsRef, ParamEnvAnd, Ty, TyCtxt, TyCtxtFeed, - UnusedGenericParams, + self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt, + TyCtxtFeed, UnusedGenericParams, }; use crate::{dep_graph, mir, thir}; @@ -1341,10 +1341,10 @@ rustc_queries! { } query codegen_select_candidate( - key: (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>) + key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>> ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { cache_on_disk_if { true } - desc { |tcx| "computing candidate for `{}`", key.1 } + desc { |tcx| "computing candidate for `{}`", key.value } } /// Return all `impl` blocks in the current crate. @@ -1406,15 +1406,15 @@ rustc_queries! { desc { "computing whether `{}` is `Unpin`", env.value } } /// Query backing `Ty::needs_drop`. - query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + query needs_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` needs drop", env.value } } /// Query backing `Ty::needs_async_drop`. - query needs_async_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + query needs_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` needs async drop", env.value } } /// Query backing `Ty::has_significant_drop_raw`. - query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { + query has_significant_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` has a significant drop", env.value } } @@ -1451,7 +1451,7 @@ rustc_queries! { /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode, and will normalize the input type. query layout_of( - key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> + key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>> ) -> Result, &'tcx ty::layout::LayoutError<'tcx>> { depth_limit desc { "computing layout of `{}`", key.value } @@ -1464,7 +1464,7 @@ rustc_queries! { /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance` /// instead, where the instance is an `InstanceKind::Virtual`. query fn_abi_of_fn_ptr( - key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)> + key: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)> ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> { desc { "computing call ABI of `{}` function pointers", key.value.0 } } @@ -1475,7 +1475,7 @@ rustc_queries! { /// NB: that includes virtual calls, which are represented by "direct calls" /// to an `InstanceKind::Virtual` instance (of `::fn`). query fn_abi_of_instance( - key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)> + key: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)> ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> { desc { "computing call ABI of `{}`", key.value.0 } } @@ -2088,7 +2088,7 @@ rustc_queries! { /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead. query try_normalize_generic_arg_after_erasing_regions( - goal: ParamEnvAnd<'tcx, GenericArg<'tcx>> + goal: PseudoCanonicalInput<'tcx, GenericArg<'tcx>> ) -> Result, NoSolution> { desc { "normalizing `{}`", goal.value } } @@ -2245,7 +2245,7 @@ rustc_queries! { /// from `Ok(None)` to avoid misleading diagnostics when an error /// has already been/will be emitted, for the original cause. query resolve_instance_raw( - key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)> + key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)> ) -> Result>, ErrorGuaranteed> { desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } } @@ -2283,7 +2283,7 @@ rustc_queries! { desc { "computing the backend features for CLI flags" } } - query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result> { + query check_validity_requirement(key: (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>)) -> Result> { desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 } } diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 45ceb0a555d..8f26e05cb72 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -905,7 +905,7 @@ impl<'tcx> PatRange<'tcx> { &self, value: mir::Const<'tcx>, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> Option { use Ordering::*; debug_assert_eq!(self.ty, value.ty()); @@ -913,10 +913,10 @@ impl<'tcx> PatRange<'tcx> { let value = PatRangeBoundary::Finite(value); // For performance, it's important to only do the second comparison if necessary. Some( - match self.lo.compare_with(value, ty, tcx, param_env)? { + match self.lo.compare_with(value, ty, tcx, typing_env)? { Less | Equal => true, Greater => false, - } && match value.compare_with(self.hi, ty, tcx, param_env)? { + } && match value.compare_with(self.hi, ty, tcx, typing_env)? { Less => true, Equal => self.end == RangeEnd::Included, Greater => false, @@ -929,17 +929,17 @@ impl<'tcx> PatRange<'tcx> { &self, other: &Self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> Option { use Ordering::*; debug_assert_eq!(self.ty, other.ty); // For performance, it's important to only do the second comparison if necessary. Some( - match other.lo.compare_with(self.hi, self.ty, tcx, param_env)? { + match other.lo.compare_with(self.hi, self.ty, tcx, typing_env)? { Less => true, Equal => self.end == RangeEnd::Included, Greater => false, - } && match self.lo.compare_with(other.hi, self.ty, tcx, param_env)? { + } && match self.lo.compare_with(other.hi, self.ty, tcx, typing_env)? { Less => true, Equal => other.end == RangeEnd::Included, Greater => false, @@ -985,9 +985,14 @@ impl<'tcx> PatRangeBoundary<'tcx> { Self::NegInfinity | Self::PosInfinity => None, } } - pub fn eval_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 { + pub fn eval_bits( + self, + ty: Ty<'tcx>, + tcx: TyCtxt<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ) -> u128 { match self { - Self::Finite(value) => value.eval_bits(tcx, param_env), + Self::Finite(value) => value.eval_bits(tcx, typing_env), Self::NegInfinity => { // Unwrap is ok because the type is known to be numeric. ty.numeric_min_and_max_as_bits(tcx).unwrap().0 @@ -999,13 +1004,13 @@ impl<'tcx> PatRangeBoundary<'tcx> { } } - #[instrument(skip(tcx, param_env), level = "debug", ret)] + #[instrument(skip(tcx, typing_env), level = "debug", ret)] pub fn compare_with( self, other: Self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> Option { use PatRangeBoundary::*; match (self, other) { @@ -1034,8 +1039,8 @@ impl<'tcx> PatRangeBoundary<'tcx> { _ => {} } - let a = self.eval_bits(ty, tcx, param_env); - let b = other.eval_bits(ty, tcx, param_env); + let a = self.eval_bits(ty, tcx, typing_env); + let b = other.eval_bits(ty, tcx, typing_env); match ty.kind() { ty::Float(ty::FloatTy::F16) => { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 0773eb7a3be..79d56702be2 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -498,12 +498,13 @@ impl<'tcx> AdtDef<'tcx> { expr_did: DefId, ) -> Result, ErrorGuaranteed> { assert!(self.is_enum()); - let param_env = tcx.param_env(expr_did); + let repr_type = self.repr().discr_type(); match tcx.const_eval_poly(expr_did) { Ok(val) => { + let typing_env = ty::TypingEnv::post_analysis(tcx, expr_did); let ty = repr_type.to_ty(tcx); - if let Some(b) = val.try_to_bits_for_ty(tcx, param_env, ty) { + if let Some(b) = val.try_to_bits_for_ty(tcx, typing_env, ty) { trace!("discriminants: {} ({:?})", b, repr_type); Ok(Discr { val: b, ty }) } else { diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 5689f3d4265..3bd09fc91c6 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -9,7 +9,7 @@ use tracing::{debug, instrument}; use crate::middle::resolve_bound_vars as rbv; use crate::mir::interpret::{LitToConstInput, Scalar}; -use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; +use crate::ty::{self, GenericArgs, Ty, TyCtxt, TypeVisitableExt}; mod int; mod kind; @@ -330,17 +330,22 @@ impl<'tcx> Const<'tcx> { None } - #[inline] /// Creates a constant with the given integer value and interns it. - pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Self { + #[inline] + pub fn from_bits( + tcx: TyCtxt<'tcx>, + bits: u128, + typing_env: ty::TypingEnv<'tcx>, + ty: Ty<'tcx>, + ) -> Self { let size = tcx - .layout_of(ty) + .layout_of(typing_env.as_query_input(ty)) .unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}")) .size; ty::Const::new_value( tcx, ty::ValTree::from_scalar_int(ScalarInt::try_from_uint(bits, size).unwrap()), - ty.value, + ty, ) } @@ -353,13 +358,13 @@ impl<'tcx> Const<'tcx> { #[inline] /// Creates an interned bool constant. pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self { - Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool)) + Self::from_bits(tcx, v as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.bool) } #[inline] /// Creates an interned usize constant. pub fn from_target_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { - Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize)) + Self::from_bits(tcx, n as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.usize) } /// Panics if self.kind != ty::ConstKind::Value @@ -393,15 +398,15 @@ impl<'tcx> Const<'tcx> { self.try_to_valtree()?.0.try_to_target_usize(tcx) } - #[inline] /// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it /// contains const generic parameters or pointers). - pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option { + #[inline] + pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option { let (scalar, ty) = self.try_to_scalar()?; let scalar = scalar.try_to_scalar_int().ok()?; - let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; - // if `ty` does not depend on generic parameters, use an empty param_env + let input = typing_env.with_reveal_all_normalized(tcx).as_query_input(ty); + let size = tcx.layout_of(input).ok()?.size; Some(scalar.to_bits(size)) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 84ac281c258..2ba1bf2822f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -596,8 +596,16 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.coroutine_is_async_gen(coroutine_def_id) } - fn layout_is_pointer_like(self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { - self.layout_of(self.erase_regions(param_env.and(ty))) + // We don't use `TypingEnv` here as it's only defined in `rustc_middle` and + // `rustc_next_trait_solver` shouldn't have to know about it. + fn layout_is_pointer_like( + self, + typing_mode: ty::TypingMode<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ty: Ty<'tcx>, + ) -> bool { + let typing_env = ty::TypingEnv { typing_mode, param_env }; + self.layout_of(self.erase_regions(typing_env).as_query_input(self.erase_regions(ty))) .is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout)) } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index bf741f63a3d..505c7278176 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -3,7 +3,7 @@ use smallvec::SmallVec; use tracing::instrument; use crate::ty::context::TyCtxt; -use crate::ty::{self, DefId, OpaqueTypeKey, ParamEnv, Ty}; +use crate::ty::{self, DefId, OpaqueTypeKey, Ty, TypingEnv}; /// Represents whether some type is inhabited in a given context. /// Examples of uninhabited types are `!`, `enum Void {}`, or a struct @@ -35,8 +35,13 @@ pub enum InhabitedPredicate<'tcx> { impl<'tcx> InhabitedPredicate<'tcx> { /// Returns true if the corresponding type is inhabited in the given `ParamEnv` and module. - pub fn apply(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, module_def_id: DefId) -> bool { - self.apply_revealing_opaque(tcx, param_env, module_def_id, &|_| None) + pub fn apply( + self, + tcx: TyCtxt<'tcx>, + typing_env: TypingEnv<'tcx>, + module_def_id: DefId, + ) -> bool { + self.apply_revealing_opaque(tcx, typing_env, module_def_id, &|_| None) } /// Returns true if the corresponding type is inhabited in the given `ParamEnv` and module, @@ -44,13 +49,13 @@ impl<'tcx> InhabitedPredicate<'tcx> { pub fn apply_revealing_opaque( self, tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, module_def_id: DefId, reveal_opaque: &impl Fn(OpaqueTypeKey<'tcx>) -> Option>, ) -> bool { let Ok(result) = self.apply_inner::( tcx, - param_env, + typing_env, &mut Default::default(), &|id| Ok(tcx.is_descendant_of(module_def_id, id)), reveal_opaque, @@ -59,25 +64,25 @@ impl<'tcx> InhabitedPredicate<'tcx> { } /// Same as `apply`, but returns `None` if self contains a module predicate - pub fn apply_any_module(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option { - self.apply_inner(tcx, param_env, &mut Default::default(), &|_| Err(()), &|_| None).ok() + pub fn apply_any_module(self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>) -> Option { + self.apply_inner(tcx, typing_env, &mut Default::default(), &|_| Err(()), &|_| None).ok() } /// Same as `apply`, but `NotInModule(_)` predicates yield `false`. That is, /// privately uninhabited types are considered always uninhabited. - pub fn apply_ignore_module(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> bool { + pub fn apply_ignore_module(self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>) -> bool { let Ok(result) = - self.apply_inner::(tcx, param_env, &mut Default::default(), &|_| Ok(true), &|_| { + self.apply_inner::(tcx, typing_env, &mut Default::default(), &|_| Ok(true), &|_| { None }); result } - #[instrument(level = "debug", skip(tcx, param_env, in_module, reveal_opaque), ret)] + #[instrument(level = "debug", skip(tcx, typing_env, in_module, reveal_opaque), ret)] fn apply_inner( self, tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, eval_stack: &mut SmallVec<[Ty<'tcx>; 1]>, // for cycle detection in_module: &impl Fn(DefId) -> Result, reveal_opaque: &impl Fn(OpaqueTypeKey<'tcx>) -> Option>, @@ -94,7 +99,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { // we have a param_env available, we can do better. Self::GenericType(t) => { let normalized_pred = tcx - .try_normalize_erasing_regions(param_env, t) + .try_normalize_erasing_regions(typing_env, t) .map_or(self, |t| t.inhabited_predicate(tcx)); match normalized_pred { // We don't have more information than we started with, so consider inhabited. @@ -107,7 +112,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { } eval_stack.push(t); let ret = - pred.apply_inner(tcx, param_env, eval_stack, in_module, reveal_opaque); + pred.apply_inner(tcx, typing_env, eval_stack, in_module, reveal_opaque); eval_stack.pop(); ret } @@ -126,7 +131,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { eval_stack.push(t); let ret = t.inhabited_predicate(tcx).apply_inner( tcx, - param_env, + typing_env, eval_stack, in_module, reveal_opaque, @@ -136,10 +141,10 @@ impl<'tcx> InhabitedPredicate<'tcx> { } }, Self::And([a, b]) => try_and(a, b, |x| { - x.apply_inner(tcx, param_env, eval_stack, in_module, reveal_opaque) + x.apply_inner(tcx, typing_env, eval_stack, in_module, reveal_opaque) }), Self::Or([a, b]) => try_or(a, b, |x| { - x.apply_inner(tcx, param_env, eval_stack, in_module, reveal_opaque) + x.apply_inner(tcx, typing_env, eval_stack, in_module, reveal_opaque) }), } } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index dd00db8635f..4a5f6d80f24 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -181,18 +181,18 @@ impl<'tcx> Ty<'tcx> { self, tcx: TyCtxt<'tcx>, module: DefId, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> bool { - self.inhabited_predicate(tcx).apply(tcx, param_env, module) + self.inhabited_predicate(tcx).apply(tcx, typing_env, module) } /// Returns true if the type is uninhabited without regard to visibility pub fn is_privately_uninhabited( self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> bool { - !self.inhabited_predicate(tcx).apply_ignore_module(tcx, param_env) + !self.inhabited_predicate(tcx).apply_ignore_module(tcx, typing_env) } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 0d1c56f0d38..d42b6be4787 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -178,9 +178,9 @@ pub enum InstanceKind<'tcx> { impl<'tcx> Instance<'tcx> { /// Returns the `Ty` corresponding to this `Instance`, with generic instantiations applied and /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization. - pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { + pub fn ty(&self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Ty<'tcx> { let ty = tcx.type_of(self.def.def_id()); - tcx.instantiate_and_normalize_erasing_regions(self.args, param_env, ty) + tcx.instantiate_and_normalize_erasing_regions(self.args, typing_env, ty) } /// Finds a crate that contains a monomorphization of this instance that @@ -519,7 +519,7 @@ impl<'tcx> Instance<'tcx> { #[instrument(level = "debug", skip(tcx), ret)] pub fn try_resolve( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, ) -> Result>, ErrorGuaranteed> { @@ -537,17 +537,14 @@ impl<'tcx> Instance<'tcx> { // All regions in the result of this query are erased, so it's // fine to erase all of the input regions. - - // HACK(eddyb) erase regions in `args` first, so that `param_env.and(...)` - // below is more likely to ignore the bounds in scope (e.g. if the only - // generic parameters mentioned by `args` were lifetime ones). + let typing_env = tcx.erase_regions(typing_env); let args = tcx.erase_regions(args); - tcx.resolve_instance_raw(tcx.erase_regions(param_env.and((def_id, args)))) + tcx.resolve_instance_raw(typing_env.as_query_input((def_id, args))) } pub fn expect_resolve( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, span: Span, @@ -558,7 +555,7 @@ impl<'tcx> Instance<'tcx> { let span_or_local_def_span = || if span.is_dummy() && def_id.is_local() { tcx.def_span(def_id) } else { span }; - match ty::Instance::try_resolve(tcx, param_env, def_id, args) { + match ty::Instance::try_resolve(tcx, typing_env, def_id, args) { Ok(Some(instance)) => instance, Ok(None) => { let type_length = type_length(args); @@ -600,7 +597,7 @@ impl<'tcx> Instance<'tcx> { pub fn resolve_for_fn_ptr( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, ) -> Option> { @@ -608,7 +605,7 @@ impl<'tcx> Instance<'tcx> { // Use either `resolve_closure` or `resolve_for_vtable` assert!(!tcx.is_closure_like(def_id), "Called `resolve_for_fn_ptr` on closure: {def_id:?}"); let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::FnPtr); - Instance::try_resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| { + Instance::try_resolve(tcx, typing_env, def_id, args).ok().flatten().map(|mut resolved| { match resolved.def { InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); @@ -648,7 +645,7 @@ impl<'tcx> Instance<'tcx> { pub fn expect_resolve_for_vtable( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, span: Span, @@ -664,7 +661,7 @@ impl<'tcx> Instance<'tcx> { return Instance { def: InstanceKind::VTableShim(def_id), args }; } - let mut resolved = Instance::expect_resolve(tcx, param_env, def_id, args, span); + let mut resolved = Instance::expect_resolve(tcx, typing_env, def_id, args, span); let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable); match resolved.def { @@ -743,7 +740,7 @@ impl<'tcx> Instance<'tcx> { let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), def_id, args, ty.ty_adt_def().and_then(|adt| tcx.hir().span_if_local(adt.did())).unwrap_or(DUMMY_SP), @@ -755,7 +752,7 @@ impl<'tcx> Instance<'tcx> { let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), def_id, args, ty.ty_adt_def().and_then(|adt| tcx.hir().span_if_local(adt.did())).unwrap_or(DUMMY_SP), @@ -883,16 +880,16 @@ impl<'tcx> Instance<'tcx> { pub fn instantiate_mir_and_normalize_erasing_regions( &self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, v: EarlyBinder<'tcx, T>, ) -> T where T: TypeFoldable>, { if let Some(args) = self.args_for_mir_body() { - tcx.instantiate_and_normalize_erasing_regions(args, param_env, v) + tcx.instantiate_and_normalize_erasing_regions(args, typing_env, v) } else { - tcx.normalize_erasing_regions(param_env, v.instantiate_identity()) + tcx.normalize_erasing_regions(typing_env, v.instantiate_identity()) } } @@ -901,21 +898,21 @@ impl<'tcx> Instance<'tcx> { pub fn try_instantiate_mir_and_normalize_erasing_regions( &self, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, v: EarlyBinder<'tcx, T>, ) -> Result> where T: TypeFoldable>, { if let Some(args) = self.args_for_mir_body() { - tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v) + tcx.try_instantiate_and_normalize_erasing_regions(args, typing_env, v) } else { // We're using `instantiate_identity` as e.g. // `FnPtrShim` is separately generated for every // instantiation of the `FnDef`, so the MIR body // is already instantiated. Any generic parameters it // contains are generic parameters from the caller. - tcx.try_normalize_erasing_regions(param_env, v.instantiate_identity()) + tcx.try_normalize_erasing_regions(typing_env, v.instantiate_identity()) } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index a0eb9029319..8625a8dcb2a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -297,12 +297,12 @@ impl<'tcx> IntoDiagArg for LayoutError<'tcx> { #[derive(Clone, Copy)] pub struct LayoutCx<'tcx> { pub calc: abi::LayoutCalculator>, - pub param_env: ty::ParamEnv<'tcx>, + pub typing_env: ty::TypingEnv<'tcx>, } impl<'tcx> LayoutCx<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { - Self { calc: abi::LayoutCalculator::new(tcx), param_env } + pub fn new(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Self { + Self { calc: abi::LayoutCalculator::new(tcx), typing_env } } } @@ -337,12 +337,12 @@ impl<'tcx> SizeSkeleton<'tcx> { pub fn compute( ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> Result, &'tcx LayoutError<'tcx>> { debug_assert!(!ty.has_non_region_infer()); // First try computing a static layout. - let err = match tcx.layout_of(param_env.and(ty)) { + let err = match tcx.layout_of(typing_env.as_query_input(ty)) { Ok(layout) => { if layout.is_sized() { return Ok(SizeSkeleton::Known(layout.size, Some(layout.align.abi))); @@ -367,7 +367,7 @@ impl<'tcx> SizeSkeleton<'tcx> { let tail = tcx.struct_tail_raw( pointee, - |ty| match tcx.try_normalize_erasing_regions(param_env, ty) { + |ty| match tcx.try_normalize_erasing_regions(typing_env, ty) { Ok(ty) => ty, Err(e) => Ty::new_error_with_message( tcx, @@ -402,7 +402,7 @@ impl<'tcx> SizeSkeleton<'tcx> { return Ok(SizeSkeleton::Known(Size::from_bytes(0), None)); } - match SizeSkeleton::compute(inner, tcx, param_env)? { + match SizeSkeleton::compute(inner, tcx, typing_env)? { // This may succeed because the multiplication of two types may overflow // but a single size of a nested array will not. SizeSkeleton::Known(s, a) => { @@ -432,7 +432,7 @@ impl<'tcx> SizeSkeleton<'tcx> { let i = VariantIdx::from_usize(i); let fields = def.variant(i).fields.iter().map(|field| { - SizeSkeleton::compute(field.ty(tcx, args), tcx, param_env) + SizeSkeleton::compute(field.ty(tcx, args), tcx, typing_env) }); let mut ptr = None; for field in fields { @@ -491,11 +491,11 @@ impl<'tcx> SizeSkeleton<'tcx> { } ty::Alias(..) => { - let normalized = tcx.normalize_erasing_regions(param_env, ty); + let normalized = tcx.normalize_erasing_regions(typing_env, ty); if ty == normalized { Err(err) } else { - SizeSkeleton::compute(normalized, tcx, param_env) + SizeSkeleton::compute(normalized, tcx, typing_env) } } @@ -521,8 +521,14 @@ pub trait HasTyCtxt<'tcx>: HasDataLayout { fn tcx(&self) -> TyCtxt<'tcx>; } -pub trait HasParamEnv<'tcx> { - fn param_env(&self) -> ty::ParamEnv<'tcx>; +pub trait HasTypingEnv<'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx>; + + /// FIXME(#132279): This method should not be used as in the future + /// everything should take a `TypingEnv` instead. Remove it as that point. + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.typing_env().param_env + } } impl<'tcx> HasDataLayout for TyCtxt<'tcx> { @@ -577,9 +583,9 @@ impl<'tcx> HasTyCtxt<'tcx> for TyCtxtAt<'tcx> { } } -impl<'tcx> HasParamEnv<'tcx> for LayoutCx<'tcx> { - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env +impl<'tcx> HasTypingEnv<'tcx> for LayoutCx<'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.typing_env } } @@ -646,7 +652,7 @@ pub type TyAndLayout<'tcx> = rustc_abi::TyAndLayout<'tcx, Ty<'tcx>>; /// Trait for contexts that want to be able to compute layouts of types. /// This automatically gives access to `LayoutOf`, through a blanket `impl`. -pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasParamEnv<'tcx> { +pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasTypingEnv<'tcx> { /// The `TyAndLayout`-wrapping type (or `TyAndLayout` itself), which will be /// returned from `layout_of` (see also `handle_layout_err`). type LayoutOfResult: MaybeResult> = TyAndLayout<'tcx>; @@ -692,7 +698,7 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> { let tcx = self.tcx().at(span); MaybeResult::from( - tcx.layout_of(self.param_env().and(ty)) + tcx.layout_of(self.typing_env().as_query_input(ty)) .map_err(|err| self.handle_layout_err(*err, span, ty)), ) } @@ -716,7 +722,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx> { impl<'tcx, C> TyAbiInterface<'tcx, C> for Ty<'tcx> where - C: HasTyCtxt<'tcx> + HasParamEnv<'tcx>, + C: HasTyCtxt<'tcx> + HasTypingEnv<'tcx>, { fn ty_and_layout_for_variant( this: TyAndLayout<'tcx>, @@ -736,10 +742,10 @@ where Variants::Single { index } => { let tcx = cx.tcx(); - let param_env = cx.param_env(); + let typing_env = cx.typing_env(); // Deny calling for_variant more than once for non-Single enums. - if let Ok(original_layout) = tcx.layout_of(param_env.and(this.ty)) { + if let Ok(original_layout) = tcx.layout_of(typing_env.as_query_input(this.ty)) { assert_eq!(original_layout.variants, Variants::Single { index }); } @@ -780,7 +786,7 @@ where fn field_ty_or_layout<'tcx>( this: TyAndLayout<'tcx>, - cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>), + cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>), i: usize, ) -> TyMaybeWithLayout<'tcx> { let tcx = cx.tcx(); @@ -823,12 +829,13 @@ where Ty::new_mut_ref(tcx, tcx.lifetimes.re_static, nil) }; - // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing - // the `Result` should always work because the type is - // always either `*mut ()` or `&'static mut ()`. + // NOTE: using an fully monomorphized typing env and `unwrap`-ing + // the `Result` should always work because the type is always either + // `*mut ()` or `&'static mut ()`. + let typing_env = ty::TypingEnv::fully_monomorphized(); return TyMaybeWithLayout::TyAndLayout(TyAndLayout { ty: this.ty, - ..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap() + ..tcx.layout_of(typing_env.as_query_input(unit_ptr_ty)).unwrap() }); } @@ -848,7 +855,7 @@ where && !pointee.references_error() { let metadata = tcx.normalize_erasing_regions( - cx.param_env(), + cx.typing_env(), Ty::new_projection(tcx, metadata_def_id, [pointee]), ); @@ -865,7 +872,7 @@ where metadata } } else { - match tcx.struct_tail_for_codegen(pointee, cx.param_env()).kind() { + match tcx.struct_tail_for_codegen(pointee, cx.typing_env()).kind() { ty::Slice(_) | ty::Str => tcx.types.usize, ty::Dynamic(data, _, ty::Dyn) => mk_dyn_vtable(data.principal()), _ => bug!("TyAndLayout::field({:?}): not applicable", this), @@ -953,7 +960,7 @@ where match field_ty_or_layout(this, cx, i) { TyMaybeWithLayout::Ty(field_ty) => { - cx.tcx().layout_of(cx.param_env().and(field_ty)).unwrap_or_else(|e| { + cx.tcx().layout_of(cx.typing_env().as_query_input(field_ty)).unwrap_or_else(|e| { bug!( "failed to get layout for `{field_ty}`: {e:?},\n\ despite it being a field (#{i}) of an existing layout: {this:#?}", @@ -972,18 +979,18 @@ where offset: Size, ) -> Option { let tcx = cx.tcx(); - let param_env = cx.param_env(); + let typing_env = cx.typing_env(); let pointee_info = match *this.ty.kind() { ty::RawPtr(p_ty, _) if offset.bytes() == 0 => { - tcx.layout_of(param_env.and(p_ty)).ok().map(|layout| PointeeInfo { + tcx.layout_of(typing_env.as_query_input(p_ty)).ok().map(|layout| PointeeInfo { size: layout.size, align: layout.align.abi, safe: None, }) } ty::FnPtr(..) if offset.bytes() == 0 => { - tcx.layout_of(param_env.and(this.ty)).ok().map(|layout| PointeeInfo { + tcx.layout_of(typing_env.as_query_input(this.ty)).ok().map(|layout| PointeeInfo { size: layout.size, align: layout.align.abi, safe: None, @@ -996,14 +1003,14 @@ where let optimize = tcx.sess.opts.optimize != OptLevel::No; let kind = match mt { hir::Mutability::Not => PointerKind::SharedRef { - frozen: optimize && ty.is_freeze(tcx, cx.param_env()), + frozen: optimize && ty.is_freeze(tcx, typing_env.param_env), }, hir::Mutability::Mut => PointerKind::MutableRef { - unpin: optimize && ty.is_unpin(tcx, cx.param_env()), + unpin: optimize && ty.is_unpin(tcx, typing_env.param_env), }, }; - tcx.layout_of(param_env.and(ty)).ok().map(|layout| PointeeInfo { + tcx.layout_of(typing_env.as_query_input(ty)).ok().map(|layout| PointeeInfo { size: layout.size, align: layout.align.abi, safe: Some(kind), @@ -1093,7 +1100,7 @@ where debug_assert!(pointee.safe.is_none()); let optimize = tcx.sess.opts.optimize != OptLevel::No; pointee.safe = Some(PointerKind::Box { - unpin: optimize && boxed_ty.is_unpin(tcx, cx.param_env()), + unpin: optimize && boxed_ty.is_unpin(tcx, typing_env.param_env), global: this.ty.is_box_global(tcx), }); } @@ -1304,9 +1311,11 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { let span = self.layout_tcx_at_span(); let tcx = self.tcx().at(span); - MaybeResult::from(tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).map_err( - |err| self.handle_fn_abi_err(*err, span, FnAbiRequest::OfFnPtr { sig, extra_args }), - )) + MaybeResult::from( + tcx.fn_abi_of_fn_ptr(self.typing_env().as_query_input((sig, extra_args))).map_err( + |err| self.handle_fn_abi_err(*err, span, FnAbiRequest::OfFnPtr { sig, extra_args }), + ), + ) } /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for @@ -1326,17 +1335,19 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { let tcx = self.tcx().at(span); MaybeResult::from( - tcx.fn_abi_of_instance(self.param_env().and((instance, extra_args))).map_err(|err| { - // HACK(eddyb) at least for definitions of/calls to `Instance`s, - // we can get some kind of span even if one wasn't provided. - // However, we don't do this early in order to avoid calling - // `def_span` unconditionally (which may have a perf penalty). - let span = if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) }; - self.handle_fn_abi_err(*err, span, FnAbiRequest::OfInstance { - instance, - extra_args, - }) - }), + tcx.fn_abi_of_instance(self.typing_env().as_query_input((instance, extra_args))) + .map_err(|err| { + // HACK(eddyb) at least for definitions of/calls to `Instance`s, + // we can get some kind of span even if one wasn't provided. + // However, we don't do this early in order to avoid calling + // `def_span` unconditionally (which may have a perf penalty). + let span = + if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) }; + self.handle_fn_abi_err(*err, span, FnAbiRequest::OfInstance { + instance, + extra_args, + }) + }), ) } } @@ -1346,14 +1357,14 @@ impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {} impl<'tcx> TyCtxt<'tcx> { pub fn offset_of_subfield( self, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, mut layout: TyAndLayout<'tcx>, indices: I, ) -> Size where I: Iterator, { - let cx = LayoutCx::new(self, param_env); + let cx = LayoutCx::new(self, typing_env); let mut offset = Size::ZERO; for (variant, field) in indices { @@ -1363,7 +1374,7 @@ impl<'tcx> TyCtxt<'tcx> { layout = layout.field(&cx, index); if !layout.is_sized() { // If it is not sized, then the tail must still have at least a known static alignment. - let tail = self.struct_tail_for_codegen(layout.ty, param_env); + let tail = self.struct_tail_for_codegen(layout.ty, typing_env); if !matches!(tail.kind(), ty::Slice(..)) { bug!( "offset of not-statically-aligned field (type {:?}) cannot be computed statically", diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7fda0662a34..d6f7ee748bb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -103,7 +103,7 @@ use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; use crate::metadata::ModChild; use crate::middle::privacy::EffectiveVisibilities; use crate::mir::{Body, CoroutineLayout}; -use crate::query::Providers; +use crate::query::{IntoQueryParam, Providers}; use crate::traits::{self, Reveal}; use crate::ty; pub use crate::ty::diagnostics::*; @@ -1122,6 +1122,104 @@ impl<'tcx, T> ParamEnvAnd<'tcx, T> { } } +/// The environment in which to do trait solving. +/// +/// Most of the time you only need to care about the `ParamEnv` +/// as the `TypingMode` is simply stored in the `InferCtxt`. +/// +/// However, there are some places which rely on trait solving +/// without using an `InferCtxt` themselves. For these to be +/// able to use the trait system they have to be able to initialize +/// such an `InferCtxt` with the right `typing_mode`, so they need +/// to track both. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(TypeVisitable, TypeFoldable)] +pub struct TypingEnv<'tcx> { + pub typing_mode: TypingMode<'tcx>, + pub param_env: ParamEnv<'tcx>, +} + +impl<'tcx> TypingEnv<'tcx> { + // FIXME(#132279): This method should be removed but simplifies the + // transition. + pub fn from_param_env(param_env: ParamEnv<'tcx>) -> TypingEnv<'tcx> { + TypingEnv { typing_mode: TypingMode::from_param_env(param_env), param_env } + } + + /// Create a typing environment with no where-clauses in scope + /// where all opaque types and default associated items are revealed. + /// + /// This is only suitable for monomorphized, post-typeck environments. + /// Do not use this for MIR optimizations, as even though they also + /// use `TypingMode::PostAnalysis`, they may still have where-clauses + /// in scope. + pub fn fully_monomorphized() -> TypingEnv<'tcx> { + TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::reveal_all() } + } + + /// Create a typing environment for use during analysis outside of a body. + /// + /// Using a typing environment inside of bodies is not supported as the body + /// may define opaque types. In this case the used functions have to be + /// converted to use proper canonical inputs instead. + pub fn non_body_analysis( + tcx: TyCtxt<'tcx>, + def_id: impl IntoQueryParam, + ) -> TypingEnv<'tcx> { + TypingEnv { typing_mode: TypingMode::non_body_analysis(), param_env: tcx.param_env(def_id) } + } + + pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam) -> TypingEnv<'tcx> { + TypingEnv { + typing_mode: TypingMode::PostAnalysis, + param_env: tcx.param_env_reveal_all_normalized(def_id), + } + } + + /// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all + /// opaque types in the `param_env`. + pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { + let TypingEnv { typing_mode: _, param_env } = self; + let param_env = param_env.with_reveal_all_normalized(tcx); + TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env } + } + + /// Combine this typing environment with the given `value` to be used by + /// not (yet) canonicalized queries. This only works if the value does not + /// contain anything local to some `InferCtxt`, i.e. inference variables or + /// placeholders. + pub fn as_query_input(self, value: T) -> PseudoCanonicalInput<'tcx, T> + where + T: TypeVisitable>, + { + debug_assert!(!value.has_infer()); + // FIXME(#132279): We should assert that the value does not contain any placeholders + // as these placeholders are also local to the current inference context. However, we + // currently use pseudo-canonical queries in the trait solver which replaces params with + // placeholders. We should also simply not use pseudo-canonical queries in the trait + // solver, at which point we can readd this assert. + // + // debug_assert!(!value.has_placeholders()); + PseudoCanonicalInput { typing_env: self, value } + } +} + +/// Similar to `CanonicalInput`, this carries the `typing_mode` and the environment +/// necessary to do any kind of trait solving inside of nested queries. +/// +/// Unlike proper canonicalization, this requires the `param_env` and the `value` to not +/// contain anything local to the `infcx` of the caller, so we don't actually canonicalize +/// anything. +/// +/// This should be created by using `infcx.pseudo_canonicalize_query(param_env, value)` +/// or by using `typing_env.as_query_input(value)`. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable)] +pub struct PseudoCanonicalInput<'tcx, T> { + pub typing_env: TypingEnv<'tcx>, + pub value: T, +} + #[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)] pub struct Destructor { /// The `DefId` of the destructor method diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index e51d2201922..f611b69905c 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -35,16 +35,16 @@ impl<'tcx> TyCtxt<'tcx> { /// /// This should only be used outside of type inference. For example, /// it assumes that normalization will succeed. - #[tracing::instrument(level = "debug", skip(self, param_env), ret)] - pub fn normalize_erasing_regions(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T + #[tracing::instrument(level = "debug", skip(self, typing_env), ret)] + pub fn normalize_erasing_regions(self, typing_env: ty::TypingEnv<'tcx>, value: T) -> T where T: TypeFoldable>, { debug!( - "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", + "normalize_erasing_regions::<{}>(value={:?}, typing_env={:?})", std::any::type_name::(), value, - param_env, + typing_env, ); // Erase first before we do the real query -- this keeps the @@ -55,7 +55,7 @@ impl<'tcx> TyCtxt<'tcx> { if !value.has_aliases() { value } else { - value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env }) + value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, typing_env }) } } @@ -66,17 +66,17 @@ impl<'tcx> TyCtxt<'tcx> { /// succeeds. pub fn try_normalize_erasing_regions( self, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, value: T, ) -> Result> where T: TypeFoldable>, { debug!( - "try_normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", + "try_normalize_erasing_regions::<{}>(value={:?}, typing_env={:?})", std::any::type_name::(), value, - param_env, + typing_env, ); // Erase first before we do the real query -- this keeps the @@ -87,7 +87,7 @@ impl<'tcx> TyCtxt<'tcx> { if !value.has_aliases() { Ok(value) } else { - let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, param_env); + let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, typing_env); value.try_fold_with(&mut folder) } } @@ -103,17 +103,17 @@ impl<'tcx> TyCtxt<'tcx> { // FIXME(@lcnr): This method should not be necessary, we now normalize // inside of binders. We should be able to only use // `tcx.instantiate_bound_regions_with_erased`. - #[tracing::instrument(level = "debug", skip(self, param_env))] + #[tracing::instrument(level = "debug", skip(self, typing_env))] pub fn normalize_erasing_late_bound_regions( self, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, value: ty::Binder<'tcx, T>, ) -> T where T: TypeFoldable>, { let value = self.instantiate_bound_regions_with_erased(value); - self.normalize_erasing_regions(param_env, value) + self.normalize_erasing_regions(typing_env, value) } /// Monomorphizes a type from the AST by first applying the @@ -125,14 +125,14 @@ impl<'tcx> TyCtxt<'tcx> { pub fn instantiate_and_normalize_erasing_regions( self, param_args: GenericArgsRef<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, value: EarlyBinder<'tcx, T>, ) -> T where T: TypeFoldable>, { let instantiated = value.instantiate(self, param_args); - self.normalize_erasing_regions(param_env, instantiated) + self.normalize_erasing_regions(typing_env, instantiated) } /// Monomorphizes a type from the AST by first applying the @@ -143,20 +143,20 @@ impl<'tcx> TyCtxt<'tcx> { pub fn try_instantiate_and_normalize_erasing_regions( self, param_args: GenericArgsRef<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, value: EarlyBinder<'tcx, T>, ) -> Result> where T: TypeFoldable>, { let instantiated = value.instantiate(self, param_args); - self.try_normalize_erasing_regions(param_env, instantiated) + self.try_normalize_erasing_regions(typing_env, instantiated) } } struct NormalizeAfterErasingRegionsFolder<'tcx> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, } impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> { @@ -164,8 +164,7 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> { &self, arg: ty::GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { - let arg = self.param_env.and(arg); - + let arg = self.typing_env.as_query_input(arg); self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!( "Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead", arg.value @@ -189,12 +188,12 @@ impl<'tcx> TypeFolder> for NormalizeAfterErasingRegionsFolder<'tcx> struct TryNormalizeAfterErasingRegionsFolder<'tcx> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, } impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> { - fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { - TryNormalizeAfterErasingRegionsFolder { tcx, param_env } + fn new(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Self { + TryNormalizeAfterErasingRegionsFolder { tcx, typing_env } } #[instrument(skip(self), level = "debug")] @@ -202,10 +201,8 @@ impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> { &self, arg: ty::GenericArg<'tcx>, ) -> Result, NoSolution> { - let arg = self.param_env.and(arg); - debug!(?arg); - - self.tcx.try_normalize_generic_arg_after_erasing_regions(arg) + let input = self.typing_env.as_query_input(arg); + self.tcx.try_normalize_generic_arg_after_erasing_regions(input) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 3c6e34160f4..1108619828d 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -18,6 +18,7 @@ use rustc_span::sym; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; +use super::TypingEnv; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::Providers; use crate::ty::layout::{FloatExt, IntegerExt}; @@ -177,9 +178,13 @@ impl<'tcx> TyCtxt<'tcx> { /// Should only be called if `ty` has no inference variables and does not /// need its lifetimes preserved (e.g. as part of codegen); otherwise /// normalization attempt may cause compiler bugs. - pub fn struct_tail_for_codegen(self, ty: Ty<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { + pub fn struct_tail_for_codegen( + self, + ty: Ty<'tcx>, + typing_env: ty::TypingEnv<'tcx>, + ) -> Ty<'tcx> { let tcx = self; - tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(param_env, ty), || {}) + tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(typing_env, ty), || {}) } /// Returns the deeply last field of nested structures, or the same type if @@ -271,11 +276,11 @@ impl<'tcx> TyCtxt<'tcx> { self, source: Ty<'tcx>, target: Ty<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> (Ty<'tcx>, Ty<'tcx>) { let tcx = self; tcx.struct_lockstep_tails_raw(source, target, |ty| { - tcx.normalize_erasing_regions(param_env, ty) + tcx.normalize_erasing_regions(typing_env, ty) }) } @@ -420,10 +425,10 @@ impl<'tcx> TyCtxt<'tcx> { // Async drop glue morphology is an internal detail, so reveal_all probably // should be fine - let param_env = ty::ParamEnv::reveal_all(); - if ty.needs_async_drop(self, param_env) { + let typing_env = ty::TypingEnv::fully_monomorphized(); + if ty.needs_async_drop(self, typing_env) { AsyncDropGlueMorphology::Custom - } else if ty.needs_drop(self, param_env) { + } else if ty.needs_drop(self, typing_env) { AsyncDropGlueMorphology::DeferredDropInPlace } else { AsyncDropGlueMorphology::Noop @@ -683,12 +688,10 @@ impl<'tcx> TyCtxt<'tcx> { } /// Get the type of the pointer to the static that we use in MIR. - pub fn static_ptr_ty(self, def_id: DefId) -> Ty<'tcx> { + pub fn static_ptr_ty(self, def_id: DefId, typing_env: ty::TypingEnv<'tcx>) -> Ty<'tcx> { // Make sure that any constants in the static's type are evaluated. - let static_ty = self.normalize_erasing_regions( - ty::ParamEnv::empty(), - self.type_of(def_id).instantiate_identity(), - ); + let static_ty = + self.normalize_erasing_regions(typing_env, self.type_of(def_id).instantiate_identity()); // Make sure that accesses to unsafe statics end up using raw pointers. // For thread-locals, this needs to be kept in sync with `Rvalue::ty`. @@ -1157,15 +1160,17 @@ impl<'tcx> Ty<'tcx> { /// Returns the maximum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option> { + let typing_env = TypingEnv::fully_monomorphized(); self.numeric_min_and_max_as_bits(tcx) - .map(|(_, max)| ty::Const::from_bits(tcx, max, ty::ParamEnv::empty().and(self))) + .map(|(_, max)| ty::Const::from_bits(tcx, max, typing_env, self)) } /// Returns the minimum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option> { + let typing_env = TypingEnv::fully_monomorphized(); self.numeric_min_and_max_as_bits(tcx) - .map(|(min, _)| ty::Const::from_bits(tcx, min, ty::ParamEnv::empty().and(self))) + .map(|(min, _)| ty::Const::from_bits(tcx, min, typing_env, self)) } /// Checks whether values of this type `T` are *moved* or *copied* @@ -1345,7 +1350,7 @@ impl<'tcx> Ty<'tcx> { /// /// Note that this method is used to check eligible types in unions. #[inline] - pub fn needs_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { + pub fn needs_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool { // Avoid querying in simple cases. match needs_drop_components(tcx, self) { Err(AlwaysRequiresDrop) => true, @@ -1359,14 +1364,13 @@ impl<'tcx> Ty<'tcx> { }; // This doesn't depend on regions, so try to minimize distinct - // query keys used. - // If normalization fails, we just use `query_ty`. - debug_assert!(!param_env.has_infer()); + // query keys used. If normalization fails, we just use `query_ty`. + debug_assert!(!typing_env.param_env.has_infer()); let query_ty = tcx - .try_normalize_erasing_regions(param_env, query_ty) + .try_normalize_erasing_regions(typing_env, query_ty) .unwrap_or_else(|_| tcx.erase_regions(query_ty)); - tcx.needs_drop_raw(param_env.and(query_ty)) + tcx.needs_drop_raw(typing_env.as_query_input(query_ty)) } } } @@ -1385,7 +1389,7 @@ impl<'tcx> Ty<'tcx> { // FIXME(zetanumbers): Note that this method is used to check eligible types // in unions. #[inline] - pub fn needs_async_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { + pub fn needs_async_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool { // Avoid querying in simple cases. match needs_drop_components(tcx, self) { Err(AlwaysRequiresDrop) => true, @@ -1401,12 +1405,12 @@ impl<'tcx> Ty<'tcx> { // This doesn't depend on regions, so try to minimize distinct // query keys used. // If normalization fails, we just use `query_ty`. - debug_assert!(!param_env.has_infer()); + debug_assert!(!typing_env.has_infer()); let query_ty = tcx - .try_normalize_erasing_regions(param_env, query_ty) + .try_normalize_erasing_regions(typing_env, query_ty) .unwrap_or_else(|_| tcx.erase_regions(query_ty)); - tcx.needs_async_drop_raw(param_env.and(query_ty)) + tcx.needs_async_drop_raw(typing_env.as_query_input(query_ty)) } } } @@ -1420,7 +1424,7 @@ impl<'tcx> Ty<'tcx> { /// Note that this method is used to check for change in drop order for /// 2229 drop reorder migration analysis. #[inline] - pub fn has_significant_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { + pub fn has_significant_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool { // Avoid querying in simple cases. match needs_drop_components(tcx, self) { Err(AlwaysRequiresDrop) => true, @@ -1443,8 +1447,8 @@ impl<'tcx> Ty<'tcx> { // This doesn't depend on regions, so try to minimize distinct // query keys used. - let erased = tcx.normalize_erasing_regions(param_env, query_ty); - tcx.has_significant_drop_raw(param_env.and(erased)) + let erased = tcx.normalize_erasing_regions(typing_env, query_ty); + tcx.has_significant_drop_raw(typing_env.as_query_input(erased)) } } } diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index 963fa12a8c7..e5eeb23be25 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -97,7 +97,7 @@ pub(super) fn vtable_allocation_provider<'tcx>( assert!(vtable_entries.len() >= vtable_min_entries(tcx, poly_trait_ref)); let layout = tcx - .layout_of(ty::ParamEnv::reveal_all().and(ty)) + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .expect("failed to build vtable representation"); assert!(layout.is_sized(), "can't create a vtable for an unsized type"); let size = layout.size.bytes(); @@ -117,7 +117,7 @@ pub(super) fn vtable_allocation_provider<'tcx>( let idx: u64 = u64::try_from(idx).unwrap(); let scalar = match entry { VtblEntry::MetadataDropInPlace => { - if ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) { + if ty.needs_drop(tcx, ty::TypingEnv::fully_monomorphized()) { let instance = ty::Instance::resolve_drop_in_place(tcx, ty); let fn_alloc_id = tcx.reserve_and_set_fn_alloc(instance, CTFE_ALLOC_SALT); let fn_ptr = Pointer::from(fn_alloc_id); diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs index ed27a880562..acfb78b3f6e 100644 --- a/compiler/rustc_middle/src/util/call_kind.rs +++ b/compiler/rustc_middle/src/util/call_kind.rs @@ -8,7 +8,7 @@ use rustc_span::symbol::Ident; use rustc_span::{DesugaringKind, Span, sym}; use tracing::debug; -use crate::ty::{AssocItemContainer, GenericArgsRef, Instance, ParamEnv, Ty, TyCtxt}; +use crate::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum CallDesugaringKind { @@ -62,7 +62,7 @@ pub enum CallKind<'tcx> { pub fn call_kind<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, method_did: DefId, method_args: GenericArgsRef<'tcx>, fn_call_span: Span, @@ -98,10 +98,10 @@ pub fn call_kind<'tcx>( Some(CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) }) } else if is_deref { let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { - Instance::try_resolve(tcx, param_env, deref_target, method_args).transpose() + Instance::try_resolve(tcx, typing_env, deref_target, method_args).transpose() }); if let Some(Ok(instance)) = deref_target { - let deref_target_ty = instance.ty(tcx, param_env); + let deref_target_ty = instance.ty(tcx, typing_env); Some(CallKind::DerefCoercion { deref_target: tcx.def_span(instance.def_id()), deref_target_ty, diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index 4815db47b16..e809c9a23f3 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -25,7 +25,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::*; use rustc_middle::span_bug; use rustc_middle::thir::*; -use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; mod parse; @@ -77,7 +77,7 @@ pub(super) fn build_custom_mir<'tcx>( let mut pctxt = ParseCtxt { tcx, - param_env: tcx.param_env(did), + typing_env: body.typing_env(tcx), thir, source_scope: OUTERMOST_SOURCE_SCOPE, body: &mut body, @@ -136,7 +136,7 @@ fn parse_attribute(attr: &Attribute) -> MirPhase { struct ParseCtxt<'a, 'tcx> { tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, thir: &'a Thir<'tcx>, source_scope: SourceScope, body: &'a mut Body<'tcx>, diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 07964e304b9..d08809ef67b 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -151,7 +151,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { expected: "constant pattern".to_string(), }); }; - values.push(value.eval_bits(self.tcx, self.param_env)); + values.push(value.eval_bits(self.tcx, self.typing_env)); targets.push(self.parse_block(arm.body)?); } @@ -385,7 +385,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { | ExprKind::NonHirLiteral { .. } | ExprKind::ConstBlock { .. } => Ok({ let value = as_constant_inner(expr, |_| None, self.tcx); - value.const_.eval_bits(self.tcx, self.param_env) + value.const_.eval_bits(self.tcx, self.typing_env) }), ) } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 3f2e3b956fc..640408cb9c8 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -114,8 +114,7 @@ fn lit_to_mir_constant<'tcx>( ) -> Result, LitToConstError> { let LitToConstInput { lit, ty, neg } = lit_input; let trunc = |n| { - let param_ty = ty::ParamEnv::reveal_all().and(ty); - let width = match tcx.layout_of(param_ty) { + let width = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { Ok(layout) => layout.size, Err(_) => { tcx.dcx().bug(format!("couldn't compute width of literal: {:?}", lit_input.lit)) diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index 112eac32264..aad7d54833b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -123,7 +123,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match category { Category::Constant if matches!(needs_temporary, NeedsTemporary::No) - || !expr.ty.needs_drop(this.tcx, this.param_env) => + || !expr.ty.needs_drop(this.tcx, this.typing_env()) => { let constant = this.as_constant(expr); block.and(Operand::Constant(Box::new(constant))) diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 1985dd3fca0..4a859e869e7 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -197,7 +197,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { { let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx); let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not)); - let layout = this.tcx.layout_of(this.param_env.and(source_expr.ty)); + let layout = + this.tcx.layout_of(this.typing_env().as_query_input(source_expr.ty)); let discr = this.temp(discr_ty, source_expr.span); this.cfg.push_assign( block, @@ -229,7 +230,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let range_val = Const::from_bits( this.tcx, range, - ty::ParamEnv::empty().and(unsigned_ty), + ty::TypingEnv::fully_monomorphized(), + unsigned_ty, ); let lit_op = this.literal_operand(expr.span, range_val); let is_bin_op = this.temp(bool_ty, expr_span); @@ -812,9 +814,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Helper to get a `-1` value of the appropriate type fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { - let param_ty = ty::ParamEnv::empty().and(ty); - let size = self.tcx.layout_of(param_ty).unwrap().size; - let literal = Const::from_bits(self.tcx, size.unsigned_int_max(), param_ty); + let typing_env = ty::TypingEnv::fully_monomorphized(); + let size = self.tcx.layout_of(typing_env.as_query_input(ty)).unwrap().size; + let literal = Const::from_bits(self.tcx, size.unsigned_int_max(), typing_env, ty); self.literal_operand(span, literal) } @@ -822,10 +824,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Helper to get the minimum value of the appropriate type fn minval_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { assert!(ty.is_signed()); - let param_ty = ty::ParamEnv::empty().and(ty); - let bits = self.tcx.layout_of(param_ty).unwrap().size.bits(); + let typing_env = ty::TypingEnv::fully_monomorphized(); + let bits = self.tcx.layout_of(typing_env.as_query_input(ty)).unwrap().size.bits(); let n = 1 << (bits - 1); - let literal = Const::from_bits(self.tcx, n, param_ty); + let literal = Const::from_bits(self.tcx, n, typing_env, ty); self.literal_operand(span, literal) } diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index dc317feb20c..0dec56d21ae 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -266,7 +266,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // that makes the call. target: expr .ty - .is_inhabited_from(this.tcx, this.parent_module, this.param_env) + .is_inhabited_from( + this.tcx, + this.parent_module, + this.infcx.typing_env(this.param_env), + ) .then_some(success), call_source: if from_hir_call { CallSource::Normal diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 76034c03b4b..02ca12028d3 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Generate better code for things that don't need to be // dropped. - if lhs_expr.ty.needs_drop(this.tcx, this.param_env) { + if lhs_expr.ty.needs_drop(this.tcx, this.typing_env()) { let rhs = unpack!(block = this.as_local_rvalue(block, rhs)); let lhs = unpack!(block = this.as_place(block, lhs)); block = diff --git a/compiler/rustc_mir_build/src/build/matches/match_pair.rs b/compiler/rustc_mir_build/src/build/matches/match_pair.rs index 6df50057ee8..fcbf84a41d9 100644 --- a/compiler/rustc_mir_build/src/build/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/build/matches/match_pair.rs @@ -214,7 +214,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> { || !v .inhabited_predicate(cx.tcx, adt_def) .instantiate(cx.tcx, args) - .apply_ignore_module(cx.tcx, cx.param_env) + .apply_ignore_module(cx.tcx, cx.infcx.typing_env(cx.param_env)) }) && (adt_def.did().is_local() || !adt_def.is_variant_list_non_exhaustive()); if irrefutable { diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 37cedd8cf5c..4f7bbc4ce3e 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -567,7 +567,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // not to add such values here. let is_covering_range = |test_case: &TestCase<'_, 'tcx>| { test_case.as_range().is_some_and(|range| { - matches!(range.contains(value, self.tcx, self.param_env), None | Some(true)) + matches!( + range.contains(value, self.tcx, self.typing_env()), + None | Some(true) + ) }) }; let is_conflicting_candidate = |candidate: &&mut Candidate<'_, 'tcx>| { @@ -584,7 +587,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None } else { fully_matched = true; - let bits = value.eval_bits(self.tcx, self.param_env); + let bits = value.eval_bits(self.tcx, self.typing_env()); Some(TestBranch::Constant(value, bits)) } } @@ -596,7 +599,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fully_matched = false; let not_contained = sorted_candidates.keys().filter_map(|br| br.as_constant()).copied().all( - |val| matches!(range.contains(val, self.tcx, self.param_env), Some(false)), + |val| { + matches!(range.contains(val, self.tcx, self.typing_env()), Some(false)) + }, ); not_contained.then(|| { @@ -608,7 +613,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { (TestKind::If, TestCase::Constant { value }) => { fully_matched = true; - let value = value.try_eval_bool(self.tcx, self.param_env).unwrap_or_else(|| { + let value = value.try_eval_bool(self.tcx, self.typing_env()).unwrap_or_else(|| { span_bug!(test.span, "expected boolean value but got {value:?}") }); Some(if value { TestBranch::Success } else { TestBranch::Failure }) @@ -688,7 +693,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fully_matched = false; // If the testing range does not overlap with pattern range, // the pattern can be matched only if this test fails. - if !test.overlaps(pat, self.tcx, self.param_env)? { + if !test.overlaps(pat, self.tcx, self.typing_env())? { Some(TestBranch::Failure) } else { None @@ -697,7 +702,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } (TestKind::Range(range), &TestCase::Constant { value }) => { fully_matched = false; - if !range.contains(value, self.tcx, self.param_env)? { + if !range.contains(value, self.tcx, self.typing_env())? { // `value` is not contained in the testing range, // so `value` can be matched only if this test fails. Some(TestBranch::Failure) diff --git a/compiler/rustc_mir_build/src/build/misc.rs b/compiler/rustc_mir_build/src/build/misc.rs index 53cb99d44e8..a14dcad6573 100644 --- a/compiler/rustc_mir_build/src/build/misc.rs +++ b/compiler/rustc_mir_build/src/build/misc.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Returns a zero literal operand for the appropriate type, works for /// bool, char and integers. pub(crate) fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { - let literal = Const::from_bits(self.tcx, 0, ty::ParamEnv::empty().and(ty)); + let literal = Const::from_bits(self.tcx, 0, ty::TypingEnv::fully_monomorphized(), ty); self.literal_operand(span, literal) } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 46be2aee637..cf8dc597b7b 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -230,6 +230,10 @@ struct Capture<'tcx> { } impl<'a, 'tcx> Builder<'a, 'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.infcx.typing_env(self.param_env) + } + fn is_bound_var_in_guard(&self, id: LocalVarId) -> bool { self.guard_context.iter().any(|frame| frame.locals.iter().any(|local| local.id == id)) } diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index a7e56b8f589..e63fbeeac66 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -1010,7 +1010,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { let needs_drop = match drop_kind { DropKind::Value => { - if !self.local_decls[local].ty.needs_drop(self.tcx, self.param_env) { + if !self.local_decls[local].ty.needs_drop(self.tcx, self.typing_env()) { return; } true diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 33e194fa246..da6b52ce0b8 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -566,7 +566,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { && adt_def.is_union() { if let Some(assigned_ty) = self.assignment_info { - if assigned_ty.needs_drop(self.tcx, self.param_env) { + if assigned_ty + .needs_drop(self.tcx, ty::TypingEnv::from_param_env(self.param_env)) + { // This would be unsafe, but should be outright impossible since we // reject such unions. assert!( diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 00f65e0c7d0..62c6d85b73f 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -528,7 +528,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo } if let ty::Ref(_, sub_ty, _) = self.ty.kind() { - if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.param_env) { + if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env()) { diag.note(fluent::mir_build_reference_note); } } diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index cb9a4e2604e..a1b75c22c4d 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -136,12 +136,17 @@ impl<'tcx> TerminatorClassifier<'tcx> for CallRecursion<'tcx> { let func_ty = func.ty(body, tcx); if let ty::FnDef(callee, args) = *func_ty.kind() { - let Ok(normalized_args) = tcx.try_normalize_erasing_regions(param_env, args) else { + let Ok(normalized_args) = + tcx.try_normalize_erasing_regions(ty::TypingEnv::from_param_env(param_env), args) + else { return false; }; - let (callee, call_args) = if let Ok(Some(instance)) = - Instance::try_resolve(tcx, param_env, callee, normalized_args) - { + let (callee, call_args) = if let Ok(Some(instance)) = Instance::try_resolve( + tcx, + ty::TypingEnv::from_param_env(param_env), + callee, + normalized_args, + ) { (instance.def_id(), instance.args) } else { (callee, normalized_args) diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index b8877a64e47..3fa0e4def82 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -2,7 +2,7 @@ use rustc_ast as ast; use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; -use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt}; +use rustc_middle::ty::{self, ScalarInt, TyCtxt}; use tracing::trace; use crate::build::parse_float_into_scalar; @@ -14,8 +14,7 @@ pub(crate) fn lit_to_const<'tcx>( let LitToConstInput { lit, ty, neg } = lit_input; let trunc = |n| { - let param_ty = ParamEnv::reveal_all().and(ty); - let width = match tcx.layout_of(param_ty) { + let width = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { Ok(layout) => layout.size, Err(_) => { tcx.dcx().bug(format!("couldn't compute width of literal: {:?}", lit_input.lit)) diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 64457031997..198fa4ffb7a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -284,10 +284,9 @@ impl<'tcx> Cx<'tcx> { let ty = adt_def.repr().discr_type(); let discr_ty = ty.to_ty(tcx); - let param_env_ty = self.param_env.and(discr_ty); let size = tcx - .layout_of(param_env_ty) - .unwrap_or_else(|e| panic!("could not compute layout for {param_env_ty:?}: {e:?}")) + .layout_of(self.typing_env().as_query_input(discr_ty)) + .unwrap_or_else(|e| panic!("could not compute layout for {discr_ty:?}: {e:?}")) .size; let (lit, overflowing) = ScalarInt::truncate_from_uint(discr_offset as u128, size); @@ -1025,7 +1024,7 @@ impl<'tcx> Cx<'tcx> { // but distinguish between &STATIC and &THREAD_LOCAL as they have different semantics Res::Def(DefKind::Static { .. }, id) => { // this is &raw for extern static or static mut, and & for other statics - let ty = self.tcx.static_ptr_ty(id); + let ty = self.tcx.static_ptr_ty(id, self.typing_env()); let temp_lifetime = self .rvalue_scopes .temporary_scope(self.region_scope_tree, expr.hir_id.local_id); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 377931e3be7..dfc180f5261 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -12,6 +12,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::thir::*; +use rustc_middle::ty::solve::Reveal; use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; use tracing::instrument; @@ -109,6 +110,17 @@ impl<'tcx> Cx<'tcx> { } } + fn typing_mode(&self) -> ty::TypingMode<'tcx> { + debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); + // FIXME(#132279): In case we're in a body, we should use a typing + // mode which reveals the opaque types defined by that body. + ty::TypingMode::non_body_analysis() + } + + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } + } + #[instrument(level = "debug", skip(self))] fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box> { pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index f222a869c03..73fcbeaef82 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -721,8 +721,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { .variant(*variant_index) .inhabited_predicate(self.tcx, *adt) .instantiate(self.tcx, args); - variant_inhabited.apply(self.tcx, cx.param_env, cx.module) - && !variant_inhabited.apply_ignore_module(self.tcx, cx.param_env) + variant_inhabited.apply(self.tcx, cx.typing_env(), cx.module) + && !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env()) } else { false }; @@ -1124,7 +1124,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( } if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() { - if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.param_env) { + if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env()) { err.note("references are always considered inhabited"); } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 82632350af5..6b462198db6 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -50,10 +50,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { struct ConstToPat<'tcx> { span: Span, - param_env: ty::ParamEnv<'tcx>, // inference context used for checking `T: Structural` bounds. infcx: InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, treat_byte_string_as_slice: bool, } @@ -81,6 +81,10 @@ impl<'tcx> ConstToPat<'tcx> { self.infcx.tcx } + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.infcx.typing_env(self.param_env) + } + fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool { ty.is_structural_eq_shallow(self.infcx.tcx) } @@ -100,13 +104,14 @@ impl<'tcx> ConstToPat<'tcx> { // // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All` // instead of having this logic here - let param_env = - self.tcx().erase_regions(self.param_env).with_reveal_all_normalized(self.tcx()); + let typing_env = + self.tcx().erase_regions(self.typing_env()).with_reveal_all_normalized(self.tcx()); let uv = self.tcx().erase_regions(uv); // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - let valtree = match self.infcx.tcx.const_eval_resolve_for_typeck(param_env, uv, self.span) { + let valtree = match self.infcx.tcx.const_eval_resolve_for_typeck(typing_env, uv, self.span) + { Ok(Ok(c)) => c, Err(ErrorHandled::Reported(_, _)) => { // Let's tell the use where this failing const occurs. @@ -187,7 +192,7 @@ impl<'tcx> ConstToPat<'tcx> { .map(|(idx, (val, ty))| { let field = FieldIdx::new(idx); // Patterns can only use monomorphic types. - let ty = self.tcx().normalize_erasing_regions(self.param_env, ty); + let ty = self.tcx().normalize_erasing_regions(self.typing_env(), ty); FieldPat { field, pattern: self.valtree_to_pat(val, ty) } }) .collect() diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index ec852add94d..d17bc8566cc 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -242,7 +242,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let lo = lo.unwrap_or(PatRangeBoundary::NegInfinity); let hi = hi.unwrap_or(PatRangeBoundary::PosInfinity); - let cmp = lo.compare_with(hi, ty, self.tcx, self.param_env); + let cmp = lo.compare_with(hi, ty, self.tcx, ty::TypingEnv::from_param_env(self.param_env)); let mut kind = PatKind::Range(Box::new(PatRange { lo, hi, end, ty })); match (end, cmp) { // `x..y` where `x < y`. diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 9a1f000d39d..494b7d54d8a 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -6,7 +6,6 @@ use rustc_index::Idx; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; use rustc_middle::span_bug; -use rustc_middle::traits::Reveal; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; use rustc_span::DUMMY_SP; @@ -111,7 +110,7 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug { fn patch(&mut self) -> &mut MirPatch<'tcx>; fn body(&self) -> &'a Body<'tcx>; fn tcx(&self) -> TyCtxt<'tcx>; - fn param_env(&self) -> ty::ParamEnv<'tcx>; + fn typing_env(&self) -> ty::TypingEnv<'tcx>; // Drop logic @@ -273,9 +272,9 @@ where let subpath = self.elaborator.field_subpath(variant_path, field); let tcx = self.tcx(); - assert_eq!(self.elaborator.param_env().reveal(), Reveal::All); + assert_eq!(self.elaborator.typing_env().typing_mode, ty::TypingMode::PostAnalysis); let field_ty = - tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, args)); + tcx.normalize_erasing_regions(self.elaborator.typing_env(), f.ty(tcx, args)); (tcx.mk_place_field(base_place, field, field_ty), subpath) }) @@ -372,7 +371,7 @@ where let mut fields = fields; fields.retain(|&(place, _)| { - self.place_ty(place).needs_drop(self.tcx(), self.elaborator.param_env()) + self.place_ty(place).needs_drop(self.tcx(), self.elaborator.typing_env()) }); debug!("drop_ladder - fields needing drop: {:?}", fields); @@ -544,11 +543,11 @@ where } else { have_otherwise = true; - let param_env = self.elaborator.param_env(); + let typing_env = self.elaborator.typing_env(); let have_field_with_drop_glue = variant .fields .iter() - .any(|field| field.ty(tcx, args).needs_drop(tcx, param_env)); + .any(|field| field.ty(tcx, args).needs_drop(tcx, typing_env)); if have_field_with_drop_glue { have_otherwise_with_drop_glue = true; } diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index af2d514fc76..ed8678de1eb 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -462,7 +462,7 @@ impl<'tcx> Map<'tcx> { drop(assignments); // Create values for places whose type have scalar layout. - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); + let typing_env = body.typing_env(tcx); for place_info in self.places.iter_mut() { // The user requires a bound on the number of created values. if let Some(value_limit) = value_limit @@ -471,13 +471,13 @@ impl<'tcx> Map<'tcx> { break; } - if let Ok(ty) = tcx.try_normalize_erasing_regions(param_env, place_info.ty) { + if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, place_info.ty) { place_info.ty = ty; } // Allocate a value slot if it doesn't have one, and the user requested one. assert!(place_info.value_index.is_none()); - if let Ok(layout) = tcx.layout_of(param_env.and(place_info.ty)) + if let Ok(layout) = tcx.layout_of(typing_env.as_query_input(place_info.ty)) && layout.backend_repr.is_scalar() { place_info.value_index = Some(self.value_count.into()); @@ -874,7 +874,7 @@ impl TryFrom> for TrackElem { pub fn iter_fields<'tcx>( ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, mut f: impl FnMut(Option, FieldIdx, Ty<'tcx>), ) { match ty.kind() { @@ -892,20 +892,20 @@ pub fn iter_fields<'tcx>( for (f_index, f_def) in v_def.fields.iter().enumerate() { let field_ty = f_def.ty(tcx, args); let field_ty = tcx - .try_normalize_erasing_regions(param_env, field_ty) + .try_normalize_erasing_regions(typing_env, field_ty) .unwrap_or_else(|_| tcx.erase_regions(field_ty)); f(variant, f_index.into(), field_ty); } } } ty::Closure(_, args) => { - iter_fields(args.as_closure().tupled_upvars_ty(), tcx, param_env, f); + iter_fields(args.as_closure().tupled_upvars_ty(), tcx, typing_env, f); } ty::Coroutine(_, args) => { - iter_fields(args.as_coroutine().tupled_upvars_ty(), tcx, param_env, f); + iter_fields(args.as_coroutine().tupled_upvars_ty(), tcx, typing_env, f); } ty::CoroutineClosure(_, args) => { - iter_fields(args.as_coroutine_closure().tupled_upvars_ty(), tcx, param_env, f); + iter_fields(args.as_coroutine_closure().tupled_upvars_ty(), tcx, typing_env, f); } _ => (), } diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index 559df222a50..12a2fe23b14 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -1,6 +1,6 @@ use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{self, TyCtxt}; use tracing::debug; use crate::util; @@ -40,10 +40,10 @@ pub(super) struct AddMovesForPackedDrops; impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span); - - let def_id = body.source.def_id(); let mut patch = MirPatch::new(body); - let param_env = tcx.param_env(def_id); + // FIXME(#132279): This is used during the phase transition from analysis + // to runtime, so we have to manually specify the correct typing mode. + let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id()); for (bb, data) in body.basic_blocks.iter_enumerated() { let loc = Location { block: bb, statement_index: data.statements.len() }; @@ -51,7 +51,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops { match terminator.kind { TerminatorKind::Drop { place, .. } - if util::is_disaligned(tcx, body, param_env, place) => + if util::is_disaligned(tcx, body, typing_env, place) => { add_move_for_packed_drop( tcx, diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 1922d4fef25..e9b85ba6e9d 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -9,9 +9,9 @@ pub(super) struct CheckPackedRef; impl<'tcx> crate::MirLint<'tcx> for CheckPackedRef { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { - let param_env = tcx.param_env(body.source.def_id()); + let typing_env = body.typing_env(tcx); let source_info = SourceInfo::outermost(body.span); - let mut checker = PackedRefChecker { body, tcx, param_env, source_info }; + let mut checker = PackedRefChecker { body, tcx, typing_env, source_info }; checker.visit_body(body); } } @@ -19,7 +19,7 @@ impl<'tcx> crate::MirLint<'tcx> for CheckPackedRef { struct PackedRefChecker<'a, 'tcx> { body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, source_info: SourceInfo, } @@ -37,7 +37,8 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { } fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { - if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.param_env, *place) { + if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.typing_env, *place) + { let def_id = self.body.source.instance.def_id(); if let Some(impl_def_id) = self.tcx.impl_of_method(def_id) && self.tcx.is_builtin_derived(impl_def_id) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index c2666caa1e8..d38a1dd11dc 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1069,11 +1069,9 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Note that `elaborate_drops` only drops the upvars of a coroutine, and // this is ok because `open_drop` can only be reached within that own // coroutine's resume function. + let typing_env = body.typing_env(tcx); - let def_id = body.source.def_id(); - let param_env = tcx.param_env(def_id); - - let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env }; + let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, typing_env }; for (block, block_data) in body.basic_blocks.iter_enumerated() { let (target, unwind, source_info) = match block_data.terminator() { @@ -1204,9 +1202,9 @@ fn insert_panic_block<'tcx>( insert_term_block(body, kind) } -fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { +fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool { // Returning from a function with an uninhabited return type is undefined behavior. - if body.return_ty().is_privately_uninhabited(tcx, param_env) { + if body.return_ty().is_privately_uninhabited(tcx, typing_env) { return false; } @@ -1627,7 +1625,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { // `storage_liveness` tells us which locals have live storage at suspension points let (remap, layout, storage_liveness) = compute_layout(liveness_info, body); - let can_return = can_return(tcx, body, tcx.param_env(body.source.def_id())); + let can_return = can_return(tcx, body, body.typing_env(tcx)); // Run the transformation which converts Places from Local to coroutine struct // accesses for locals in `remap`. diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs index 59b403538a3..b23d8b9e737 100644 --- a/compiler/rustc_mir_transform/src/cost_checker.rs +++ b/compiler/rustc_mir_transform/src/cost_checker.rs @@ -1,7 +1,7 @@ use rustc_middle::bug; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; const INSTR_COST: usize = 5; const CALL_PENALTY: usize = 25; @@ -14,7 +14,7 @@ const CONST_SWITCH_BONUS: usize = 10; #[derive(Clone)] pub(super) struct CostChecker<'b, 'tcx> { tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, penalty: usize, bonus: usize, callee_body: &'b Body<'tcx>, @@ -24,11 +24,11 @@ pub(super) struct CostChecker<'b, 'tcx> { impl<'b, 'tcx> CostChecker<'b, 'tcx> { pub(super) fn new( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, instance: Option>, callee_body: &'b Body<'tcx>, ) -> CostChecker<'b, 'tcx> { - CostChecker { tcx, param_env, callee_body, instance, penalty: 0, bonus: 0 } + CostChecker { tcx, typing_env, callee_body, instance, penalty: 0, bonus: 0 } } /// Add function-level costs not well-represented by the block-level costs. @@ -119,7 +119,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { TerminatorKind::Drop { place, unwind, .. } => { // If the place doesn't actually need dropping, treat it like a regular goto. let ty = self.instantiate_ty(place.ty(self.callee_body, self.tcx).ty); - if ty.needs_drop(self.tcx, self.param_env) { + if ty.needs_drop(self.tcx, self.typing_env) { self.penalty += CALL_PENALTY; if let UnwindAction::Cleanup(_) = unwind { self.penalty += LANDINGPAD_PENALTY; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index ab6460c490b..500515bc3cc 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -16,7 +16,7 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::fmt::DebugWithContext; use rustc_mir_dataflow::lattice::{FlatSet, HasBottom}; @@ -82,7 +82,7 @@ struct ConstAnalysis<'a, 'tcx> { tcx: TyCtxt<'tcx>, local_decls: &'a LocalDecls<'tcx>, ecx: InterpCx<'tcx, DummyMachine>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, } impl<'tcx> Analysis<'tcx> for ConstAnalysis<'_, 'tcx> { @@ -144,13 +144,13 @@ impl<'tcx> Analysis<'tcx> for ConstAnalysis<'_, 'tcx> { impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map<'tcx>) -> Self { - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); + let typing_env = body.typing_env(tcx); Self { map, tcx, local_decls: &body.local_decls, - ecx: InterpCx::new(tcx, DUMMY_SP, param_env, DummyMachine), - param_env, + ecx: InterpCx::new(tcx, DUMMY_SP, typing_env.param_env, DummyMachine), + typing_env, } } @@ -389,7 +389,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { && let Some(operand_ty) = operand_ty.builtin_deref(true) && let ty::Array(_, len) = operand_ty.kind() && let Some(len) = Const::Ty(self.tcx.types.usize, *len) - .try_eval_scalar_int(self.tcx, self.param_env) + .try_eval_scalar_int(self.tcx, self.typing_env) { state.insert_value_idx(target_len, FlatSet::Elem(len.into()), &self.map); } @@ -411,7 +411,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { let place_ty = place.ty(self.local_decls, self.tcx); if let ty::Array(_, len) = place_ty.ty.kind() { Const::Ty(self.tcx.types.usize, *len) - .try_eval_scalar(self.tcx, self.param_env) + .try_eval_scalar(self.tcx, self.typing_env) .map_or(FlatSet::Top, FlatSet::Elem) } else if let [ProjectionElem::Deref] = place.projection[..] { state.get_len(place.local.into(), &self.map) @@ -420,7 +420,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { } } Rvalue::Cast(CastKind::IntToInt | CastKind::IntToFloat, operand, ty) => { - let Ok(layout) = self.tcx.layout_of(self.param_env.and(*ty)) else { + let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(*ty)) else { return ValueOrPlace::Value(FlatSet::Top); }; match self.eval_operand(operand, state) { @@ -434,7 +434,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { } } Rvalue::Cast(CastKind::FloatToInt | CastKind::FloatToFloat, operand, ty) => { - let Ok(layout) = self.tcx.layout_of(self.param_env.and(*ty)) else { + let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(*ty)) else { return ValueOrPlace::Value(FlatSet::Top); }; match self.eval_operand(operand, state) { @@ -470,7 +470,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { FlatSet::Top => FlatSet::Top, }, Rvalue::NullaryOp(null_op, ty) => { - let Ok(layout) = self.tcx.layout_of(self.param_env.and(*ty)) else { + let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(*ty)) else { return ValueOrPlace::Value(FlatSet::Top); }; let val = match null_op { @@ -479,7 +479,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { NullOp::OffsetOf(fields) => self .ecx .tcx - .offset_of_subfield(self.ecx.param_env(), layout, fields.iter()) + .offset_of_subfield(self.typing_env, layout, fields.iter()) .bytes(), _ => return ValueOrPlace::Value(FlatSet::Top), }; @@ -514,7 +514,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { ) -> FlatSet { constant .const_ - .try_eval_scalar(self.tcx, self.param_env) + .try_eval_scalar(self.tcx, self.typing_env) .map_or(FlatSet::Top, FlatSet::Elem) } @@ -554,7 +554,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { } else if rhs.projection.first() == Some(&PlaceElem::Deref) && let FlatSet::Elem(pointer) = state.get(rhs.local.into(), &self.map) && let rhs_ty = self.local_decls[rhs.local].ty - && let Ok(rhs_layout) = self.tcx.layout_of(self.param_env.and(rhs_ty)) + && let Ok(rhs_layout) = + self.tcx.layout_of(self.typing_env.as_query_input(rhs_ty)) { let op = ImmTy::from_scalar(pointer, rhs_layout).into(); self.assign_constant(state, place, op, rhs.projection); @@ -614,8 +615,10 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { TrackElem::DerefLen => { let op: OpTy<'_> = self.ecx.deref_pointer(op).discard_err()?.into(); let len_usize = op.len(&self.ecx).discard_err()?; - let layout = - self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).unwrap(); + let layout = self + .tcx + .layout_of(self.typing_env.as_query_input(self.tcx.types.usize)) + .unwrap(); Some(ImmTy::from_uint(len_usize, layout).into()) } }, @@ -702,9 +705,11 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { FlatSet::Top => FlatSet::Top, FlatSet::Elem(scalar) => { let ty = op.ty(self.local_decls, self.tcx); - self.tcx.layout_of(self.param_env.and(ty)).map_or(FlatSet::Top, |layout| { - FlatSet::Elem(ImmTy::from_scalar(scalar, layout)) - }) + self.tcx + .layout_of(self.typing_env.as_query_input(ty)) + .map_or(FlatSet::Top, |layout| { + FlatSet::Elem(ImmTy::from_scalar(scalar, layout)) + }) } FlatSet::Bottom => FlatSet::Bottom, } @@ -714,7 +719,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { if !enum_ty.is_enum() { return None; } - let enum_ty_layout = self.tcx.layout_of(self.param_env.and(enum_ty)).ok()?; + let enum_ty_layout = self.tcx.layout_of(self.typing_env.as_query_input(enum_ty)).ok()?; let discr_value = self.ecx.discriminant_for_variant(enum_ty_layout.ty, variant_index).discard_err()?; Some(discr_value.to_scalar()) diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs index 753bae8e156..db72ec522a2 100644 --- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs +++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs @@ -198,7 +198,7 @@ pub(super) fn deduced_param_attrs<'tcx>( // see [1]. // // [1]: https://github.com/rust-lang/rust/pull/103172#discussion_r999139997 - let param_env = tcx.param_env_reveal_all_normalized(def_id); + let typing_env = body.typing_env(tcx); let mut deduced_param_attrs = tcx.arena.alloc_from_iter( body.local_decls.iter().skip(1).take(body.arg_count).enumerate().map( |(arg_index, local_decl)| DeducedParamAttrs { @@ -207,8 +207,8 @@ pub(super) fn deduced_param_attrs<'tcx>( // their generic parameters, otherwise we'll see exponential // blow-up in compile times: #113372 && tcx - .normalize_erasing_regions(param_env, local_decl.ty) - .is_freeze(tcx, param_env), + .normalize_erasing_regions(typing_env, local_decl.ty) + .is_freeze(tcx, typing_env.param_env), }, ), ); diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 74572100db3..b0f041d8722 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -3,6 +3,7 @@ use std::fmt; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_index::IndexVec; use rustc_index::bit_set::BitSet; +use rustc_infer::traits::Reveal; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; @@ -53,14 +54,14 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops { #[instrument(level = "trace", skip(self, tcx, body))] fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { debug!("elaborate_drops({:?} @ {:?})", body.source, body.span); - - let def_id = body.source.def_id(); - let param_env = tcx.param_env_reveal_all_normalized(def_id); + // FIXME(#132279): This is used during the phase transition from analysis + // to runtime, so we have to manually specify the correct typing mode. + let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id()); // For types that do not need dropping, the behaviour is trivial. So we only need to track // init/uninit for types that do need dropping. - let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, param_env)); + let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, typing_env)); let elaborate_patch = { - let env = MoveDataParamEnv { move_data, param_env }; + let env = MoveDataParamEnv { move_data, param_env: typing_env.param_env }; let mut inits = MaybeInitializedPlaces::new(tcx, body, &env.move_data) .skipping_unreachable_unwind() @@ -147,8 +148,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> { self.tcx } - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env() + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.typing_env() } #[instrument(level = "debug", skip(self), ret)] @@ -250,6 +251,11 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { self.env.param_env } + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + debug_assert_eq!(self.param_env().reveal(), Reveal::All); + ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env() } + } + fn create_drop_flag(&mut self, index: MovePathIndex, span: Span) { let patch = &mut self.patch; debug!("create_drop_flag({:?})", self.body.span); @@ -335,7 +341,7 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { if !place .ty(&self.body.local_decls, self.tcx) .ty - .needs_drop(self.tcx, self.env.param_env) + .needs_drop(self.tcx, self.typing_env()) { self.patch.patch_terminator(bb, TerminatorKind::Goto { target }); continue; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 274eea9563f..27fe0ad72e7 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -100,7 +100,7 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::GlobalAlloc; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; @@ -295,6 +295,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } } + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env } + } + #[instrument(level = "trace", skip(self), ret)] fn insert(&mut self, value: Value<'tcx>) -> VnIndex { let (index, new) = self.values.insert_full(value); @@ -531,7 +535,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { NullOp::OffsetOf(fields) => self .ecx .tcx - .offset_of_subfield(self.ecx.param_env(), layout, fields.iter()) + .offset_of_subfield(self.typing_env(), layout, fields.iter()) .bytes(), NullOp::UbChecks => return None, }; @@ -1476,8 +1480,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { if left_meta_ty == right_meta_ty { true } else if let Ok(left) = - self.tcx.try_normalize_erasing_regions(self.param_env, left_meta_ty) - && let Ok(right) = self.tcx.try_normalize_erasing_regions(self.param_env, right_meta_ty) + self.tcx.try_normalize_erasing_regions(self.typing_env(), left_meta_ty) + && let Ok(right) = + self.tcx.try_normalize_erasing_regions(self.typing_env(), right_meta_ty) { left == right } else { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index e95ab4ffe16..fcb51fbddd9 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -13,9 +13,7 @@ use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::{ - self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt, TypeFlags, TypeVisitableExt, -}; +use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; use rustc_session::config::{DebugInfo, OptLevel}; use rustc_span::source_map::Spanned; use rustc_span::sym; @@ -94,12 +92,12 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { return false; } - let param_env = tcx.param_env_reveal_all_normalized(def_id); + let typing_env = body.typing_env(tcx); let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id); let mut this = Inliner { tcx, - param_env, + typing_env, codegen_fn_attrs, history: Vec::new(), changed: false, @@ -115,7 +113,7 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { struct Inliner<'tcx> { tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, /// Caller codegen attributes. codegen_fn_attrs: &'tcx CodegenFnAttrs, /// Stack of inlined instances. @@ -201,7 +199,11 @@ impl<'tcx> Inliner<'tcx> { let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() }; let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty; for arg in args { - if !arg.node.ty(&caller_body.local_decls, self.tcx).is_sized(self.tcx, self.param_env) { + if !arg + .node + .ty(&caller_body.local_decls, self.tcx) + .is_sized(self.tcx, self.typing_env.param_env) + { // We do not allow inlining functions with unsized params. Inlining these functions // could create unsized locals, which are unsound and being phased out. return Err("Call has unsized argument"); @@ -219,7 +221,7 @@ impl<'tcx> Inliner<'tcx> { let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions( self.tcx, - self.param_env, + self.typing_env, ty::EarlyBinder::bind(callee_body.clone()), ) else { return Err("failed to normalize callee body"); @@ -230,7 +232,7 @@ impl<'tcx> Inliner<'tcx> { if !validate_types( self.tcx, MirPhase::Runtime(RuntimePhase::Optimized), - self.param_env, + self.typing_env, &callee_body, &caller_body, ) @@ -243,13 +245,7 @@ impl<'tcx> Inliner<'tcx> { // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. let output_type = callee_body.return_ty(); - if !util::sub_types( - self.tcx, - caller_body.typing_mode(self.tcx), - self.param_env, - output_type, - destination_ty, - ) { + if !util::sub_types(self.tcx, self.typing_env, output_type, destination_ty) { trace!(?output_type, ?destination_ty); return Err("failed to normalize return type"); } @@ -279,13 +275,7 @@ impl<'tcx> Inliner<'tcx> { self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; - if !util::sub_types( - self.tcx, - caller_body.typing_mode(self.tcx), - self.param_env, - input_type, - arg_ty, - ) { + if !util::sub_types(self.tcx, self.typing_env, input_type, arg_ty) { trace!(?arg_ty, ?input_type); return Err("failed to normalize tuple argument type"); } @@ -294,13 +284,7 @@ impl<'tcx> Inliner<'tcx> { for (arg, input) in args.iter().zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx); - if !util::sub_types( - self.tcx, - caller_body.typing_mode(self.tcx), - self.param_env, - input_type, - arg_ty, - ) { + if !util::sub_types(self.tcx, self.typing_env, input_type, arg_ty) { trace!(?arg_ty, ?input_type); return Err("failed to normalize argument type"); } @@ -402,9 +386,10 @@ impl<'tcx> Inliner<'tcx> { let func_ty = func.ty(caller_body, self.tcx); if let ty::FnDef(def_id, args) = *func_ty.kind() { // To resolve an instance its args have to be fully normalized. - let args = self.tcx.try_normalize_erasing_regions(self.param_env, args).ok()?; - let callee = - Instance::try_resolve(self.tcx, self.param_env, def_id, args).ok().flatten()?; + let args = self.tcx.try_normalize_erasing_regions(self.typing_env, args).ok()?; + let callee = Instance::try_resolve(self.tcx, self.typing_env, def_id, args) + .ok() + .flatten()?; if let InstanceKind::Virtual(..) | InstanceKind::Intrinsic(_) = callee.def { return None; @@ -528,7 +513,7 @@ impl<'tcx> Inliner<'tcx> { // FIXME: Give a bonus to functions with only a single caller let mut checker = - CostChecker::new(self.tcx, self.param_env, Some(callsite.callee), callee_body); + CostChecker::new(self.tcx, self.typing_env, Some(callsite.callee), callee_body); checker.add_function_level_costs(); @@ -552,7 +537,7 @@ impl<'tcx> Inliner<'tcx> { self.tcx, ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty), ); - if ty.needs_drop(tcx, self.param_env) + if ty.needs_drop(tcx, self.typing_env) && let UnwindAction::Cleanup(unwind) = unwind { work_list.push(unwind); diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 9828e90de88..a40768300f5 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -15,7 +15,6 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( (root, target): (ty::Instance<'tcx>, LocalDefId), ) -> bool { trace!(%root, target = %tcx.def_path_str(target)); - let param_env = tcx.param_env_reveal_all_normalized(target); assert_ne!( root.def_id().expect_local(), target, @@ -31,11 +30,11 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( ); #[instrument( level = "debug", - skip(tcx, param_env, target, stack, seen, recursion_limiter, caller, recursion_limit) + skip(tcx, typing_env, target, stack, seen, recursion_limiter, caller, recursion_limit) )] fn process<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, caller: ty::Instance<'tcx>, target: LocalDefId, stack: &mut Vec>, @@ -47,13 +46,13 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( for &(callee, args) in tcx.mir_inliner_callees(caller.def) { let Ok(args) = caller.try_instantiate_mir_and_normalize_erasing_regions( tcx, - param_env, + typing_env, ty::EarlyBinder::bind(args), ) else { - trace!(?caller, ?param_env, ?args, "cannot normalize, skipping"); + trace!(?caller, ?typing_env, ?args, "cannot normalize, skipping"); continue; }; - let Ok(Some(callee)) = ty::Instance::try_resolve(tcx, param_env, callee, args) else { + let Ok(Some(callee)) = ty::Instance::try_resolve(tcx, typing_env, callee, args) else { trace!(?callee, "cannot resolve, skipping"); continue; }; @@ -115,7 +114,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( let found_recursion = ensure_sufficient_stack(|| { process( tcx, - param_env, + typing_env, callee, target, stack, @@ -146,7 +145,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( let recursion_limit = tcx.recursion_limit() / 2; process( tcx, - param_env, + ty::TypingEnv::post_analysis(tcx, target), root, target, &mut Vec::new(), diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 9471c1b2a9a..b80abcca969 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -69,6 +69,12 @@ struct InstSimplifyContext<'a, 'tcx> { param_env: ParamEnv<'tcx>, } +impl<'tcx> InstSimplifyContext<'_, 'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env } + } +} + impl<'tcx> InstSimplifyContext<'_, 'tcx> { fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool { self.should_simplify_custom(source_info, "Rvalue", rvalue) @@ -348,7 +354,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { } let known_is_valid = - intrinsic_assert_panics(self.tcx, self.param_env, args[0], intrinsic_name); + intrinsic_assert_panics(self.tcx, self.typing_env(), args[0], intrinsic_name); match known_is_valid { // We don't know the layout or it's not validity assertion at all, don't touch it None => {} @@ -366,13 +372,13 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { fn intrinsic_assert_panics<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, arg: ty::GenericArg<'tcx>, intrinsic_name: Symbol, ) -> Option { let requirement = ValidityRequirement::from_intrinsic(intrinsic_name)?; let ty = arg.expect_ty(); - Some(!tcx.check_validity_requirement((requirement, param_env.and(ty))).ok()?) + Some(!tcx.check_validity_requirement((requirement, typing_env.as_query_input(ty))).ok()?) } fn resolve_rust_intrinsic<'tcx>( diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 3772589ac4e..71a843a785c 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -77,13 +77,12 @@ impl<'tcx> crate::MirPass<'tcx> for JumpThreading { return; } - let param_env = tcx.param_env_reveal_all_normalized(def_id); - + let typing_env = body.typing_env(tcx); let arena = &DroplessArena::default(); let mut finder = TOFinder { tcx, - param_env, - ecx: InterpCx::new(tcx, DUMMY_SP, param_env, DummyMachine), + typing_env, + ecx: InterpCx::new(tcx, DUMMY_SP, typing_env.param_env, DummyMachine), body, arena, map: Map::new(tcx, body, Some(MAX_PLACES)), @@ -119,7 +118,7 @@ struct ThreadingOpportunity { struct TOFinder<'a, 'tcx> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ecx: InterpCx<'tcx, DummyMachine>, body: &'a Body<'tcx>, map: Map<'tcx>, @@ -207,7 +206,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { let Some(discr) = self.map.find(discr.as_ref()) else { return }; debug!(?discr); - let cost = CostChecker::new(self.tcx, self.param_env, None, self.body); + let cost = CostChecker::new(self.tcx, self.typing_env, None, self.body); let mut state = State::new_reachable(); let conds = if let Some((value, then, else_)) = targets.as_static_if() { @@ -528,7 +527,8 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { // Avoid handling them, though this could be extended in the future. return; } - let Some(value) = value.const_.try_eval_scalar_int(self.tcx, self.param_env) else { + let Some(value) = value.const_.try_eval_scalar_int(self.tcx, self.typing_env) + else { return; }; let conds = conditions.map(self.arena, |c| Condition { diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 0604665642a..3911b0a2db6 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -18,7 +18,7 @@ use rustc_middle::bug; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; -use rustc_middle::ty::{self, ConstInt, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, ConstInt, ScalarInt, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::Span; use tracing::{debug, instrument, trace}; @@ -65,7 +65,7 @@ impl<'tcx> crate::MirLint<'tcx> for KnownPanicsLint { struct ConstPropagator<'mir, 'tcx> { ecx: InterpCx<'tcx, DummyMachine>, tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, worklist: Vec, visited_blocks: BitSet, locals: IndexVec>, @@ -169,25 +169,26 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for ConstPropagator<'_, 'tcx> { } } -impl<'tcx> ty::layout::HasParamEnv<'tcx> for ConstPropagator<'_, 'tcx> { +impl<'tcx> ty::layout::HasTypingEnv<'tcx> for ConstPropagator<'_, 'tcx> { #[inline] - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.typing_env } } impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn new(body: &'mir Body<'tcx>, tcx: TyCtxt<'tcx>) -> ConstPropagator<'mir, 'tcx> { let def_id = body.source.def_id(); - let param_env = tcx.param_env_reveal_all_normalized(def_id); - - let can_const_prop = CanConstProp::check(tcx, param_env, body); - let ecx = InterpCx::new(tcx, tcx.def_span(def_id), param_env, DummyMachine); + // FIXME(#132279): This is used during the phase transition from analysis + // to runtime, so we have to manually specify the correct typing mode. + let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id()); + let can_const_prop = CanConstProp::check(tcx, typing_env, body); + let ecx = InterpCx::new(tcx, tcx.def_span(def_id), typing_env.param_env, DummyMachine); ConstPropagator { ecx, tcx, - param_env, + typing_env, worklist: vec![START_BLOCK], visited_blocks: BitSet::new_empty(body.basic_blocks.len()), locals: IndexVec::from_elem_n(Value::Uninit, body.local_decls.len()), @@ -260,7 +261,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // that the `RevealAll` pass has happened and that the body's consts // are normalized, so any call to resolve before that needs to be // manually normalized. - let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.const_).ok()?; + let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?; self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))? .as_mplace_or_imm() @@ -450,7 +451,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { if rvalue.has_param() { return None; } - if !rvalue.ty(self.local_decls(), self.tcx).is_sized(self.tcx, self.param_env) { + if !rvalue.ty(self.local_decls(), self.tcx).is_sized(self.tcx, self.typing_env.param_env) { // the interpreter doesn't support unsized locals (only unsized arguments), // but rustc does (in a kinda broken way), so we have to skip them here return None; @@ -622,7 +623,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { NullOp::AlignOf => op_layout.align.abi.bytes(), NullOp::OffsetOf(fields) => self .tcx - .offset_of_subfield(self.param_env, op_layout, fields.iter()) + .offset_of_subfield(self.typing_env, op_layout, fields.iter()) .bytes(), NullOp::UbChecks => return None, }; @@ -873,7 +874,7 @@ impl CanConstProp { /// Returns true if `local` can be propagated fn check<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, body: &Body<'tcx>, ) -> IndexVec { let mut cpv = CanConstProp { @@ -888,7 +889,7 @@ impl CanConstProp { // variant of a union *val = ConstPropMode::NoPropagation; } else { - match tcx.layout_of(param_env.and(ty)) { + match tcx.layout_of(typing_env.as_query_input(ty)) { Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {} // Either the layout fails to compute, then we can't use this local anyway // or the local is too large, then we don't want to. diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index fa659a56a27..8be5a63d008 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -3,7 +3,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::*; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, AdtDef, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_session::Session; /// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large @@ -39,8 +39,7 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { // platform, but it will still be valid. let mut alloc_cache = FxHashMap::default(); - let body_did = body.source.def_id(); - let param_env = tcx.param_env_reveal_all_normalized(body_did); + let typing_env = body.typing_env(tcx); let blocks = body.basic_blocks.as_mut(); let local_decls = &mut body.local_decls; @@ -58,7 +57,7 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { let ty = lhs.ty(local_decls, tcx).ty; let (adt_def, num_variants, alloc_id) = - self.candidate(tcx, param_env, ty, &mut alloc_cache)?; + self.candidate(tcx, typing_env, ty, &mut alloc_cache)?; let source_info = st.source_info; let span = source_info.span; @@ -207,7 +206,7 @@ impl EnumSizeOpt { fn candidate<'tcx>( &self, tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, alloc_cache: &mut FxHashMap, AllocId>, ) -> Option<(AdtDef<'tcx>, usize, AllocId)> { @@ -215,7 +214,7 @@ impl EnumSizeOpt { ty::Adt(adt_def, _args) if adt_def.is_enum() => adt_def, _ => return None, }; - let layout = tcx.layout_of(param_env.and(ty)).ok()?; + let layout = tcx.layout_of(typing_env.as_query_input(ty)).ok()?; let variants = match &layout.variants { Variants::Single { .. } => return None, Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => return None, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index d2d5facbbdc..5651bf469d5 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -333,10 +333,14 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { } fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { - let const_kind = tcx.hir().body_const_context(def); - + // N.B., this `borrow()` is guaranteed to be valid (i.e., the value + // cannot yet be stolen), because `mir_promoted()`, which steals + // from `mir_built()`, forces this query to execute before + // performing the steal. + let body = &tcx.mir_built(def).borrow(); + let ccx = check_consts::ConstCx::new(tcx, body); // No need to const-check a non-const `fn`. - match const_kind { + match ccx.const_kind { Some(ConstContext::Const { .. } | ConstContext::Static(_) | ConstContext::ConstFn) => {} None => span_bug!( tcx.def_span(def), @@ -344,20 +348,12 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { ), } - // N.B., this `borrow()` is guaranteed to be valid (i.e., the value - // cannot yet be stolen), because `mir_promoted()`, which steals - // from `mir_built()`, forces this query to execute before - // performing the steal. - let body = &tcx.mir_built(def).borrow(); - if body.return_ty().references_error() { // It's possible to reach here without an error being emitted (#121103). tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors"); return Default::default(); } - let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def) }; - let mut validator = check_consts::check::Checker::new(&ccx); validator.check_body(); diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index 237227f5294..ff027680c49 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -5,7 +5,7 @@ use rustc_index::IndexSlice; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; -use rustc_middle::ty::{ParamEnv, ScalarInt, Ty, TyCtxt}; +use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_type_ir::TyKind::*; use super::simplify::simplify_cfg; @@ -19,8 +19,7 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let def_id = body.source.def_id(); - let param_env = tcx.param_env_reveal_all_normalized(def_id); - + let typing_env = body.typing_env(tcx); let mut should_cleanup = false; for i in 0..body.basic_blocks.len() { let bbs = &*body.basic_blocks; @@ -40,11 +39,11 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification { _ => continue, }; - if SimplifyToIf.simplify(tcx, body, bb_idx, param_env).is_some() { + if SimplifyToIf.simplify(tcx, body, bb_idx, typing_env).is_some() { should_cleanup = true; continue; } - if SimplifyToExp::default().simplify(tcx, body, bb_idx, param_env).is_some() { + if SimplifyToExp::default().simplify(tcx, body, bb_idx, typing_env).is_some() { should_cleanup = true; continue; } @@ -65,7 +64,7 @@ trait SimplifyMatch<'tcx> { tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, switch_bb_idx: BasicBlock, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> Option<()> { let bbs = &body.basic_blocks; let (discr, targets) = match bbs[switch_bb_idx].terminator().kind { @@ -74,7 +73,7 @@ trait SimplifyMatch<'tcx> { }; let discr_ty = discr.ty(body.local_decls(), tcx); - self.can_simplify(tcx, targets, param_env, bbs, discr_ty)?; + self.can_simplify(tcx, targets, typing_env, bbs, discr_ty)?; let mut patch = MirPatch::new(body); @@ -90,7 +89,16 @@ trait SimplifyMatch<'tcx> { let parent_end = Location { block: switch_bb_idx, statement_index }; patch.add_statement(parent_end, StatementKind::StorageLive(discr_local)); patch.add_assign(parent_end, Place::from(discr_local), Rvalue::Use(discr)); - self.new_stmts(tcx, targets, param_env, &mut patch, parent_end, bbs, discr_local, discr_ty); + self.new_stmts( + tcx, + targets, + typing_env, + &mut patch, + parent_end, + bbs, + discr_local, + discr_ty, + ); patch.add_statement(parent_end, StatementKind::StorageDead(discr_local)); patch.patch_terminator(switch_bb_idx, bbs[first].terminator().kind.clone()); patch.apply(body); @@ -104,7 +112,7 @@ trait SimplifyMatch<'tcx> { &mut self, tcx: TyCtxt<'tcx>, targets: &SwitchTargets, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, bbs: &IndexSlice>, discr_ty: Ty<'tcx>, ) -> Option<()>; @@ -113,7 +121,7 @@ trait SimplifyMatch<'tcx> { &self, tcx: TyCtxt<'tcx>, targets: &SwitchTargets, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, patch: &mut MirPatch<'tcx>, parent_end: Location, bbs: &IndexSlice>, @@ -160,7 +168,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf { &mut self, tcx: TyCtxt<'tcx>, targets: &SwitchTargets, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, bbs: &IndexSlice>, _discr_ty: Ty<'tcx>, ) -> Option<()> { @@ -197,8 +205,8 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf { ) if lhs_f == lhs_s && f_c.const_.ty().is_bool() && s_c.const_.ty().is_bool() - && f_c.const_.try_eval_bool(tcx, param_env).is_some() - && s_c.const_.try_eval_bool(tcx, param_env).is_some() => {} + && f_c.const_.try_eval_bool(tcx, typing_env).is_some() + && s_c.const_.try_eval_bool(tcx, typing_env).is_some() => {} // Otherwise we cannot optimize. Try another block. _ => return None, @@ -211,7 +219,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf { &self, tcx: TyCtxt<'tcx>, targets: &SwitchTargets, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, patch: &mut MirPatch<'tcx>, parent_end: Location, bbs: &IndexSlice>, @@ -235,15 +243,15 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf { StatementKind::Assign(box (_, Rvalue::Use(Operand::Constant(s_c)))), ) => { // From earlier loop we know that we are dealing with bool constants only: - let f_b = f_c.const_.try_eval_bool(tcx, param_env).unwrap(); - let s_b = s_c.const_.try_eval_bool(tcx, param_env).unwrap(); + let f_b = f_c.const_.try_eval_bool(tcx, typing_env).unwrap(); + let s_b = s_c.const_.try_eval_bool(tcx, typing_env).unwrap(); if f_b == s_b { // Same value in both blocks. Use statement as is. patch.add_statement(parent_end, f.kind.clone()); } else { // Different value between blocks. Make value conditional on switch // condition. - let size = tcx.layout_of(param_env.and(discr_ty)).unwrap().size; + let size = tcx.layout_of(typing_env.as_query_input(discr_ty)).unwrap().size; let const_cmp = Operand::const_from_scalar( tcx, discr_ty, @@ -363,7 +371,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { &mut self, tcx: TyCtxt<'tcx>, targets: &SwitchTargets, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, bbs: &IndexSlice>, discr_ty: Ty<'tcx>, ) -> Option<()> { @@ -388,7 +396,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { return None; } - let discr_layout = tcx.layout_of(param_env.and(discr_ty)).unwrap(); + let discr_layout = tcx.layout_of(typing_env.as_query_input(discr_ty)).unwrap(); let first_stmts = &bbs[first_target].statements; let (second_case_val, second_target) = target_iter.next().unwrap(); let second_stmts = &bbs[second_target].statements; @@ -414,8 +422,8 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { && f_c.const_.ty().is_integral() => { match ( - f_c.const_.try_eval_scalar_int(tcx, param_env), - s_c.const_.try_eval_scalar_int(tcx, param_env), + f_c.const_.try_eval_scalar_int(tcx, typing_env), + s_c.const_.try_eval_scalar_int(tcx, typing_env), ) { (Some(f), Some(s)) if f == s => ExpectedTransformKind::SameByEq { place: lhs_f, @@ -467,11 +475,11 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))), ) if lhs_f == lhs_s && s_c.const_.ty() == f_ty - && s_c.const_.try_eval_scalar_int(tcx, param_env) == Some(scalar) => {} + && s_c.const_.try_eval_scalar_int(tcx, typing_env) == Some(scalar) => {} ( ExpectedTransformKind::Cast { place: lhs_f, ty: f_ty }, StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))), - ) if let Some(f) = s_c.const_.try_eval_scalar_int(tcx, param_env) + ) if let Some(f) = s_c.const_.try_eval_scalar_int(tcx, typing_env) && lhs_f == lhs_s && s_c.const_.ty() == f_ty && can_cast(tcx, other_val, discr_layout, f_ty, f) => {} @@ -487,7 +495,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { &self, _tcx: TyCtxt<'tcx>, targets: &SwitchTargets, - _param_env: ParamEnv<'tcx>, + _typing_env: ty::TypingEnv<'tcx>, patch: &mut MirPatch<'tcx>, parent_end: Location, bbs: &IndexSlice>, diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index fa9a6bfcf7c..6be95b1f0f1 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -325,7 +325,7 @@ impl<'tcx> Validator<'_, 'tcx> { if let TempState::Defined { location: loc, .. } = self.temps[local] && let Left(statement) = self.body.stmt_at(loc) && let Some((_, Rvalue::Use(Operand::Constant(c)))) = statement.kind.as_assign() - && let Some(idx) = c.const_.try_eval_target_usize(self.tcx, self.param_env) + && let Some(idx) = c.const_.try_eval_target_usize(self.tcx, self.typing_env) // Determine the type of the thing we are indexing. && let ty::Array(_, len) = place_base.ty(self.body, self.tcx).ty.kind() // It's an array; determine its length. @@ -490,7 +490,7 @@ impl<'tcx> Validator<'_, 'tcx> { // Integer division: the RHS must be a non-zero const. let rhs_val = match rhs { Operand::Constant(c) => { - c.const_.try_eval_scalar_int(self.tcx, self.param_env) + c.const_.try_eval_scalar_int(self.tcx, self.typing_env) } _ => None, }; @@ -509,7 +509,7 @@ impl<'tcx> Validator<'_, 'tcx> { let lhs_val = match lhs { Operand::Constant(c) => c .const_ - .try_eval_scalar_int(self.tcx, self.param_env), + .try_eval_scalar_int(self.tcx, self.typing_env), _ => None, }; let lhs_min = sz.signed_int_min(); diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs index 20c34a7469e..f786c676e9e 100644 --- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs @@ -1,7 +1,7 @@ use rustc_abi::FieldIdx; use rustc_index::bit_set::ChunkedBitSet; use rustc_middle::mir::{Body, TerminatorKind}; -use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, VariantDef}; +use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, VariantDef}; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; use rustc_mir_dataflow::{Analysis, MaybeReachable, move_path_children_matching}; @@ -18,8 +18,8 @@ pub(super) struct RemoveUninitDrops; impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let param_env = tcx.param_env(body.source.def_id()); - let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, param_env)); + let typing_env = body.typing_env(tcx); + let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, typing_env)); let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) .iterate_to_fixpoint(tcx, body, Some("remove_uninit_drops")) @@ -40,7 +40,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops { let should_keep = is_needs_drop_and_init( tcx, - param_env, + typing_env, maybe_inits, &move_data, place.ty(body, tcx).ty, @@ -66,24 +66,24 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops { fn is_needs_drop_and_init<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, maybe_inits: &ChunkedBitSet, move_data: &MoveData<'tcx>, ty: Ty<'tcx>, mpi: MovePathIndex, ) -> bool { // No need to look deeper if the root is definitely uninit or if it has no `Drop` impl. - if !maybe_inits.contains(mpi) || !ty.needs_drop(tcx, param_env) { + if !maybe_inits.contains(mpi) || !ty.needs_drop(tcx, typing_env) { return false; } let field_needs_drop_and_init = |(f, f_ty, mpi)| { let child = move_path_children_matching(move_data, mpi, |x| x.is_field_to(f)); let Some(mpi) = child else { - return Ty::needs_drop(f_ty, tcx, param_env); + return Ty::needs_drop(f_ty, tcx, typing_env); }; - is_needs_drop_and_init(tcx, param_env, maybe_inits, move_data, f_ty, mpi) + is_needs_drop_and_init(tcx, typing_env, maybe_inits, move_data, f_ty, mpi) }; // This pass is only needed for const-checking, so it doesn't handle as many cases as @@ -110,7 +110,7 @@ fn is_needs_drop_and_init<'tcx>( let downcast = move_path_children_matching(move_data, mpi, |x| x.is_downcast_to(vid)); let Some(dc_mpi) = downcast else { - return variant_needs_drop(tcx, param_env, args, variant); + return variant_needs_drop(tcx, typing_env, args, variant); }; dc_mpi @@ -139,12 +139,12 @@ fn is_needs_drop_and_init<'tcx>( fn variant_needs_drop<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, args: GenericArgsRef<'tcx>, variant: &VariantDef, ) -> bool { variant.fields.iter().any(|field| { let f_ty = field.ty(tcx, args); - f_ty.needs_drop(tcx, param_env) + f_ty.needs_drop(tcx, typing_env) }) } diff --git a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs index 28925ba1beb..ad62b47a66d 100644 --- a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs @@ -16,18 +16,18 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { trace!("Running RemoveUnneededDrops on {:?}", body.source); - let did = body.source.def_id(); - let param_env = tcx.param_env_reveal_all_normalized(did); + let typing_env = body.typing_env(tcx); let mut should_simplify = false; - for block in body.basic_blocks.as_mut() { let terminator = block.terminator_mut(); if let TerminatorKind::Drop { place, target, .. } = terminator.kind { let ty = place.ty(&body.local_decls, tcx); - if ty.ty.needs_drop(tcx, param_env) { + if ty.ty.needs_drop(tcx, typing_env) { continue; } - if !tcx.consider_optimizing(|| format!("RemoveUnneededDrops {did:?} ")) { + if !tcx.consider_optimizing(|| { + format!("RemoveUnneededDrops {:?}", body.source.def_id()) + }) { continue; } debug!("SUCCESS: replacing `drop` with goto({:?})", target); diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index f13bb1c5993..2f723bccc19 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -21,9 +21,9 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveZsts { return; } - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); + let typing_env = body.typing_env(tcx); let local_decls = &body.local_decls; - let mut replacer = Replacer { tcx, param_env, local_decls }; + let mut replacer = Replacer { tcx, typing_env, local_decls }; for var_debug_info in &mut body.var_debug_info { replacer.visit_var_debug_info(var_debug_info); } @@ -35,7 +35,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveZsts { struct Replacer<'a, 'tcx> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, local_decls: &'a LocalDecls<'tcx>, } @@ -61,7 +61,7 @@ impl<'tcx> Replacer<'_, 'tcx> { if !maybe_zst(ty) { return false; } - let Ok(layout) = self.tcx.layout_of(self.param_env.and(ty)) else { + let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(ty)) else { return false; }; layout.is_zst() diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index f3b2f78b31c..587032ee720 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -8,14 +8,16 @@ pub(super) struct RevealAll; impl<'tcx> crate::MirPass<'tcx> for RevealAll { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); - RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body); + // FIXME(#132279): This is used during the phase transition from analysis + // to runtime, so we have to manually specify the correct typing mode. + let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id()); + RevealAllVisitor { tcx, typing_env }.visit_body_preserves_cfg(body); } } struct RevealAllVisitor<'tcx> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, } impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { @@ -53,7 +55,7 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { // We have to use `try_normalize_erasing_regions` here, since it's // possible that we visit impossible-to-satisfy where clauses here, // see #91745 - if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) { + if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.typing_env, constant.const_) { constant.const_ = c; } self.super_const_operand(constant, location); @@ -64,7 +66,7 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { // We have to use `try_normalize_erasing_regions` here, since it's // possible that we visit impossible-to-satisfy where clauses here, // see #91745 - if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.param_env, *ty) { + if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.typing_env, *ty) { *ty = t; } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index ffa11f5b213..f16cde7cd4e 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -274,9 +274,9 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) if ty.is_some() { let patch = { - let param_env = tcx.param_env_reveal_all_normalized(def_id); + let typing_env = ty::TypingEnv::post_analysis(tcx, def_id); let mut elaborator = - DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, param_env }; + DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, typing_env }; let dropee = tcx.mk_place_deref(dropee_ptr); let resume_block = elaborator.patch.resume_block(); elaborate_drops::elaborate_drop( @@ -334,7 +334,7 @@ pub(super) struct DropShimElaborator<'a, 'tcx> { pub body: &'a Body<'tcx>, pub patch: MirPatch<'tcx>, pub tcx: TyCtxt<'tcx>, - pub param_env: ty::ParamEnv<'tcx>, + pub typing_env: ty::TypingEnv<'tcx>, } impl fmt::Debug for DropShimElaborator<'_, '_> { @@ -355,8 +355,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.typing_env } fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle { @@ -914,7 +914,7 @@ fn build_call_shim<'tcx>( pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { debug_assert!(tcx.is_constructor(ctor_id)); - let param_env = tcx.param_env_reveal_all_normalized(ctor_id); + let typing_env = ty::TypingEnv::post_analysis(tcx, ctor_id); // Normalize the sig. let sig = tcx @@ -922,7 +922,7 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { .instantiate_identity() .no_bound_vars() .expect("LBR in ADT constructor signature"); - let sig = tcx.normalize_erasing_regions(param_env, sig); + let sig = tcx.normalize_erasing_regions(typing_env, sig); let ty::Adt(adt_def, args) = sig.output().kind() else { bug!("unexpected type for ADT ctor {:?}", sig.output()); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index f1672272862..139b25be0ab 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -48,7 +48,7 @@ struct AsyncDestructorCtorShimBuilder<'tcx> { self_ty: Option>, span: Span, source_info: SourceInfo, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, stack: Vec>, last_bb: BasicBlock, @@ -86,14 +86,14 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { // Usual case: noop() + unwind resume + return let mut bbs = IndexVec::with_capacity(3); - let param_env = tcx.param_env_reveal_all_normalized(def_id); + let typing_env = ty::TypingEnv::post_analysis(tcx, def_id); AsyncDestructorCtorShimBuilder { tcx, def_id, self_ty, span, source_info, - param_env, + typing_env, stack: Vec::with_capacity(Self::MAX_STACK_LEN), last_bb: bbs.push(BasicBlockData::new(None)), @@ -422,7 +422,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { statements: Vec::new(), terminator: Some(Terminator { source_info, - kind: if self.locals[local].ty.needs_drop(self.tcx, self.param_env) { + kind: if self.locals[local].ty.needs_drop(self.tcx, self.typing_env) { TerminatorKind::Drop { place: local.into(), target: *top_cleanup_bb, diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index e83b4727c48..bea3d0d8557 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -18,14 +18,14 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { trace!("Running SimplifyConstCondition on {:?}", body.source); - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); + let typing_env = body.typing_env(tcx); 'blocks: for block in body.basic_blocks_mut() { for stmt in block.statements.iter_mut() { // Simplify `assume` of a known value: either a NOP or unreachable. if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind && let NonDivergingIntrinsic::Assume(discr) = intrinsic && let Operand::Constant(ref c) = discr - && let Some(constant) = c.const_.try_eval_bool(tcx, param_env) + && let Some(constant) = c.const_.try_eval_bool(tcx, typing_env) { if constant { stmt.make_nop(); @@ -42,7 +42,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition { TerminatorKind::SwitchInt { discr: Operand::Constant(ref c), ref targets, .. } => { - let constant = c.const_.try_eval_bits(tcx, param_env); + let constant = c.const_.try_eval_bits(tcx, typing_env); if let Some(constant) = constant { let target = targets.target_for_value(constant); TerminatorKind::Goto { target } @@ -52,7 +52,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition { } TerminatorKind::Assert { target, cond: Operand::Constant(ref c), expected, .. - } => match c.const_.try_eval_bool(tcx, param_env) { + } => match c.const_.try_eval_bool(tcx, typing_env) { Some(v) if v == expected => TerminatorKind::Goto { target }, _ => continue, }, diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 26496b7f3fe..b6d80173086 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -37,7 +37,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { let opts = helper.find_optimizations(); let mut storage_deads_to_insert = vec![]; let mut storage_deads_to_remove: Vec<(usize, BasicBlock)> = vec![]; - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); + let typing_env = body.typing_env(tcx); for opt in opts { trace!("SUCCESS: Applying {:?}", opt); // replace terminator with a switchInt that switches on the integer directly @@ -46,7 +46,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { let new_value = match opt.branch_value_scalar { Scalar::Int(int) => { let layout = tcx - .layout_of(param_env.and(opt.branch_value_ty)) + .layout_of(typing_env.as_query_input(opt.branch_value_ty)) .expect("if we have an evaluated constant we must know the layout"); int.to_bits(layout.size) } diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 53bbb122096..52b9ec1e0a3 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -28,12 +28,12 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates { } let mut excluded = excluded_locals(body); - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); + let typing_env = body.typing_env(tcx); loop { debug!(?excluded); - let escaping = escaping_locals(tcx, param_env, &excluded, body); + let escaping = escaping_locals(tcx, typing_env, &excluded, body); debug!(?escaping); - let replacements = compute_flattening(tcx, param_env, body, escaping); + let replacements = compute_flattening(tcx, typing_env, body, escaping); debug!(?replacements); let all_dead_locals = replace_flattened_locals(tcx, body, replacements); if !all_dead_locals.is_empty() { @@ -59,7 +59,7 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates { /// client code. fn escaping_locals<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, excluded: &BitSet, body: &Body<'tcx>, ) -> BitSet { @@ -84,7 +84,7 @@ fn escaping_locals<'tcx>( // niche, so we do not want to automatically exclude it. return false; } - let Ok(layout) = tcx.layout_of(param_env.and(ty)) else { + let Ok(layout) = tcx.layout_of(typing_env.as_query_input(ty)) else { // We can't get the layout return true; }; @@ -196,7 +196,7 @@ impl<'tcx> ReplacementMap<'tcx> { /// The replacement will be done later in `ReplacementVisitor`. fn compute_flattening<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, body: &mut Body<'tcx>, escaping: BitSet, ) -> ReplacementMap<'tcx> { @@ -208,7 +208,7 @@ fn compute_flattening<'tcx>( } let decl = body.local_decls[local].clone(); let ty = decl.ty; - iter_fields(ty, tcx, param_env, |variant, field, field_ty| { + iter_fields(ty, tcx, typing_env, |variant, field, field_ty| { if variant.is_some() { // Downcasts are currently not supported. return; diff --git a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs index 3011af4d9d7..57e255b7c32 100644 --- a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs @@ -92,9 +92,7 @@ impl<'tcx> crate::MirPass<'tcx> for UnreachableEnumBranching { let Some(discriminant_ty) = get_switched_on_type(bb_data, tcx, body) else { continue }; - let layout = tcx.layout_of( - tcx.param_env_reveal_all_normalized(body.source.def_id()).and(discriminant_ty), - ); + let layout = tcx.layout_of(body.typing_env(tcx).as_query_input(discriminant_ty)); let mut allowed_variants = if let Ok(layout) = layout { // Find allowed variants based on uninhabited. diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index ae4e6ea6a74..ae0e6f594ee 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -12,8 +12,7 @@ use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ - self, CoroutineArgsExt, InstanceKind, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt, - Variance, + self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Variance, }; use rustc_middle::{bug, span_bug}; use rustc_trait_selection::traits::ObligationCtxt; @@ -47,9 +46,10 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { if matches!(body.source.instance, InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..)) { return; } + debug_assert_eq!(self.mir_phase, body.phase); let def_id = body.source.def_id(); - let mir_phase = self.mir_phase; - let param_env = mir_phase.param_env(tcx, def_id); + let mir_phase = body.phase; + let typing_env = body.typing_env(tcx); let can_unwind = if mir_phase <= MirPhase::Runtime(RuntimePhase::Initial) { // In this case `AbortUnwindingCalls` haven't yet been executed. true @@ -86,7 +86,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { cfg_checker.check_cleanup_control_flow(); // Also run the TypeChecker. - for (location, msg) in validate_types(tcx, self.mir_phase, param_env, body, body) { + for (location, msg) in validate_types(tcx, self.mir_phase, typing_env, body, body) { cfg_checker.fail(location, msg); } @@ -532,12 +532,12 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { pub(super) fn validate_types<'tcx>( tcx: TyCtxt<'tcx>, mir_phase: MirPhase, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, body: &Body<'tcx>, caller_body: &Body<'tcx>, ) -> Vec<(Location, String)> { let mut type_checker = - TypeChecker { body, caller_body, tcx, param_env, mir_phase, failures: Vec::new() }; + TypeChecker { body, caller_body, tcx, typing_env, mir_phase, failures: Vec::new() }; type_checker.visit_body(body); type_checker.failures } @@ -546,7 +546,7 @@ struct TypeChecker<'a, 'tcx> { body: &'a Body<'tcx>, caller_body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, mir_phase: MirPhase, failures: Vec<(Location, String)>, } @@ -582,14 +582,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Variance::Covariant }; - crate::util::relate_types( - self.tcx, - self.body.typing_mode(self.tcx), - self.param_env, - variance, - src, - dest, - ) + crate::util::relate_types(self.tcx, self.typing_env, variance, src, dest) } /// Check that the given predicate definitely holds in the param-env of this MIR body. @@ -608,12 +601,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - let infcx = self.tcx.infer_ctxt().build(self.body.typing_mode(self.tcx)); + let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new( self.tcx, ObligationCause::dummy(), - self.param_env, + param_env, pred, )); ocx.select_all_or_error().is_empty() @@ -630,7 +623,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if let Operand::Copy(place) = operand { let ty = place.ty(&self.body.local_decls, self.tcx).ty; - if !ty.is_copy_modulo_regions(self.tcx, self.param_env) { + if !ty.is_copy_modulo_regions(self.tcx, self.typing_env.param_env) { self.fail(location, format!("`Operand::Copy` with non-`Copy` type {ty}")); } } @@ -802,8 +795,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ProjectionElem::Subtype(ty) => { if !util::sub_types( self.tcx, - self.body.typing_mode(self.tcx), - self.param_env, + self.typing_env, ty, place_ref.ty(&self.body.local_decls, self.tcx).ty, ) { @@ -916,7 +908,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { assert!(adt_def.is_union()); assert_eq!(idx, FIRST_VARIANT); let dest_ty = self.tcx.normalize_erasing_regions( - self.param_env, + self.typing_env, adt_def.non_enum_variant().fields[field].ty(self.tcx, args), ); if let [field] = fields.raw.as_slice() { @@ -938,7 +930,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { for (src, dest) in std::iter::zip(fields, &variant.fields) { let dest_ty = self .tcx - .normalize_erasing_regions(self.param_env, dest.ty(self.tcx, args)); + .normalize_erasing_regions(self.typing_env, dest.ty(self.tcx, args)); if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest_ty) { self.fail(location, "adt field has the wrong type"); } @@ -997,7 +989,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } // FIXME: check `Thin` instead of `Sized` - if !in_pointee.is_sized(self.tcx, self.param_env) { + if !in_pointee.is_sized(self.tcx, self.typing_env.param_env) { self.fail(location, "input pointer must be thin"); } } else { @@ -1012,7 +1004,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if !self.mir_assign_valid_types(metadata_ty, self.tcx.types.usize) { self.fail(location, "slice metadata must be usize"); } - } else if pointee_ty.is_sized(self.tcx, self.param_env) { + } else if pointee_ty.is_sized(self.tcx, self.typing_env.param_env) { if metadata_ty != self.tcx.types.unit { self.fail(location, "metadata for pointer-to-thin must be unit"); } @@ -1301,8 +1293,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if !self .tcx - .normalize_erasing_regions(self.param_env, op_ty) - .is_sized(self.tcx, self.param_env) + .normalize_erasing_regions(self.typing_env, op_ty) + .is_sized(self.tcx, self.typing_env.param_env) { self.fail( location, @@ -1311,8 +1303,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } if !self .tcx - .normalize_erasing_regions(self.param_env, *target_type) - .is_sized(self.tcx, self.param_env) + .normalize_erasing_regions(self.typing_env, *target_type) + .is_sized(self.tcx, self.typing_env.param_env) { self.fail( location, @@ -1353,7 +1345,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { return; }; - current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); + current_ty = self.tcx.normalize_erasing_regions(self.typing_env, f_ty); } ty::Adt(adt_def, args) => { let Some(field) = adt_def.variant(variant).fields.get(field) else { @@ -1362,7 +1354,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { }; let f_ty = field.ty(self.tcx, args); - current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); + current_ty = self.tcx.normalize_erasing_regions(self.typing_env, f_ty); } _ => { self.fail( diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 322deb539cd..1b94c627f81 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -427,7 +427,7 @@ fn collect_items_rec<'tcx>( let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; // Nested statics have no type. if !nested { - let ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); + let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); visit_drop_use(tcx, ty, true, starting_item.span, &mut used_items); } @@ -636,7 +636,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { trace!("monomorphize: self.instance={:?}", self.instance); self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(value), ) } @@ -647,12 +647,11 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { constant: &mir::ConstOperand<'tcx>, ) -> Option> { let const_ = self.monomorphize(constant.const_); - let param_env = ty::ParamEnv::reveal_all(); // Evaluate the constant. This makes const eval failure a collection-time error (rather than // a codegen-time error). rustc stops after collection if there was an error, so this // ensures codegen never has to worry about failing consts. // (codegen relies on this and ICEs will happen if this is violated.) - match const_.eval(self.tcx, param_env, constant.span) { + match const_.eval(self.tcx, ty::TypingEnv::fully_monomorphized(), constant.span) { Ok(v) => Some(v), Err(ErrorHandled::TooGeneric(..)) => span_bug!( constant.span, @@ -863,9 +862,20 @@ fn visit_fn_use<'tcx>( ) { if let ty::FnDef(def_id, args) = *ty.kind() { let instance = if is_direct_call { - ty::Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, source) + ty::Instance::expect_resolve( + tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + source, + ) } else { - match ty::Instance::resolve_for_fn_ptr(tcx, ty::ParamEnv::reveal_all(), def_id, args) { + match ty::Instance::resolve_for_fn_ptr( + tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + ) { Some(instance) => instance, _ => bug!("failed to resolve instance for {ty}"), } @@ -1024,12 +1034,12 @@ fn find_vtable_types_for_unsizing<'tcx>( target_ty: Ty<'tcx>, ) -> (Ty<'tcx>, Ty<'tcx>) { let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { - let param_env = ty::ParamEnv::reveal_all(); + let typing_env = ty::TypingEnv::fully_monomorphized(); let type_has_metadata = |ty: Ty<'tcx>| -> bool { - if ty.is_sized(tcx.tcx, param_env) { + if ty.is_sized(tcx.tcx, typing_env.param_env) { return false; } - let tail = tcx.struct_tail_for_codegen(ty, param_env); + let tail = tcx.struct_tail_for_codegen(ty, typing_env); match tail.kind() { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, @@ -1039,7 +1049,7 @@ fn find_vtable_types_for_unsizing<'tcx>( if type_has_metadata(inner_source) { (inner_source, inner_target) } else { - tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, param_env) + tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, typing_env) } }; @@ -1270,8 +1280,13 @@ fn visit_mentioned_item<'tcx>( match *item { MentionedItem::Fn(ty) => { if let ty::FnDef(def_id, args) = *ty.kind() { - let instance = - Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, span); + let instance = Instance::expect_resolve( + tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + span, + ); // `visit_instance_use` was written for "used" item collection but works just as well // for "mentioned" item collection. // We can set `is_direct_call`; that just means we'll skip a bunch of shims that anyway @@ -1487,13 +1502,13 @@ impl<'v> RootCollector<'_, 'v> { // regions must appear in the argument // listing. let main_ret_ty = self.tcx.normalize_erasing_regions( - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), main_ret_ty.no_bound_vars().unwrap(), ); let start_instance = Instance::expect_resolve( self.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), start_def_id, self.tcx.mk_args(&[main_ret_ty.into()]), DUMMY_SP, @@ -1551,8 +1566,8 @@ fn create_mono_items_for_default_impls<'tcx>( return; } - let param_env = ty::ParamEnv::reveal_all(); - let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); + let typing_env = ty::TypingEnv::fully_monomorphized(); + let trait_ref = tcx.normalize_erasing_regions(typing_env, trait_ref); let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id); for method in tcx.provided_trait_methods(trait_ref.def_id) { if overridden_methods.contains_key(&method.def_id) { @@ -1567,7 +1582,7 @@ fn create_mono_items_for_default_impls<'tcx>( // only has lifetime generic parameters. This is validated by calling // `own_requires_monomorphization` on both the impl and method. let args = trait_ref.args.extend_to(tcx, method.def_id, only_region_params); - let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args, DUMMY_SP); + let instance = ty::Instance::expect_resolve(tcx, typing_env, method.def_id, args, DUMMY_SP); let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); if mono_item.node.is_instantiable(tcx) && tcx.should_codegen_locally(instance) { diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index eb576317678..0f08930fb4c 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -35,7 +35,9 @@ fn custom_coerce_unsize_info<'tcx>( [source_ty, target_ty], ); - match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) { + match tcx + .codegen_select_candidate(ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref)) + { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { impl_def_id, .. diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index 02b361456e4..30e634d8252 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -3,7 +3,7 @@ use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::{self, traversal}; use rustc_middle::ty::inherent::*; -use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt}; use rustc_session::lint::builtin::ABI_UNSUPPORTED_VECTOR_TYPES; use rustc_span::def_id::DefId; use rustc_span::{DUMMY_SP, Span, Symbol}; @@ -62,8 +62,9 @@ fn do_check_abi<'tcx>( /// Checks that the ABI of a given instance of a function does not contain vector-passed arguments /// or return values for which the corresponding target feature is not enabled. fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { - let param_env = ParamEnv::reveal_all(); - let Ok(abi) = tcx.fn_abi_of_instance(param_env.and((instance, ty::List::empty()))) else { + let typing_env = ty::TypingEnv::fully_monomorphized(); + let Ok(abi) = tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty()))) + else { // An error will be reported during codegen if we cannot determine the ABI of this // function. return; @@ -100,18 +101,18 @@ fn check_call_site_abi<'tcx>( // "Rust" ABI never passes arguments in vector registers. return; } - let param_env = ParamEnv::reveal_all(); + let typing_env = ty::TypingEnv::fully_monomorphized(); let callee_abi = match *callee.kind() { ty::FnPtr(..) => { - tcx.fn_abi_of_fn_ptr(param_env.and((callee.fn_sig(tcx), ty::List::empty()))) + tcx.fn_abi_of_fn_ptr(typing_env.as_query_input((callee.fn_sig(tcx), ty::List::empty()))) } ty::FnDef(def_id, args) => { // Intrinsics are handled separately by the compiler. if tcx.intrinsic(def_id).is_some() { return; } - let instance = ty::Instance::expect_resolve(tcx, param_env, def_id, args, DUMMY_SP); - tcx.fn_abi_of_instance(param_env.and((instance, ty::List::empty()))) + let instance = ty::Instance::expect_resolve(tcx, typing_env, def_id, args, DUMMY_SP); + tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty()))) } _ => { panic!("Invalid function call"); @@ -151,7 +152,7 @@ fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &m let callee_ty = func.ty(body, tcx); let callee_ty = instance.instantiate_mir_and_normalize_erasing_regions( tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(callee_ty), ); check_call_site_abi(tcx, callee_ty, *fn_span, body.source.instance); diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs index 7f04bdf46f1..438d49fd7fb 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs @@ -61,7 +61,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> { trace!("monomorphize: self.instance={:?}", self.instance); self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(value), ) } @@ -128,7 +128,9 @@ impl<'tcx> MoveCheckVisitor<'tcx> { ) -> Option { let ty = operand.ty(self.body, self.tcx); let ty = self.monomorphize(ty); - let Ok(layout) = self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) else { + let Ok(layout) = + self.tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + else { return None; }; if layout.size.bytes_usize() > limit.0 { diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 84e08ea881d..7240cfce0f7 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -666,7 +666,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( // This is a method within an impl, find out what the self-type is: let impl_self_ty = tcx.instantiate_and_normalize_erasing_regions( instance.args, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), tcx.type_of(impl_def_id), ); if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) { diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs index 093a697beeb..deb4ab433bf 100644 --- a/compiler/rustc_monomorphize/src/util.rs +++ b/compiler/rustc_monomorphize/src/util.rs @@ -22,29 +22,29 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In let typeck_results = tcx.typeck(closure_def_id); if typeck_results.closure_size_eval.contains_key(&closure_def_id) { - let param_env = ty::ParamEnv::reveal_all(); + let typing_env = ty::TypingEnv::fully_monomorphized(); let ClosureSizeProfileData { before_feature_tys, after_feature_tys } = typeck_results.closure_size_eval[&closure_def_id]; let before_feature_tys = tcx.instantiate_and_normalize_erasing_regions( closure_instance.args, - param_env, + typing_env, ty::EarlyBinder::bind(before_feature_tys), ); let after_feature_tys = tcx.instantiate_and_normalize_erasing_regions( closure_instance.args, - param_env, + typing_env, ty::EarlyBinder::bind(after_feature_tys), ); let new_size = tcx - .layout_of(param_env.and(after_feature_tys)) + .layout_of(typing_env.as_query_input(after_feature_tys)) .map(|l| format!("{:?}", l.size.bytes())) .unwrap_or_else(|e| format!("Failed {e:?}")); let old_size = tcx - .layout_of(param_env.and(before_feature_tys)) + .layout_of(typing_env.as_query_input(before_feature_tys)) .map(|l| format!("{:?}", l.size.bytes())) .unwrap_or_else(|e| format!("Failed {e:?}")); diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index df4f0ffdd57..5f740590712 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -262,7 +262,11 @@ where return ecx.forced_ambiguity(MaybeCause::Ambiguity); } - if cx.layout_is_pointer_like(goal.param_env, goal.predicate.self_ty()) { + if cx.layout_is_pointer_like( + ecx.typing_mode(goal.param_env), + goal.param_env, + goal.predicate.self_ty(), + ) { ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } else { diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index b1267562f7b..4db8584b884 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -59,9 +59,9 @@ fn unwrap_fn_abi<'tcx>( } fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { - let param_env = tcx.param_env(item_def_id); + let typing_env = ty::TypingEnv::post_analysis(tcx, item_def_id); let args = GenericArgs::identity_for_item(tcx, item_def_id); - let instance = match Instance::try_resolve(tcx, param_env, item_def_id.into(), args) { + let instance = match Instance::try_resolve(tcx, typing_env, item_def_id.into(), args) { Ok(Some(instance)) => instance, Ok(None) => { // Not sure what to do here, but `LayoutError::Unknown` seems reasonable? @@ -75,7 +75,9 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut Err(_guaranteed) => return, }; let abi = unwrap_fn_abi( - tcx.fn_abi_of_instance(param_env.and((instance, /* extra_args */ ty::List::empty()))), + tcx.fn_abi_of_instance( + typing_env.as_query_input((instance, /* extra_args */ ty::List::empty())), + ), tcx, item_def_id, ); @@ -117,10 +119,10 @@ fn test_abi_eq<'tcx>(abi1: &'tcx FnAbi<'tcx, Ty<'tcx>>, abi2: &'tcx FnAbi<'tcx, } fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { - let param_env = tcx.param_env(item_def_id); + let typing_env = ty::TypingEnv::post_analysis(tcx, item_def_id); let ty = tcx.type_of(item_def_id).instantiate_identity(); let span = tcx.def_span(item_def_id); - if !ensure_wf(tcx, param_env, ty, item_def_id, span) { + if !ensure_wf(tcx, typing_env, ty, item_def_id, span) { return; } let meta_items = attr.meta_item_list().unwrap_or_default(); @@ -134,10 +136,10 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut ); }; let abi = unwrap_fn_abi( - tcx.fn_abi_of_fn_ptr( - param_env - .and((sig_tys.with(*hdr), /* extra_args */ ty::List::empty())), - ), + tcx.fn_abi_of_fn_ptr(typing_env.as_query_input(( + sig_tys.with(*hdr), + /* extra_args */ ty::List::empty(), + ))), tcx, item_def_id, ); @@ -165,10 +167,10 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut ); }; let abi1 = unwrap_fn_abi( - tcx.fn_abi_of_fn_ptr( - param_env - .and((sig_tys1.with(*hdr1), /* extra_args */ ty::List::empty())), - ), + tcx.fn_abi_of_fn_ptr(typing_env.as_query_input(( + sig_tys1.with(*hdr1), + /* extra_args */ ty::List::empty(), + ))), tcx, item_def_id, ); @@ -179,10 +181,10 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut ); }; let abi2 = unwrap_fn_abi( - tcx.fn_abi_of_fn_ptr( - param_env - .and((sig_tys2.with(*hdr2), /* extra_args */ ty::List::empty())), - ), + tcx.fn_abi_of_fn_ptr(typing_env.as_query_input(( + sig_tys2.with(*hdr2), + /* extra_args */ ty::List::empty(), + ))), tcx, item_def_id, ); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index b1db66fa52d..ecf8d34ad84 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -273,7 +273,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { data.get(expr.hir_id).expect("no offset_of_data for offset_of"); let body_did = self.typeck_results().hir_owner.to_def_id(); - let param_env = self.tcx.param_env(body_did); + let typing_env = ty::TypingEnv::non_body_analysis(self.tcx, body_did); let mut current_ty = container; @@ -285,13 +285,13 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { self.insert_def_id(field.did); let field_ty = field.ty(self.tcx, args); - current_ty = self.tcx.normalize_erasing_regions(param_env, field_ty); + current_ty = self.tcx.normalize_erasing_regions(typing_env, field_ty); } // we don't need to mark tuple fields as live, // but we may need to mark subfields ty::Tuple(tys) => { current_ty = - self.tcx.normalize_erasing_regions(param_env, tys[field.as_usize()]); + self.tcx.normalize_erasing_regions(typing_env, tys[field.as_usize()]); } _ => span_bug!(expr.span, "named field access on non-ADT"), } @@ -944,7 +944,10 @@ impl<'tcx> DeadVisitor<'tcx> { if is_positional && self .tcx - .layout_of(self.tcx.param_env(field.did).and(field_type)) + .layout_of( + ty::TypingEnv::non_body_analysis(self.tcx, field.did) + .as_query_input(field_type), + ) .map_or(true, |layout| layout.is_zst()) { return ShouldWarnAboutField::No; diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 986dce5b56d..bb90b5a1e31 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -2,10 +2,9 @@ use rustc_abi::{HasDataLayout, TargetDataLayout}; use rustc_ast::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::infer::canonical::ir::TypingMode; use rustc_middle::span_bug; -use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers}; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; @@ -39,11 +38,13 @@ pub fn test_layout(tcx: TyCtxt<'_>) { pub fn ensure_wf<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, def_id: LocalDefId, span: Span, ) -> bool { + let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); + let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); let pred = ty::ClauseKind::WellFormed(ty.into()); let obligation = traits::Obligation::new( tcx, @@ -55,8 +56,6 @@ pub fn ensure_wf<'tcx>( param_env, pred, ); - let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)); - let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); ocx.register_obligation(obligation); let errors = ocx.select_all_or_error(); if !errors.is_empty() { @@ -69,13 +68,13 @@ pub fn ensure_wf<'tcx>( } fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { - let param_env = tcx.param_env(item_def_id); + let typing_env = ty::TypingEnv::post_analysis(tcx, item_def_id); let ty = tcx.type_of(item_def_id).instantiate_identity(); let span = tcx.def_span(item_def_id.to_def_id()); - if !ensure_wf(tcx, param_env, ty, item_def_id, span) { + if !ensure_wf(tcx, typing_env, ty, item_def_id, span) { return; } - match tcx.layout_of(param_env.and(ty)) { + match tcx.layout_of(typing_env.as_query_input(ty)) { Ok(ty_layout) => { // Check out the `#[rustc_layout(..)]` attribute to tell what to dump. // The `..` are the names of fields to dump. @@ -107,19 +106,15 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { span, homogeneous_aggregate: format!( "{:?}", - ty_layout.homogeneous_aggregate(&UnwrapLayoutCx { tcx, param_env }) + ty_layout + .homogeneous_aggregate(&UnwrapLayoutCx { tcx, typing_env }) ), }); } sym::debug => { - let normalized_ty = format!( - "{}", - tcx.normalize_erasing_regions( - param_env.with_reveal_all_normalized(tcx), - ty, - ) - ); + let normalized_ty = + format!("{}", tcx.normalize_erasing_regions(typing_env, ty)); // FIXME: using the `Debug` impl here isn't ideal. let ty_layout = format!("{:#?}", *ty_layout); tcx.dcx().emit_err(LayoutOf { span, normalized_ty, ty_layout }); @@ -140,7 +135,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { struct UnwrapLayoutCx<'tcx> { tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, } impl<'tcx> LayoutOfHelpers<'tcx> for UnwrapLayoutCx<'tcx> { @@ -155,9 +150,9 @@ impl<'tcx> HasTyCtxt<'tcx> for UnwrapLayoutCx<'tcx> { } } -impl<'tcx> HasParamEnv<'tcx> for UnwrapLayoutCx<'tcx> { - fn param_env(&self) -> ParamEnv<'tcx> { - self.param_env +impl<'tcx> HasTypingEnv<'tcx> for UnwrapLayoutCx<'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.typing_env } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 366f7dd293c..c6c99852952 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1297,7 +1297,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn check_is_ty_uninhabited(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode { let ty = self.typeck_results.expr_ty(expr); let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id(); - if ty.is_inhabited_from(self.ir.tcx, m, self.param_env) { + if ty.is_inhabited_from(self.ir.tcx, m, ty::TypingEnv::from_param_env(self.param_env)) { return succ; } match self.ir.lnks[succ] { diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 9ea5023064c..936e5235c55 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -9,6 +9,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::middle::stability::EvalResult; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary}; +use rustc_middle::traits::Reveal; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef, @@ -108,6 +109,17 @@ impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> { } impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { + pub fn typing_mode(&self) -> ty::TypingMode<'tcx> { + debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); + // FIXME(#132279): This is inside of a body. If we need to use the `param_env` + // and `typing_mode` we should reveal opaques defined by that body. + ty::TypingMode::non_body_analysis() + } + + pub fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } + } + /// Type inference occasionally gives us opaque types in places where corresponding patterns /// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited /// types, we use the corresponding concrete type if possible. @@ -139,7 +151,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { !ty.inhabited_predicate(self.tcx).apply_revealing_opaque( self.tcx, - self.param_env, + self.typing_env(), self.module, &|key| self.reveal_opaque_key(key), ) @@ -179,7 +191,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { variant.fields.iter().map(move |field| { let ty = field.ty(self.tcx, args); // `field.ty()` doesn't normalize after instantiating. - let ty = self.tcx.normalize_erasing_regions(self.param_env, ty); + let ty = self.tcx.normalize_erasing_regions(self.typing_env(), ty); let ty = self.reveal_opaque_ty(ty); (field, ty) }) @@ -369,7 +381,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let is_inhabited = v .inhabited_predicate(cx.tcx, *def) .instantiate(cx.tcx, args) - .apply_revealing_opaque(cx.tcx, cx.param_env, cx.module, &|key| { + .apply_revealing_opaque(cx.tcx, cx.typing_env(), cx.module, &|key| { cx.reveal_opaque_key(key) }); // Variants that depend on a disabled unstable feature. @@ -430,7 +442,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { match bdy { PatRangeBoundary::NegInfinity => MaybeInfiniteInt::NegInfinity, PatRangeBoundary::Finite(value) => { - let bits = value.eval_bits(self.tcx, self.param_env); + let bits = value.eval_bits(self.tcx, self.typing_env()); match *ty.kind() { ty::Int(ity) => { let size = Integer::from_int_ty(&self.tcx, ity).size().bits(); @@ -539,7 +551,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { PatKind::Constant { value } => { match ty.kind() { ty::Bool => { - ctor = match value.try_eval_bool(cx.tcx, cx.param_env) { + ctor = match value.try_eval_bool(cx.tcx, cx.typing_env()) { Some(b) => Bool(b), None => Opaque(OpaqueId::new()), }; @@ -547,7 +559,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Char | ty::Int(_) | ty::Uint(_) => { - ctor = match value.try_eval_bits(cx.tcx, cx.param_env) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { Some(bits) => { let x = match *ty.kind() { ty::Int(ity) => { @@ -564,7 +576,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F16) => { - ctor = match value.try_eval_bits(cx.tcx, cx.param_env) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Half::from_bits(bits); @@ -576,7 +588,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F32) => { - ctor = match value.try_eval_bits(cx.tcx, cx.param_env) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Single::from_bits(bits); @@ -588,7 +600,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F64) => { - ctor = match value.try_eval_bits(cx.tcx, cx.param_env) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Double::from_bits(bits); @@ -600,7 +612,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F128) => { - ctor = match value.try_eval_bits(cx.tcx, cx.param_env) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Quad::from_bits(bits); @@ -649,8 +661,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Float(fty) => { use rustc_apfloat::Float; - let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.param_env)); - let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.param_env)); + let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env())); + let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env())); match fty { ty::FloatTy::F16 => { use rustc_apfloat::ieee::Half; diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 0e6f905e7a1..2f4387e412d 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -133,7 +133,7 @@ fn encode_const<'tcx>( match ct_ty.kind() { ty::Int(ity) => { let bits = c - .try_to_bits(tcx, ty::ParamEnv::reveal_all()) + .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected monomorphic const in cfi"); let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128; if val < 0 { @@ -143,7 +143,7 @@ fn encode_const<'tcx>( } ty::Uint(_) => { let val = c - .try_to_bits(tcx, ty::ParamEnv::reveal_all()) + .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected monomorphic const in cfi"); let _ = write!(s, "{val}"); } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs index 01568a0f61c..562e288afaa 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs @@ -117,7 +117,9 @@ pub fn typeid_for_instance<'tcx>( .unwrap_or_else(|| bug!("typeid_for_instance: invalid option(s) `{:?}`", options.bits())); let instance = transform_instance(tcx, instance, transform_ty_options); let fn_abi = tcx - .fn_abi_of_instance(ty::ParamEnv::reveal_all().and((instance, ty::List::empty()))) + .fn_abi_of_instance( + ty::TypingEnv::fully_monomorphized().as_query_input((instance, ty::List::empty())), + ) .unwrap_or_else(|error| { bug!("typeid_for_instance: couldn't get fn_abi of instance {instance:?}: {error:?}") }); diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index cba79a02f8b..9c01bd04353 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -136,18 +136,18 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { return t; } let variant = adt_def.non_enum_variant(); - let param_env = self.tcx.param_env(variant.def_id); + let typing_env = ty::TypingEnv::post_analysis(self.tcx, variant.def_id); let field = variant.fields.iter().find(|field| { let ty = self.tcx.type_of(field.did).instantiate_identity(); let is_zst = self .tcx - .layout_of(param_env.and(ty)) + .layout_of(typing_env.as_query_input(ty)) .is_ok_and(|layout| layout.is_zst()); !is_zst }); if let Some(field) = field { let ty0 = self.tcx.normalize_erasing_regions( - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), field.ty(self.tcx, args), ); // Generalize any repr(transparent) user-defined type that is either a @@ -209,9 +209,9 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { } } - ty::Alias(..) => { - self.fold_ty(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), t)) - } + ty::Alias(..) => self.fold_ty( + self.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t), + ), ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Param(..) | ty::Placeholder(..) => { bug!("fold_ty: unexpected `{:?}`", t.kind()); @@ -241,7 +241,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc let alias_ty = ty::AliasTy::new_from_args(tcx, assoc_ty.def_id, super_trait_ref.args); let resolved = tcx.normalize_erasing_regions( - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), alias_ty.to_ty(tcx), ); debug!("Resolved {:?} -> {resolved}", alias_ty.to_ty(tcx)); @@ -376,7 +376,7 @@ pub(crate) fn transform_instance<'tcx>( // implementation will not. We need to walk back to the more general trait method let trait_ref = tcx.instantiate_and_normalize_erasing_regions( instance.args, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), trait_ref, ); let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); @@ -397,7 +397,7 @@ pub(crate) fn transform_instance<'tcx>( } else if tcx.is_closure_like(instance.def_id()) { // We're either a closure or a coroutine. Our goal is to find the trait we're defined on, // instantiate it, and take the type of its only method as our own. - let closure_ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); + let closure_ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); let (trait_id, inputs) = match closure_ty.kind() { ty::Closure(..) => { let closure_args = instance.args.as_closure(); diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 5c09879f60e..4e8db6096d4 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -41,7 +41,7 @@ pub(crate) fn try_new_allocation<'tcx>( let size = scalar.size(); let align = tables .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)) + .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .map_err(|e| e.stable(tables))? .align; let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi); @@ -53,7 +53,7 @@ pub(crate) fn try_new_allocation<'tcx>( ConstValue::ZeroSized => { let align = tables .tcx - .layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)) + .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .map_err(|e| e.stable(tables))? .align; new_empty_allocation(align.abi) @@ -66,7 +66,7 @@ pub(crate) fn try_new_allocation<'tcx>( rustc_middle::mir::interpret::Scalar::from_target_usize(meta, &tables.tcx); let layout = tables .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)) + .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .map_err(|e| e.stable(tables))?; let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi); @@ -90,7 +90,7 @@ pub(crate) fn try_new_allocation<'tcx>( let alloc = tables.tcx.global_alloc(alloc_id).unwrap_memory(); let ty_size = tables .tcx - .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)) + .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .map_err(|e| e.stable(tables))? .size; allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables) diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs index cd91fc26c10..2eb0cea0e85 100644 --- a/compiler/rustc_smir/src/rustc_smir/builder.rs +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -40,7 +40,7 @@ impl<'tcx> BodyBuilder<'tcx> { { let mut mono_body = self.instance.instantiate_mir_and_normalize_erasing_regions( tables.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(body), ); self.visit_body(&mut mono_body); @@ -60,7 +60,7 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> { location: mir::Location, ) { let const_ = constant.const_; - let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), constant.span) { + let val = match const_.eval(self.tcx, ty::TypingEnv::fully_monomorphized(), constant.span) { Ok(v) => v, Err(mir::interpret::ErrorHandled::Reported(..)) => return, Err(mir::interpret::ErrorHandled::TooGeneric(..)) => { diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 3db65692af7..b19adf321c3 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -11,7 +11,7 @@ use std::iter; use rustc_abi::HasDataLayout; use rustc_hir::LangItem; use rustc_middle::ty::layout::{ - FnAbiOf, FnAbiOfHelpers, HasParamEnv, HasTyCtxt, LayoutOf, LayoutOfHelpers, + FnAbiOf, FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOf, LayoutOfHelpers, }; use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; use rustc_middle::ty::{ @@ -410,7 +410,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let mir_const = cnst.internal(&mut *tables, tcx); mir_const - .try_eval_target_usize(tables.tcx, ParamEnv::empty()) + .try_eval_target_usize(tables.tcx, ty::TypingEnv::fully_monomorphized()) .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) } fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { @@ -428,7 +428,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let ty_internal = ty.internal(&mut *tables, tcx); let size = tables .tcx - .layout_of(ParamEnv::empty().and(ty_internal)) + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty_internal)) .map_err(|err| { Error::new(format!( "Cannot create a zero-sized constant for type `{ty_internal}`: {err}" @@ -469,7 +469,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); - let size = tables.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap().size; + let size = tables + .tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .unwrap() + .size; // We don't use Const::from_bits since it doesn't have any error checking. let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { @@ -486,7 +490,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); - let size = tables.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap().size; + let size = tables + .tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .unwrap() + .size; // We don't use Const::from_bits since it doesn't have any error checking. let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { @@ -523,7 +531,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let def_ty = tables.tcx.type_of(item.internal(&mut *tables, tcx)); tables .tcx - .instantiate_and_normalize_erasing_regions(args, ty::ParamEnv::reveal_all(), def_ty) + .instantiate_and_normalize_erasing_regions( + args, + ty::TypingEnv::fully_monomorphized(), + def_ty, + ) .stable(&mut *tables) } @@ -573,7 +585,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation"); - instance.ty(tables.tcx, ParamEnv::reveal_all()).stable(&mut *tables) + instance.ty(tables.tcx, ty::TypingEnv::fully_monomorphized()).stable(&mut *tables) } fn instance_args(&self, def: InstanceDef) -> GenericArgs { @@ -642,7 +654,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let def_id = def.0.internal(&mut *tables, tcx); let args_ref = args.internal(&mut *tables, tcx); - match Instance::try_resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) { + match Instance::try_resolve( + tables.tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args_ref, + ) { Ok(Some(instance)) => Some(instance.stable(&mut *tables)), Ok(None) | Err(_) => None, } @@ -665,8 +682,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let def_id = def.0.internal(&mut *tables, tcx); let args_ref = args.internal(&mut *tables, tcx); - Instance::resolve_for_fn_ptr(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) - .stable(&mut *tables) + Instance::resolve_for_fn_ptr( + tables.tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args_ref, + ) + .stable(&mut *tables) } fn resolve_closure( @@ -827,9 +849,9 @@ impl<'tcx> LayoutOfHelpers<'tcx> for Tables<'tcx> { } } -impl<'tcx> HasParamEnv<'tcx> for Tables<'tcx> { - fn param_env(&self) -> ty::ParamEnv<'tcx> { - ty::ParamEnv::reveal_all() +impl<'tcx> HasTypingEnv<'tcx> for Tables<'tcx> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv::fully_monomorphized() } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 05b4ff327a9..94f51b87cff 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -26,7 +26,7 @@ pub(super) fn mangle<'tcx>( ) -> String { let def_id = instance.def_id(); // FIXME(eddyb) this should ideally not be needed. - let args = tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), instance.args); + let args = tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), instance.args); let prefix = "_R"; let mut cx: SymbolMangler<'_> = SymbolMangler { @@ -237,15 +237,16 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { if !args.is_empty() { param_env = EarlyBinder::bind(param_env).instantiate(self.tcx, args); } + let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env }; match &mut impl_trait_ref { Some(impl_trait_ref) => { assert_eq!(impl_trait_ref.self_ty(), self_ty); - *impl_trait_ref = self.tcx.normalize_erasing_regions(param_env, *impl_trait_ref); + *impl_trait_ref = self.tcx.normalize_erasing_regions(typing_env, *impl_trait_ref); self_ty = impl_trait_ref.self_ty(); } None => { - self_ty = self.tcx.normalize_erasing_regions(param_env, self_ty); + self_ty = self.tcx.normalize_erasing_regions(typing_env, self_ty); } } @@ -591,7 +592,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ct_ty.print(self)?; let mut bits = ct - .try_to_bits(self.tcx, ty::ParamEnv::reveal_all()) + .try_to_bits(self.tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected const to be monomorphic"); // Negative integer values are mangled using `n` as a "sign prefix". diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 808e6a50d85..9a7bdaa5b57 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -528,7 +528,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // Find the method being called. let Ok(Some(instance)) = ty::Instance::try_resolve( tcx, - ctxt.param_env, + self.cx.typing_env(ctxt.param_env), ctxt.assoc_item.def_id, self.cx.resolve_vars_if_possible(ctxt.args), ) else { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 1109b11d2a7..4e7d7b79ff4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2079,7 +2079,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { cand.trait_ref = self .tcx .try_normalize_erasing_regions( - self.tcx.param_env(cand.impl_def_id), + ty::TypingEnv::non_body_analysis(self.tcx, cand.impl_def_id), cand.trait_ref, ) .unwrap_or(cand.trait_ref); diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index c00246cfd7d..cf63f14fb93 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -513,7 +513,7 @@ fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: let method_def_id = method.def_id; let sig = tcx.fn_sig(method_def_id).instantiate_identity(); - let param_env = tcx.param_env(method_def_id); + let typing_env = ty::TypingEnv::non_body_analysis(tcx, method_def_id); let receiver_ty = tcx.liberate_late_bound_regions(method_def_id, sig.input(0)); if receiver_ty == tcx.types.self_param { @@ -523,7 +523,7 @@ fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: // e.g., `Rc<()>` let unit_receiver_ty = receiver_for_self_ty(tcx, receiver_ty, tcx.types.unit, method_def_id); - match tcx.layout_of(param_env.and(unit_receiver_ty)).map(|l| l.backend_repr) { + match tcx.layout_of(typing_env.as_query_input(unit_receiver_ty)).map(|l| l.backend_repr) { Ok(BackendRepr::Scalar(..)) => (), abi => { tcx.dcx().span_delayed_bug( @@ -538,7 +538,7 @@ fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: // e.g., `Rc` let trait_object_receiver = receiver_for_self_ty(tcx, receiver_ty, trait_object_ty, method_def_id); - match tcx.layout_of(param_env.and(trait_object_receiver)).map(|l| l.backend_repr) { + match tcx.layout_of(typing_env.as_query_input(trait_object_receiver)).map(|l| l.backend_repr) { Ok(BackendRepr::ScalarPair(..)) => (), abi => { tcx.dcx().span_delayed_bug( diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index fe90066b4e7..c0603c06d42 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -611,11 +611,12 @@ pub fn try_evaluate_const<'tcx>( // // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All` // instead of having this logic here - let env = tcx.erase_regions(param_env).with_reveal_all_normalized(tcx); + let typing_env = + tcx.erase_regions(infcx.typing_env(param_env)).with_reveal_all_normalized(tcx); let erased_uv = tcx.erase_regions(uv); use rustc_middle::mir::interpret::ErrorHandled; - match tcx.const_eval_resolve_for_typeck(env, erased_uv, DUMMY_SP) { + match tcx.const_eval_resolve_for_typeck(typing_env, erased_uv, DUMMY_SP) { Ok(Ok(val)) => Ok(ty::Const::new_value( tcx, val, diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 4ff0910c9b9..1d3e8d43af7 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -144,7 +144,14 @@ pub fn compute_dropck_outlives_inner<'tcx>( result.overflows.len(), ty_stack.len() ); - dtorck_constraint_for_ty_inner(tcx, param_env, DUMMY_SP, depth, ty, &mut constraints)?; + dtorck_constraint_for_ty_inner( + tcx, + ocx.infcx.typing_env(param_env), + DUMMY_SP, + depth, + ty, + &mut constraints, + )?; // "outlives" represent types/regions that may be touched // by a destructor. @@ -196,10 +203,10 @@ pub fn compute_dropck_outlives_inner<'tcx>( /// Returns a set of constraints that needs to be satisfied in /// order for `ty` to be valid for destruction. -#[instrument(level = "debug", skip(tcx, param_env, span, constraints))] +#[instrument(level = "debug", skip(tcx, typing_env, span, constraints))] pub fn dtorck_constraint_for_ty_inner<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, span: Span, depth: usize, ty: Ty<'tcx>, @@ -234,20 +241,20 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( ty::Pat(ety, _) | ty::Array(ety, _) | ty::Slice(ety) => { // single-element containers, behave like their element rustc_data_structures::stack::ensure_sufficient_stack(|| { - dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, *ety, constraints) + dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, *ety, constraints) })?; } ty::Tuple(tys) => rustc_data_structures::stack::ensure_sufficient_stack(|| { for ty in tys.iter() { - dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, ty, constraints)?; + dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, ty, constraints)?; } Ok::<_, NoSolution>(()) })?, ty::Closure(_, args) => rustc_data_structures::stack::ensure_sufficient_stack(|| { for ty in args.as_closure().upvar_tys() { - dtorck_constraint_for_ty_inner(tcx, param_env, span, depth + 1, ty, constraints)?; + dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, ty, constraints)?; } Ok::<_, NoSolution>(()) })?, @@ -257,7 +264,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( for ty in args.as_coroutine_closure().upvar_tys() { dtorck_constraint_for_ty_inner( tcx, - param_env, + typing_env, span, depth + 1, ty, @@ -296,7 +303,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( // While we conservatively assume that all coroutines require drop // to avoid query cycles during MIR building, we can check the actual // witness during borrowck to avoid unnecessary liveness constraints. - if args.witness().needs_drop(tcx, tcx.erase_regions(param_env)) { + if args.witness().needs_drop(tcx, tcx.erase_regions(typing_env)) { constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from)); constraints.outlives.push(args.resume_ty().into()); } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index bf3f83ec827..1e0c487c4d4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -1224,16 +1224,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // The regions of a type don't affect the size of the type let tcx = self.tcx(); let self_ty = tcx.instantiate_bound_regions_with_erased(obligation.predicate.self_ty()); - // We should erase regions from both the param-env and type, since both - // may have infer regions. Specifically, after canonicalizing and instantiating, - // early bound regions turn into region vars in both the new and old solver. - let key = tcx.erase_regions(obligation.param_env.and(self_ty)); + // But if there are inference variables, we have to wait until it's resolved. - if key.has_non_region_infer() { + if (obligation.param_env, self_ty).has_non_region_infer() { candidates.ambiguous = true; return; } + // We should erase regions from both the param-env and type, since both + // may have infer regions. Specifically, after canonicalizing and instantiating, + // early bound regions turn into region vars in both the new and old solver. + let key = self.infcx.pseudo_canonicalize_query( + tcx.erase_regions(obligation.param_env), + tcx.erase_regions(self_ty), + ); if let Ok(layout) = tcx.layout_of(key) && layout.layout.is_pointer_like(&tcx.data_layout) { diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index bb56d6eaf54..8352d31d13a 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -276,8 +276,10 @@ fn vtable_entries<'tcx>( // The trait type may have higher-ranked lifetimes in it; // erase them if they appear, so that we get the type // at some particular call site. - let args = - tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), args); + let args = tcx.normalize_erasing_late_bound_regions( + ty::TypingEnv::fully_monomorphized(), + args, + ); // It's possible that the method relies on where-clauses that // do not hold for this particular set of type parameters. @@ -294,7 +296,7 @@ fn vtable_entries<'tcx>( let instance = ty::Instance::expect_resolve_for_vtable( tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), def_id, args, DUMMY_SP, diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index d8c1c50d79a..57225df0819 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -6,7 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; -use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, @@ -23,14 +23,15 @@ use tracing::debug; /// This also expects that `trait_ref` is fully normalized. pub(crate) fn codegen_select_candidate<'tcx>( tcx: TyCtxt<'tcx>, - (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>), + key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>>, ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { + let PseudoCanonicalInput { typing_env, value: trait_ref } = key; // We expect the input to be fully normalized. - debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref)); + debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(typing_env, trait_ref)); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. - let infcx = tcx.infer_ctxt().ignoring_regions().build(TypingMode::from_param_env(param_env)); + let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env); let mut selcx = SelectionContext::new(&infcx); let obligation_cause = ObligationCause::dummy(); diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 4e5309eea28..51e4dbe81b3 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -5,7 +5,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; -use rustc_middle::ty::{GenericArgs, TyCtxt}; +use rustc_middle::ty::{self, GenericArgs, TyCtxt}; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::dropck_outlives::{ compute_dropck_outlives_inner, dtorck_constraint_for_ty_inner, @@ -35,7 +35,7 @@ pub(crate) fn adt_dtorck_constraint( ) -> Result<&DropckConstraint<'_>, NoSolution> { let def = tcx.adt_def(def_id); let span = tcx.def_span(def_id); - let param_env = tcx.param_env(def_id); + let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id); debug!("dtorck_constraint: {:?}", def); if def.is_manually_drop() { @@ -57,7 +57,7 @@ pub(crate) fn adt_dtorck_constraint( let mut result = DropckConstraint::empty(); for field in def.all_fields() { let fty = tcx.type_of(field.did).instantiate_identity(); - dtorck_constraint_for_ty_inner(tcx, param_env, span, 0, fty, &mut result)?; + dtorck_constraint_for_ty_inner(tcx, typing_env, span, 0, fty, &mut result)?; } result.outlives.extend(tcx.destructor_constraints(def)); dedup_dtorck_constraint(&mut result); diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index d79059a39a1..68ff66bbce7 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -1,7 +1,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; use rustc_middle::traits::query::NoSolution; -use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Normalized, ObligationCause}; use tracing::debug; @@ -19,10 +19,10 @@ pub(crate) fn provide(p: &mut Providers) { fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable> + PartialEq + Copy>( tcx: TyCtxt<'tcx>, - goal: ParamEnvAnd<'tcx, T>, + goal: PseudoCanonicalInput<'tcx, T>, ) -> Result { - let ParamEnvAnd { param_env, value } = goal; - let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)); + let PseudoCanonicalInput { typing_env, value } = goal; + let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); let cause = ObligationCause::dummy(); match infcx.at(&cause, param_env).query_normalize(value) { Ok(Normalized { value: normalized_value, obligations: normalized_obligations }) => { diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs index 9dabcea706f..023c8fad781 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs @@ -31,7 +31,7 @@ where #[cfg(feature = "rustc")] mod rustc { use rustc_middle::ty::layout::LayoutCx; - use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; + use rustc_middle::ty::{Ty, TyCtxt, TypingEnv}; use super::*; use crate::layout::tree::rustc::Err; @@ -43,7 +43,7 @@ mod rustc { pub(crate) fn answer(self) -> Answer< as QueryContext>::Ref> { let Self { src, dst, assume, context } = self; - let layout_cx = LayoutCx::new(context, ParamEnv::reveal_all()); + let layout_cx = LayoutCx::new(context, TypingEnv::fully_monomorphized()); // Convert `src` and `dst` from their rustc representations, to `Tree`-based // representations. diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 0184e93acf1..e2283383196 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -7,7 +7,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ - FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind, + FnAbiError, HasTyCtxt, HasTypingEnv, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind, }; use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt}; use rustc_session::config::OptLevel; @@ -26,11 +26,11 @@ pub(crate) fn provide(providers: &mut Providers) { // for `Instance` (e.g. typeck would use `Ty::fn_sig` instead), // or should go through `FnAbi` instead, to avoid losing any // adjustments `fn_abi_of_instance` might be performing. -#[tracing::instrument(level = "debug", skip(tcx, param_env))] +#[tracing::instrument(level = "debug", skip(tcx, typing_env))] fn fn_sig_for_fn_abi<'tcx>( tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> ty::PolyFnSig<'tcx> { if let InstanceKind::ThreadLocalShim(..) = instance.def { return ty::Binder::dummy(tcx.mk_fn_sig( @@ -42,7 +42,7 @@ fn fn_sig_for_fn_abi<'tcx>( )); } - let ty = instance.ty(tcx, param_env); + let ty = instance.ty(tcx, typing_env); match *ty.kind() { ty::FnDef(..) => { // HACK(davidtwco,eddyb): This is a workaround for polymorphization considering @@ -56,7 +56,10 @@ fn fn_sig_for_fn_abi<'tcx>( ty::FnDef(def_id, args) => tcx .fn_sig(def_id) .map_bound(|fn_sig| { - tcx.normalize_erasing_regions(tcx.param_env(def_id), fn_sig) + tcx.normalize_erasing_regions( + ty::TypingEnv::non_body_analysis(tcx, def_id), + fn_sig, + ) }) .instantiate(tcx, args), _ => unreachable!(), @@ -329,27 +332,26 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv fn fn_abi_of_fn_ptr<'tcx>( tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)>, + query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)>, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { - let (param_env, (sig, extra_args)) = query.into_parts(); - - let cx = LayoutCx::new(tcx, param_env); + let ty::PseudoCanonicalInput { typing_env, value: (sig, extra_args) } = query; + let cx = LayoutCx::new(tcx, typing_env); fn_abi_new_uncached(&cx, sig, extra_args, None, None, false) } fn fn_abi_of_instance<'tcx>( tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)>, + query: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)>, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { - let (param_env, (instance, extra_args)) = query.into_parts(); + let ty::PseudoCanonicalInput { typing_env, value: (instance, extra_args) } = query; - let sig = fn_sig_for_fn_abi(tcx, instance, param_env); + let sig = fn_sig_for_fn_abi(tcx, instance, typing_env); let caller_location = instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty()); fn_abi_new_uncached( - &LayoutCx::new(tcx, param_env), + &LayoutCx::new(tcx, typing_env), sig, extra_args, caller_location, @@ -395,7 +397,7 @@ fn adjust_for_rust_scalar<'tcx>( Some(kind) } else if let Some(pointee) = drop_target_pointee { // The argument to `drop_in_place` is semantically equivalent to a mutable reference. - Some(PointerKind::MutableRef { unpin: pointee.is_unpin(tcx, cx.param_env()) }) + Some(PointerKind::MutableRef { unpin: pointee.is_unpin(tcx, cx.typing_env.param_env) }) } else { None }; @@ -542,7 +544,7 @@ fn fn_abi_sanity_check<'tcx>( // With metadata. Must be unsized and not on the stack. assert!(arg.layout.is_unsized() && !on_stack); // Also, must not be `extern` type. - let tail = tcx.struct_tail_for_codegen(arg.layout.ty, cx.param_env()); + let tail = tcx.struct_tail_for_codegen(arg.layout.ty, cx.typing_env); if matches!(tail.kind(), ty::Foreign(..)) { // These types do not have metadata, so having `meta_attrs` is bogus. // Conceptually, unsized arguments must be copied around, which requires dynamically @@ -573,7 +575,7 @@ fn fn_abi_new_uncached<'tcx>( force_thin_self_ptr: bool, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> { let tcx = cx.tcx(); - let sig = tcx.normalize_erasing_late_bound_regions(cx.param_env, sig); + let sig = tcx.normalize_erasing_late_bound_regions(cx.typing_env, sig); let conv = conv_from_spec_abi(cx.tcx(), sig.abi, sig.c_variadic); @@ -744,7 +746,7 @@ fn fn_abi_adjust_for_abi<'tcx>( #[tracing::instrument(level = "debug", skip(cx))] fn make_thin_self_ptr<'tcx>( - cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>), + cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>), layout: TyAndLayout<'tcx>, ) -> TyAndLayout<'tcx> { let tcx = cx.tcx(); @@ -784,6 +786,6 @@ fn make_thin_self_ptr<'tcx>( // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing the `Result` // should always work because the type is always `*mut ()`. - ..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap() + ..tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(unit_ptr_ty)).unwrap() } } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 1d8a0880760..84fc03a8f13 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -6,7 +6,9 @@ use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError}; use rustc_middle::ty::util::AsyncDropGlueMorphology; -use rustc_middle::ty::{self, GenericArgsRef, Instance, TyCtxt, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{ + self, GenericArgsRef, Instance, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, +}; use rustc_span::sym; use rustc_trait_selection::traits; use rustc_type_ir::ClosureKind; @@ -17,18 +19,18 @@ use crate::errors::UnexpectedFnPtrAssociatedItem; fn resolve_instance_raw<'tcx>( tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>, + key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>, ) -> Result>, ErrorGuaranteed> { - let (param_env, (def_id, args)) = key.into_parts(); + let PseudoCanonicalInput { typing_env, value: (def_id, args) } = key; let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) { - debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env); + debug!(" => associated item, attempting to find impl in typing_env {:#?}", typing_env); resolve_associated_item( tcx, def_id, - param_env, + typing_env, trait_def_id, - tcx.normalize_erasing_regions(param_env, args), + tcx.normalize_erasing_regions(typing_env, args), ) } else { let def = if tcx.intrinsic(def_id).is_some() { @@ -37,7 +39,7 @@ fn resolve_instance_raw<'tcx>( } else if tcx.is_lang_item(def_id, LangItem::DropInPlace) { let ty = args.type_at(0); - if ty.needs_drop(tcx, param_env) { + if ty.needs_drop(tcx, typing_env) { debug!(" => nontrivial drop glue"); match *ty.kind() { ty::Closure(..) @@ -93,15 +95,16 @@ fn resolve_instance_raw<'tcx>( fn resolve_associated_item<'tcx>( tcx: TyCtxt<'tcx>, trait_item_id: DefId, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, trait_id: DefId, rcvr_args: GenericArgsRef<'tcx>, ) -> Result>, ErrorGuaranteed> { - debug!(?trait_item_id, ?param_env, ?trait_id, ?rcvr_args, "resolve_associated_item"); + debug!(?trait_item_id, ?typing_env, ?trait_id, ?rcvr_args, "resolve_associated_item"); let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args); - let vtbl = match tcx.codegen_select_candidate((param_env, trait_ref)) { + let input = typing_env.as_query_input(trait_ref); + let vtbl = match tcx.codegen_select_candidate(input) { Ok(vtbl) => vtbl, Err( CodegenObligationError::Ambiguity @@ -116,7 +119,7 @@ fn resolve_associated_item<'tcx>( traits::ImplSource::UserDefined(impl_data) => { debug!( "resolving ImplSource::UserDefined: {:?}, {:?}, {:?}, {:?}", - param_env, trait_item_id, rcvr_args, impl_data + typing_env, trait_item_id, rcvr_args, impl_data ); assert!(!rcvr_args.has_infer()); assert!(!trait_ref.has_infer()); @@ -129,8 +132,9 @@ fn resolve_associated_item<'tcx>( .unwrap_or_else(|| { bug!("{:?} not found in {:?}", trait_item_id, impl_data.impl_def_id); }); - let infcx = tcx.infer_ctxt().build(TypingMode::PostAnalysis); - let param_env = param_env.with_reveal_all_normalized(tcx); + + let typing_env = typing_env.with_reveal_all_normalized(tcx); + let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); let args = rcvr_args.rebase_onto(tcx, trait_def_id, impl_data.args); let args = translate_args( &infcx, diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 63421dfdce6..02ee3f32915 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -19,7 +19,8 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, AdtDef, CoroutineArgsExt, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, + self, AdtDef, CoroutineArgsExt, EarlyBinder, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt, + TypeVisitableExt, }; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::sym; @@ -40,22 +41,22 @@ pub(crate) fn provide(providers: &mut Providers) { #[instrument(skip(tcx, query), level = "debug")] fn layout_of<'tcx>( tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> Result, &'tcx LayoutError<'tcx>> { - let (param_env, ty) = query.into_parts(); + let PseudoCanonicalInput { typing_env, value: ty } = query; debug!(?ty); // Optimization: We convert to RevealAll and convert opaque types in the where bounds // to their hidden types. This reduces overall uncached invocations of `layout_of` and // is thus a small performance improvement. - let param_env = param_env.with_reveal_all_normalized(tcx); + let typing_env = typing_env.with_reveal_all_normalized(tcx); let unnormalized_ty = ty; // FIXME: We might want to have two different versions of `layout_of`: // One that can be called after typecheck has completed and can use // `normalize_erasing_regions` here and another one that can be called // before typecheck has completed and uses `try_normalize_erasing_regions`. - let ty = match tcx.try_normalize_erasing_regions(param_env, ty) { + let ty = match tcx.try_normalize_erasing_regions(typing_env, ty) { Ok(t) => t, Err(normalization_error) => { return Err(tcx @@ -66,10 +67,10 @@ fn layout_of<'tcx>( if ty != unnormalized_ty { // Ensure this layout is also cached for the normalized type. - return tcx.layout_of(param_env.and(ty)); + return tcx.layout_of(typing_env.as_query_input(ty)); } - let cx = LayoutCx::new(tcx, param_env); + let cx = LayoutCx::new(tcx, typing_env); let layout = layout_of_uncached(&cx, ty)?; let layout = TyAndLayout { ty, layout }; @@ -104,7 +105,7 @@ fn map_error<'tcx>( // This is sometimes not a compile error if there are trivially false where clauses. // See `tests/ui/layout/trivial-bounds-sized.rs` for an example. assert!(field.layout.is_unsized(), "invalid layout error {err:#?}"); - if !field.ty.is_sized(cx.tcx(), cx.param_env) { + if !field.ty.is_sized(cx.tcx(), cx.typing_env.param_env) { cx.tcx().dcx().delayed_bug(format!( "encountered unexpected unsized field in layout of {ty:?}: {field:#?}" )); @@ -152,7 +153,6 @@ fn layout_of_uncached<'tcx>( } let tcx = cx.tcx(); - let param_env = cx.param_env; let dl = cx.data_layout(); let scalar_unit = |value: Primitive| { let size = value.size(dl); @@ -178,12 +178,12 @@ fn layout_of_uncached<'tcx>( { if let Some(start) = start { scalar.valid_range_mut().start = start - .try_to_bits(tcx, param_env) + .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; } if let Some(end) = end { let mut end = end - .try_to_bits(tcx, param_env) + .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; if !include_end { end = end.wrapping_sub(1); @@ -235,8 +235,8 @@ fn layout_of_uncached<'tcx>( data_ptr.valid_range_mut().start = 1; } - let pointee = tcx.normalize_erasing_regions(param_env, pointee); - if pointee.is_sized(tcx, param_env) { + let pointee = tcx.normalize_erasing_regions(cx.typing_env, pointee); + if pointee.is_sized(tcx, cx.typing_env.param_env) { return Ok(tcx.mk_layout(LayoutData::scalar(cx, data_ptr))); } @@ -247,7 +247,7 @@ fn layout_of_uncached<'tcx>( { let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]); let metadata_ty = - match tcx.try_normalize_erasing_regions(param_env, pointee_metadata) { + match tcx.try_normalize_erasing_regions(cx.typing_env, pointee_metadata) { Ok(metadata_ty) => metadata_ty, Err(mut err) => { // Usually `::Metadata` can't be normalized because @@ -259,7 +259,7 @@ fn layout_of_uncached<'tcx>( // that is an alias, which is likely the cause of the normalization // error. match tcx.try_normalize_erasing_regions( - param_env, + cx.typing_env, tcx.struct_tail_raw(pointee, |ty| ty, || {}), ) { Ok(_) => {} @@ -283,7 +283,7 @@ fn layout_of_uncached<'tcx>( metadata } else { - let unsized_part = tcx.struct_tail_for_codegen(pointee, param_env); + let unsized_part = tcx.struct_tail_for_codegen(pointee, cx.typing_env); match unsized_part.kind() { ty::Foreign(..) => { @@ -316,7 +316,7 @@ fn layout_of_uncached<'tcx>( // Arrays and slices. ty::Array(element, mut count) => { if count.has_aliases() { - count = tcx.normalize_erasing_regions(param_env, count); + count = tcx.normalize_erasing_regions(cx.typing_env, count); if count.has_aliases() { return Err(error(cx, LayoutError::Unknown(ty))); } @@ -331,7 +331,7 @@ fn layout_of_uncached<'tcx>( .checked_mul(count, dl) .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?; - let abi = if count != 0 && ty.is_privately_uninhabited(tcx, param_env) { + let abi = if count != 0 && ty.is_privately_uninhabited(tcx, cx.typing_env) { BackendRepr::Uninhabited } else { BackendRepr::Memory { sized: true } @@ -620,7 +620,11 @@ fn layout_of_uncached<'tcx>( // If the struct tail is sized and can be unsized, check that unsizing doesn't move the fields around. if cfg!(debug_assertions) && maybe_unsized - && def.non_enum_variant().tail().ty(tcx, args).is_sized(tcx, cx.param_env) + && def + .non_enum_variant() + .tail() + .ty(tcx, args) + .is_sized(tcx, cx.typing_env.param_env) { let mut variants = variants; let tail_replacement = cx.layout_of(Ty::new_slice(tcx, tcx.types.u8)).unwrap(); @@ -1024,7 +1028,7 @@ fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx>, layout: TyAndLayout<'tc // Ignore layouts that are done with non-empty environments or // non-monomorphic layouts, as the user only wants to see the stuff // resulting from the final codegen session. - if layout.ty.has_non_region_param() || !cx.param_env.caller_bounds().is_empty() { + if layout.ty.has_non_region_param() || !cx.typing_env.param_env.caller_bounds().is_empty() { return; } diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index fc05dd8256b..26ea81daf78 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -9,7 +9,7 @@ pub(super) fn partially_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLa let tcx = cx.tcx(); // Type-level uninhabitedness should always imply ABI uninhabitedness. - if layout.ty.is_privately_uninhabited(tcx, cx.param_env) { + if layout.ty.is_privately_uninhabited(tcx, cx.typing_env) { assert!(layout.is_uninhabited()); } diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 5fecbd310b7..d462dbd9416 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -14,14 +14,17 @@ use crate::errors::NeedsDropOverflow; type NeedsDropResult = Result; -fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { +fn needs_drop_raw<'tcx>( + tcx: TyCtxt<'tcx>, + query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>, +) -> bool { // If we don't know a type doesn't need drop, for example if it's a type // parameter without a `Copy` bound, then we conservatively return that it // needs drop. let adt_has_dtor = |adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant); - let res = drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false) - .filter(filter_array_elements(tcx, query.param_env)) + let res = drop_tys_helper(tcx, query.value, query.typing_env, adt_has_dtor, false) + .filter(filter_array_elements(tcx, query.typing_env)) .next() .is_some(); @@ -29,14 +32,17 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx> res } -fn needs_async_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { +fn needs_async_drop_raw<'tcx>( + tcx: TyCtxt<'tcx>, + query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>, +) -> bool { // If we don't know a type doesn't need async drop, for example if it's a // type parameter without a `Copy` bound, then we conservatively return that // it needs async drop. let adt_has_async_dtor = |adt_def: ty::AdtDef<'tcx>| adt_def.async_destructor(tcx).map(|_| DtorType::Significant); - let res = drop_tys_helper(tcx, query.value, query.param_env, adt_has_async_dtor, false) - .filter(filter_array_elements(tcx, query.param_env)) + let res = drop_tys_helper(tcx, query.value, query.typing_env, adt_has_async_dtor, false) + .filter(filter_array_elements(tcx, query.typing_env)) .next() .is_some(); @@ -50,11 +56,11 @@ fn needs_async_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty /// logic that is easier to follow while not repeating any checks that may thus diverge. fn filter_array_elements<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ) -> impl Fn(&Result, AlwaysRequiresDrop>) -> bool { move |ty| match ty { Ok(ty) => match *ty.kind() { - ty::Array(elem, _) => tcx.needs_drop_raw(param_env.and(elem)), + ty::Array(elem, _) => tcx.needs_drop_raw(typing_env.as_query_input(elem)), _ => true, }, Err(AlwaysRequiresDrop) => true, @@ -63,16 +69,16 @@ fn filter_array_elements<'tcx>( fn has_significant_drop_raw<'tcx>( tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> bool { let res = drop_tys_helper( tcx, query.value, - query.param_env, + query.typing_env, adt_consider_insignificant_dtor(tcx), true, ) - .filter(filter_array_elements(tcx, query.param_env)) + .filter(filter_array_elements(tcx, query.typing_env)) .next() .is_some(); debug!("has_significant_drop_raw({:?}) = {:?}", query, res); @@ -81,7 +87,7 @@ fn has_significant_drop_raw<'tcx>( struct NeedsDropTypes<'tcx, F> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, // Whether to reveal coroutine witnesses, this is set // to `false` unless we compute `needs_drop` for a coroutine witness. reveal_coroutine_witnesses: bool, @@ -99,7 +105,7 @@ struct NeedsDropTypes<'tcx, F> { impl<'tcx, F> NeedsDropTypes<'tcx, F> { fn new( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, adt_components: F, ) -> Self { @@ -107,7 +113,7 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> { seen_tys.insert(ty); Self { tcx, - param_env, + typing_env, reveal_coroutine_witnesses: false, seen_tys, query_ty: ty, @@ -180,7 +186,7 @@ where } } - _ if component.is_copy_modulo_regions(tcx, self.param_env) => (), + _ if component.is_copy_modulo_regions(tcx, self.typing_env.param_env) => (), ty::Closure(_, args) => { for upvar in args.as_closure().upvar_tys() { @@ -204,7 +210,7 @@ where }; for required_ty in tys { let required = tcx - .try_normalize_erasing_regions(self.param_env, required_ty) + .try_normalize_erasing_regions(self.typing_env, required_ty) .unwrap_or(required_ty); queue_type(self, required); @@ -271,7 +277,7 @@ enum DtorType { fn drop_tys_helper<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, - param_env: rustc_middle::ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, adt_has_dtor: impl Fn(ty::AdtDef<'tcx>) -> Option, only_significant: bool, ) -> impl Iterator>> { @@ -337,7 +343,7 @@ fn drop_tys_helper<'tcx>( .map(|v| v.into_iter()) }; - NeedsDropTypes::new(tcx, param_env, ty, adt_components) + NeedsDropTypes::new(tcx, typing_env, ty, adt_components) } fn adt_consider_insignificant_dtor<'tcx>( @@ -375,7 +381,7 @@ fn adt_drop_tys<'tcx>( drop_tys_helper( tcx, tcx.type_of(def_id).instantiate_identity(), - tcx.param_env(def_id), + ty::TypingEnv::non_body_analysis(tcx, def_id), adt_has_dtor, false, ) @@ -392,7 +398,7 @@ fn adt_significant_drop_tys( drop_tys_helper( tcx, tcx.type_of(def_id).instantiate_identity(), // identical to `tcx.make_adt(def, identity_args)` - tcx.param_env(def_id), + ty::TypingEnv::non_body_analysis(tcx, def_id), adt_consider_insignificant_dtor(tcx), true, ) diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index aadb64f45d7..105ae76708b 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -1,6 +1,7 @@ use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use crate::fold::TypeFoldable; use crate::inherent::*; @@ -20,6 +21,7 @@ use crate::{self as ty, Interner}; /// If neither of these functions are available, feel free to reach out to /// t-types for help. #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum TypingMode { /// When checking whether impls overlap, we check whether any obligations diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 36ddddccfa2..f988f003c0f 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -13,7 +13,7 @@ use crate::lang_items::TraitSolverLangItem; use crate::relate::Relate; use crate::solve::{CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{self as ty, search_graph}; +use crate::{self as ty, TypingMode, search_graph}; pub trait Interner: Sized @@ -277,7 +277,12 @@ pub trait Interner: fn coroutine_is_gen(self, coroutine_def_id: Self::DefId) -> bool; fn coroutine_is_async_gen(self, coroutine_def_id: Self::DefId) -> bool; - fn layout_is_pointer_like(self, param_env: Self::ParamEnv, ty: Self::Ty) -> bool; + fn layout_is_pointer_like( + self, + typing_mode: TypingMode, + param_env: Self::ParamEnv, + ty: Self::Ty, + ) -> bool; type UnsizingParams: Deref>; fn unsizing_params_for_adt(self, adt_def_id: Self::DefId) -> Self::UnsizingParams; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9e11360cab4..f0787d286fd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1819,8 +1819,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T { // Only anon consts can implicitly capture params. // FIXME: is this correct behavior? - let param_env = cx.tcx.param_env(*def_id); - cx.tcx.normalize_erasing_regions(param_env, ct) + let typing_env = ty::TypingEnv::from_param_env(cx.tcx.param_env(*def_id)); + cx.tcx.normalize_erasing_regions(typing_env, ct) } else { ct }; @@ -2039,7 +2039,7 @@ pub(crate) fn clean_middle_ty<'tcx>( format!("{pat:?}").into_boxed_str(), ), ty::Array(ty, n) => { - let n = cx.tcx.normalize_erasing_regions(cx.param_env, n); + let n = cx.tcx.normalize_erasing_regions(cx.typing_env(), n); let n = print_const(cx, n); Array(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None)), n.into()) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index e3a0dbe1a7f..a10a6a92bf5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -772,8 +772,10 @@ impl Item { .find(|field| { let ty = field.ty(tcx, ty::GenericArgs::identity_for_item(tcx, field.did)); - tcx.layout_of(tcx.param_env(field.did).and(ty)) - .is_ok_and(|layout| !layout.is_1zst()) + tcx.layout_of( + ty::TypingEnv::post_analysis(tcx, field.did).as_query_input(ty), + ) + .is_ok_and(|layout| !layout.is_1zst()) }) .map_or_else( || adt.all_fields().any(|field| field.vis.is_public()), diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index e551e0170c6..d59b4e4081c 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -419,7 +419,10 @@ fn print_const_with_custom_print_scalar<'tcx>( } (mir::Const::Val(mir::ConstValue::Scalar(int), _), ty::Int(i)) => { let ty = ct.ty(); - let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; + let size = tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .unwrap() + .size; let sign_extended_data = int.assert_scalar_int().to_int(size); let mut output = if with_underscores { format_integer_with_underscore_sep(&sign_extended_data.to_string()) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index d5f6bfe415d..a562a9eee71 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -19,7 +19,7 @@ use rustc_hir::{HirId, Path}; use rustc_interface::interface; use rustc_lint::{MissingDoc, late_lint_mod}; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks}; pub(crate) use rustc_session::config::{Options, UnstableOptions}; use rustc_session::{Session, lint}; @@ -88,6 +88,13 @@ impl<'tcx> DocContext<'tcx> { ret } + pub(crate) fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv { + typing_mode: ty::TypingMode::non_body_analysis(), + param_env: self.param_env, + } + } + /// Call the closure with the given parameters set as /// the generic parameters for a type alias' RHS. pub(crate) fn enter_alias( diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index d85ba3a2b14..9317844956d 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -37,9 +37,9 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>( } let tcx = cx.tcx(); - let param_env = tcx.param_env(ty_def_id); + let typing_env = ty::TypingEnv::post_analysis(tcx, ty_def_id); let ty = tcx.type_of(ty_def_id).instantiate_identity(); - let type_layout = tcx.layout_of(param_env.and(ty)); + let type_layout = tcx.layout_of(typing_env.as_query_input(ty)); let variants = if let Ok(type_layout) = type_layout && let Variants::Multiple { variants, tag, tag_encoding, .. } = @@ -71,7 +71,7 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>( Vec::new() }; - let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| { + let type_layout_size = tcx.layout_of(typing_env.as_query_input(ty)).map(|layout| { let is_unsized = layout.is_unsized(); let is_uninhabited = layout.is_uninhabited(); let size = layout.size.bytes(); diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs index 0b82c0cd04c..00626a37ef8 100644 --- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs +++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs @@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones { }, _ => return, } - && let Ok(Some(resolved_fn)) = Instance::try_resolve(cx.tcx, cx.param_env, fn_id, fn_gen_args) + && let Ok(Some(resolved_fn)) = Instance::try_resolve(cx.tcx, cx.typing_env(), fn_id, fn_gen_args) // TODO: This check currently bails if the local variable has no initializer. // That is overly conservative - the lint should fire even if there was no initializer, // but the variable has been initialized before `lhs` was evaluated. diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index 7d89195eeca..adac2f27ea8 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -62,7 +62,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) - }) .is_some_and(|assoc_item| { let proj = Ty::new_projection(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, [])); - let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); + let nty = cx.tcx.normalize_erasing_regions(cx.typing_env(), proj); nty.is_bool() }) diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index b167d7f2208..f864b7a5a8a 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -17,7 +17,7 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypeckResults}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults}; use rustc_session::impl_lint_pass; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; @@ -755,7 +755,8 @@ impl TyCoercionStability { DefinedTy::Hir(ty) => Self::for_hir_ty(ty), DefinedTy::Mir(ty) => Self::for_mir_ty( cx.tcx, - ty.param_env, + // FIXME(#132279): convert `DefinedTy` to use `TypingEnv` instead. + ty::TypingEnv::from_param_env(ty.param_env), cx.tcx.instantiate_bound_regions_with_erased(ty.value), for_return, ), @@ -823,12 +824,12 @@ impl TyCoercionStability { } } - fn for_mir_ty<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, for_return: bool) -> Self { + fn for_mir_ty<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, for_return: bool) -> Self { let ty::Ref(_, mut ty, _) = *ty.kind() else { return Self::None; }; - ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty); + ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); loop { break match *ty.kind() { ty::Ref(_, ref_ty, _) => { diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index 55afdbf22e1..617982f4da3 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -99,7 +99,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { sym::mem_forget if is_copy => return, sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => return, sym::mem_drop - if !(arg_ty.needs_drop(cx.tcx, cx.param_env) + if !(arg_ty.needs_drop(cx.tcx, cx.typing_env()) || is_must_use_func_call(cx, arg) || is_must_use_ty(cx, arg_ty) || drop_is_single_call_in_arm) => @@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { (DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into(), Some(arg.span)) }, sym::mem_forget => { - if arg_ty.needs_drop(cx.tcx, cx.param_env) { + if arg_ty.needs_drop(cx.tcx, cx.typing_env()) { ( MEM_FORGET, Cow::Owned(format!( diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs index 25105817ad9..4bc6ad0798c 100644 --- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs @@ -70,7 +70,7 @@ fn check_sig(cx: &LateContext<'_>, name: Symbol, sig: &FnSig<'_>, fn_id: LocalDe .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(fn_id).instantiate_identity().output()); let ret_ty = cx .tcx - .try_normalize_erasing_regions(cx.param_env, ret_ty) + .try_normalize_erasing_regions(cx.typing_env(), ret_ty) .unwrap_or(ret_ty); if cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs index 314d0dfa26c..906da81b183 100644 --- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs +++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs @@ -215,7 +215,7 @@ impl {self_ty_without_ref} {{ && implements_trait(cx, ret_ty, iterator_did, &[]) && let Some(iter_ty) = make_normalized_projection( cx.tcx, - cx.param_env, + cx.typing_env(), iterator_did, sym::Item, [ret_ty], diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index c5a2760234f..644365c9fe5 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -4,7 +4,7 @@ use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, ParamEnv}; +use rustc_middle::ty; use rustc_session::impl_lint_pass; use rustc_span::{BytePos, Pos, Span}; @@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let ty::Array(element_type, cst) = ty.kind() && let Some((ty::ValTree::Leaf(element_count), _)) = cx.tcx - .try_normalize_erasing_regions(ParamEnv::empty(), *cst).unwrap_or(*cst).try_to_valtree() + .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_valtree() && let element_count = element_count.to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size) diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs index 25f9be8b2d7..593704f206a 100644 --- a/src/tools/clippy/clippy_lints/src/large_futures.rs +++ b/src/tools/clippy/clippy_lints/src/large_futures.rs @@ -63,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeFuture { && let ty = cx.typeck_results().expr_ty(arg) && let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() && implements_trait(cx, ty, future_trait_def_id, &[]) - && let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)) + && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty)) && let size = layout.layout.size() && size >= Size::from_bytes(self.future_size_threshold) { diff --git a/src/tools/clippy/clippy_lints/src/large_stack_frames.rs b/src/tools/clippy/clippy_lints/src/large_stack_frames.rs index d2bdf194ada..5ed948c02bb 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_frames.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_frames.rs @@ -150,11 +150,11 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackFrames { } let mir = cx.tcx.optimized_mir(def_id); - let param_env = cx.tcx.param_env(def_id); + let typing_env = mir.typing_env(cx.tcx); let sizes_of_locals = || { mir.local_decls.iter().filter_map(|local| { - let layout = cx.tcx.layout_of(param_env.and(local.ty)).ok()?; + let layout = cx.tcx.layout_of(typing_env.as_query_input(local.ty)).ok()?; Some((local, layout.size.bytes())) }) }; diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index ee561ea85ed..48318682f33 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -151,7 +151,7 @@ fn is_ref_iterable<'tcx>( // Using by value won't consume anything if implements_trait(cx, self_ty, trait_id, &[]) && let Some(ty) = - make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty]) + make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty]) && ty == res_ty { return Some((AdjustKind::None, self_ty)); @@ -168,7 +168,7 @@ fn is_ref_iterable<'tcx>( }; if implements_trait(cx, self_ty, trait_id, &[]) && let Some(ty) = - make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty]) + make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty]) && ty == res_ty { return Some((AdjustKind::reborrow(mutbl), self_ty)); @@ -181,7 +181,7 @@ fn is_ref_iterable<'tcx>( // Attempt to borrow let self_ty = Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, self_ty, mutbl); if implements_trait(cx, self_ty, trait_id, &[]) - && let Some(ty) = make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty]) + && let Some(ty) = make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty]) && ty == res_ty { return Some((AdjustKind::borrow(mutbl), self_ty)); @@ -204,7 +204,7 @@ fn is_ref_iterable<'tcx>( && target != self_ty && implements_trait(cx, target, trait_id, &[]) && let Some(ty) = - make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) + make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target]) && ty == res_ty { Some((AdjustKind::auto_reborrow(mutbl), target)) @@ -222,7 +222,7 @@ fn is_ref_iterable<'tcx>( if is_copy(cx, target) && implements_trait(cx, target, trait_id, &[]) && let Some(ty) = - make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) + make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target]) && ty == res_ty { Some((AdjustKind::Deref, target)) @@ -240,7 +240,7 @@ fn is_ref_iterable<'tcx>( if self_ty.is_ref() && implements_trait(cx, target, trait_id, &[]) && let Some(ty) = - make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) + make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target]) && ty == res_ty { Some((AdjustKind::auto_borrow(mutbl), target)) diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 9c41528e647..c00b9b368c4 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -203,10 +203,10 @@ fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool { fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: Ty<'tcx>) -> bool { if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator) && let Some(into_iter_trait) = cx.tcx.get_diagnostic_item(sym::IntoIterator) - && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.param_env, iter_trait, sym::Item, [iter_ty]) + && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.typing_env(), iter_trait, sym::Item, [iter_ty]) && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty]) && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( - cx.param_env, + cx.typing_env(), Ty::new_projection_from_args(cx.tcx, into_iter_item_proj.def_id, into_iter_item_proj.args), ) { @@ -237,7 +237,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - ) && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) && let proj_ty = Ty::new_projection_from_args(cx.tcx, iter_item.def_id, args) - && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) + && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), proj_ty) { item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id)) } else { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs index 062d1348555..7d01bdc2269 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>( arg: &'tcx Expr<'_>, ) { let typeck_results = cx.typeck_results(); - let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.param_env, typeck_results); + let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), typeck_results); if let Some(id) = typeck_results.type_dependent_def_id(expr.hir_id) && (cx.tcx.is_diagnostic_item(sym::cmp_ord_min, id) || cx.tcx.is_diagnostic_item(sym::cmp_ord_max, id)) { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 82549413fa9..84ea3554a35 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -578,7 +578,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< if output_ty.contains(param_ty) { if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions( new_subst, - cx.param_env, + cx.typing_env(), bound_fn_sig.rebind(output_ty), ) { expr = parent_expr; diff --git a/src/tools/clippy/clippy_lints/src/methods/zst_offset.rs b/src/tools/clippy/clippy_lints/src/methods/zst_offset.rs index d33021c2a7b..102fa7bc895 100644 --- a/src/tools/clippy/clippy_lints/src/methods/zst_offset.rs +++ b/src/tools/clippy/clippy_lints/src/methods/zst_offset.rs @@ -7,7 +7,7 @@ use super::ZST_OFFSET; pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) { if let ty::RawPtr(ty, _) = cx.typeck_results().expr_ty(recv).kind() - && let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(*ty)) + && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(*ty)) && layout.is_zst() { span_lint(cx, ZST_OFFSET, expr.span, "offset calculation on zero-sized value"); diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index c1424b9f1dc..43b885fbd2c 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -421,7 +421,7 @@ fn replace_types<'tcx>( .expect_ty(cx.tcx) .to_ty(cx.tcx); - if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection) + if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), projection) && args[term_param_ty.index as usize] != GenericArg::from(projected_ty) { deque.push_back((*term_param_ty, projected_ty)); diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 5e20b406426..57fa4797c5e 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -278,23 +278,23 @@ impl<'tcx> NonCopyConst<'tcx> { fn is_value_unfrozen_expr(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { let args = cx.typeck_results().node_args(hir_id); - let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), DUMMY_SP); + let result = Self::const_eval_resolve(cx.tcx, cx.typing_env(), ty::UnevaluatedConst::new(def_id, args), DUMMY_SP); Self::is_value_unfrozen_raw(cx, result, ty) } pub fn const_eval_resolve( tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, ct: ty::UnevaluatedConst<'tcx>, span: Span, ) -> EvalToValTreeResult<'tcx> { - match ty::Instance::try_resolve(tcx, param_env, ct.def, ct.args) { + match ty::Instance::try_resolve(tcx, typing_env, ct.def, ct.args) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: None, }; - tcx.const_eval_global_id_for_typeck(param_env, cid, span) + tcx.const_eval_global_id_for_typeck(typing_env.param_env, cid, span) }, Ok(None) => Err(ErrorHandled::TooGeneric(span)), Err(err) => Err(ErrorHandled::Reported(err.into(), span)), @@ -321,7 +321,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { // Normalize assoc types because ones originated from generic params // bounded other traits could have their bound. - let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty); + let normalized = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); if self.interior_mut.is_interior_mut_ty(cx, normalized) // When there's no default value, lint it only according to its type; // in other words, lint consts whose value *could* be unfrozen, not definitely is. @@ -361,12 +361,12 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { .trait_item_def_id && cx .tcx - .layout_of(cx.tcx.param_env(of_trait_def_id).and( + .layout_of(ty::TypingEnv::post_analysis(cx.tcx, of_trait_def_id).as_query_input( // Normalize assoc types because ones originated from generic params // bounded other traits could have their bound at the trait defs; // and, in that case, the definition is *not* generic. cx.tcx.normalize_erasing_regions( - cx.tcx.param_env(of_trait_def_id), + ty::TypingEnv::post_analysis(cx.tcx, of_trait_def_id), cx.tcx.type_of(of_assoc_item).instantiate_identity(), ), )) @@ -376,7 +376,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { // similar to unknown layouts. // e.g. `layout_of(...).is_err() || has_frozen_variant(...);` && let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity() - && let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty) + && let normalized = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty) && self.interior_mut.is_interior_mut_ty(cx, normalized) && Self::is_value_unfrozen_poly(cx, *body_id, normalized) { @@ -386,7 +386,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { ItemKind::Impl(Impl { of_trait: None, .. }) => { let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity(); // Normalize assoc types originated from generic params. - let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty); + let normalized = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); if self.interior_mut.is_interior_mut_ty(cx, normalized) && Self::is_value_unfrozen_poly(cx, *body_id, normalized) diff --git a/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs b/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs index 5d94cfab3b0..1a0bfd8b997 100644 --- a/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs @@ -26,7 +26,7 @@ fn comparison_to_const<'tcx>( if let ExprKind::Binary(operator, left, right) = expr.kind && let Ok(cmp_op) = CmpOp::try_from(operator.node) { - let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.param_env, typeck); + let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), typeck); match (ecx.eval(left), ecx.eval(right)) { (Some(_), Some(_)) => None, (_, Some(con)) => Some((cmp_op, left, right, con, typeck.expr_ty(right))), diff --git a/src/tools/clippy/clippy_lints/src/operators/erasing_op.rs b/src/tools/clippy/clippy_lints/src/operators/erasing_op.rs index 24bfe2b050b..e3fc8d8fea7 100644 --- a/src/tools/clippy/clippy_lints/src/operators/erasing_op.rs +++ b/src/tools/clippy/clippy_lints/src/operators/erasing_op.rs @@ -39,7 +39,7 @@ fn check_op<'tcx>( other: &Expr<'tcx>, parent: &Expr<'tcx>, ) { - if ConstEvalCtxt::with_env(cx.tcx, cx.param_env, tck).eval_simple(op) == Some(Constant::Int(0)) { + if ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), tck).eval_simple(op) == Some(Constant::Int(0)) { if different_types(tck, other, parent) { return; } diff --git a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs index ab5f91c1d67..8272d3643d4 100644 --- a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs +++ b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs @@ -17,8 +17,7 @@ pub(crate) fn check<'tcx>( right: &'tcx Expr<'_>, ) { if (op == BinOpKind::Eq || op == BinOpKind::Ne) && is_float(cx, left) { - let typeck = cx.typeck_results(); - let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.param_env, typeck); + let ecx = ConstEvalCtxt::new(cx); let left_is_local = match ecx.eval_with_source(left) { Some((c, s)) if !is_allowed(&c) => s.is_local(), Some(_) => return, diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index dc66fb28fa8..0ac818c21d9 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -136,7 +136,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { }); } else if let Some(target_id) = cx.tcx.lang_items().deref_target() { if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( - cx.param_env, + cx.typing_env(), Ty::new_projection_from_args(cx.tcx, target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])), ) { if deref_ty == expr_ty { diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index 1e0f6dff1ab..aeff31d02d2 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -391,7 +391,7 @@ fn check_final_expr<'tcx>( if let Some(inner) = inner { if for_each_unconsumed_temporary(cx, inner, |temporary_ty| { - if temporary_ty.has_significant_drop(cx.tcx, cx.param_env) + if temporary_ty.has_significant_drop(cx.tcx, cx.typing_env()) && temporary_ty .walk() .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(re) if !re.is_static())) diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index abd8363456d..1a5b958e6a6 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -154,7 +154,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> { let ty = self .cx .tcx - .try_normalize_erasing_regions(self.cx.param_env, ty) + .try_normalize_erasing_regions(self.cx.typing_env(), ty) .unwrap_or(ty); match self.type_cache.entry(ty) { Entry::Occupied(e) => return *e.get(), diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index 52bb7c4bd68..50a1577b288 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -58,7 +58,7 @@ fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: && let Some(last_field) = data.fields().last() && let field_ty = cx .tcx - .normalize_erasing_regions(cx.param_env, cx.tcx.type_of(last_field.def_id).instantiate_identity()) + .normalize_erasing_regions(cx.typing_env(), cx.tcx.type_of(last_field.def_id).instantiate_identity()) && let ty::Array(_, array_len) = *field_ty.kind() && let Some(0) = array_len.try_to_target_usize(cx.tcx) { diff --git a/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs index ca9daf2d2a0..1209bd5b34f 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs @@ -88,8 +88,8 @@ pub(super) fn check<'tcx>( && is_normalizable(cx, cx.param_env, to_ty) // we only want to lint if the target type has a niche that is larger than the one of the source type // e.g. `u8` to `NonZero` should lint, but `NonZero` to `u8` should not - && let Ok(from_layout) = cx.tcx.layout_of(cx.param_env.and(from_ty)) - && let Ok(to_layout) = cx.tcx.layout_of(cx.param_env.and(to_ty)) + && let Ok(from_layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(from_ty)) + && let Ok(to_layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(to_ty)) && match (from_layout.largest_niche, to_layout.largest_niche) { (Some(from_niche), Some(to_niche)) => !range_fully_contained(from_niche.valid_range, to_niche.valid_range), (None, Some(_)) => true, diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index 3b32e4396b9..4dc1290e8b1 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -244,7 +244,7 @@ enum ReducedTy<'tcx> { /// Reduce structs containing a single non-zero sized field to it's contained type. fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> { loop { - ty = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty).unwrap_or(ty); + ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty); return match *ty.kind() { ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => { ReducedTy::TypeErasure { raw_ptr_only: false } @@ -297,8 +297,8 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> } fn is_zero_sized_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - if let Ok(ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty) - && let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)) + if let Ok(ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) + && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty)) { layout.layout.size().bytes() == 0 } else { diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs index e8ccd35b4da..5baa67b1f3e 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs @@ -4,10 +4,11 @@ use rustc_middle::ty::Ty; // check if the component types of the transmuted collection and the result have different ABI, // size or alignment pub(super) fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool { - if let Ok(from) = cx.tcx.try_normalize_erasing_regions(cx.param_env, from) - && let Ok(to) = cx.tcx.try_normalize_erasing_regions(cx.param_env, to) - && let Ok(from_layout) = cx.tcx.layout_of(cx.param_env.and(from)) - && let Ok(to_layout) = cx.tcx.layout_of(cx.param_env.and(to)) + let typing_env = cx.typing_env(); + if let Ok(from) = cx.tcx.try_normalize_erasing_regions(typing_env, from) + && let Ok(to) = cx.tcx.try_normalize_erasing_regions(typing_env, to) + && let Ok(from_layout) = cx.tcx.layout_of(typing_env.as_query_input(from)) + && let Ok(to_layout) = cx.tcx.layout_of(typing_env.as_query_input(to)) { from_layout.size != to_layout.size || from_layout.align.abi != to_layout.align.abi } else { diff --git a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs index cfa565cf803..ee9ef017253 100644 --- a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs +++ b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs @@ -46,7 +46,7 @@ impl LateLintPass<'_> for UninhabitedReferences { if let ExprKind::Unary(UnOp::Deref, _) = expr.kind { let ty = cx.typeck_results().expr_ty_adjusted(expr); - if ty.is_privately_uninhabited(cx.tcx, cx.param_env) { + if ty.is_privately_uninhabited(cx.tcx, cx.typing_env()) { span_lint( cx, UNINHABITED_REFERENCES, @@ -71,7 +71,7 @@ impl LateLintPass<'_> for UninhabitedReferences { } if let FnRetTy::Return(hir_ty) = fndecl.output && let TyKind::Ref(_, mut_ty) = hir_ty.kind - && lower_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env) + && lower_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.typing_env()) { span_lint( cx, diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 24a02c7ef87..52c98646289 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -18,7 +18,7 @@ use rustc_lexer::tokenize; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; use rustc_middle::mir::interpret::{Scalar, alloc_range}; -use rustc_middle::ty::{self, FloatTy, IntTy, ParamEnv, ScalarInt, Ty, TyCtxt, TypeckResults, UintTy}; +use rustc_middle::ty::{self, FloatTy, IntTy, ScalarInt, Ty, TyCtxt, TypeckResults, UintTy}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::def_id::DefId; use rustc_span::symbol::Ident; @@ -387,7 +387,7 @@ impl Ord for FullInt { /// See the module level documentation for some context. pub struct ConstEvalCtxt<'tcx> { tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, typeck: &'tcx TypeckResults<'tcx>, source: Cell, } @@ -398,17 +398,17 @@ impl<'tcx> ConstEvalCtxt<'tcx> { pub fn new(cx: &LateContext<'tcx>) -> Self { Self { tcx: cx.tcx, - param_env: cx.param_env, + typing_env: cx.typing_env(), typeck: cx.typeck_results(), source: Cell::new(ConstantSource::Local), } } /// Creates an evaluation context. - pub fn with_env(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, typeck: &'tcx TypeckResults<'tcx>) -> Self { + pub fn with_env(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, typeck: &'tcx TypeckResults<'tcx>) -> Self { Self { tcx, - param_env, + typing_env, typeck, source: Cell::new(ConstantSource::Local), } @@ -643,7 +643,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { let args = self.typeck.node_args(id); let result = self .tcx - .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), qpath.span()) + .const_eval_resolve(self.typing_env, mir::UnevaluatedConst::new(def_id, args), qpath.span()) .ok() .map(|val| mir::Const::from_value(val, ty))?; f(self, result) diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index a2e97919d04..7f0363ac942 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -105,7 +105,7 @@ fn res_has_significant_drop(res: Res, cx: &LateContext<'_>, e: &Expr<'_>) -> boo { cx.typeck_results() .expr_ty(e) - .has_significant_drop(cx.tcx, cx.param_env) + .has_significant_drop(cx.tcx, cx.typing_env()) } else { false } diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index c73ab4bfa68..ea866a78d87 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -297,8 +297,8 @@ impl HirEqInterExpr<'_, '_, '_> { if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results && typeck_lhs.expr_ty(left) == typeck_rhs.expr_ty(right) && let (Some(l), Some(r)) = ( - ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.param_env, typeck_lhs).eval_simple(left), - ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.param_env, typeck_rhs).eval_simple(right), + ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.typing_env(), typeck_lhs).eval_simple(left), + ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.typing_env(), typeck_rhs).eval_simple(right), ) && l == r { @@ -813,7 +813,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { #[expect(clippy::too_many_lines)] pub fn hash_expr(&mut self, e: &Expr<'_>) { let simple_const = self.maybe_typeck_results.and_then(|typeck_results| { - ConstEvalCtxt::with_env(self.cx.tcx, self.cx.param_env, typeck_results).eval_simple(e) + ConstEvalCtxt::with_env(self.cx.tcx, self.cx.typing_env(), typeck_results).eval_simple(e) }); // const hashing may result in the same hash as some unrelated node, so add a sort of diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 19316a90683..f28e5c9ed0e 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1631,7 +1631,7 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool } let enclosing_body = cx.tcx.hir().enclosing_body_owner(e.hir_id); if let Some(Constant::Int(v)) = - ConstEvalCtxt::with_env(cx.tcx, cx.tcx.param_env(enclosing_body), cx.tcx.typeck(enclosing_body)).eval(e) + ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), cx.tcx.typeck(enclosing_body)).eval(e) { return value == v; } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 971f8eeb1b3..abadca71400 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -142,7 +142,7 @@ fn check_rvalue<'tcx>( // We cannot allow this for now. return Err((span, "unsizing casts are only allowed for references right now".into())); }; - let unsized_ty = tcx.struct_tail_for_codegen(pointee_ty, tcx.param_env(def_id)); + let unsized_ty = tcx.struct_tail_for_codegen(pointee_ty, ty::TypingEnv::post_analysis(tcx, def_id)); if let ty::Slice(_) | ty::Str = unsized_ty.kind() { check_operand(tcx, op, span, body, msrv)?; // Casting/coercing things to slices is fine. @@ -408,15 +408,17 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx> return true; } + + let (infcx, param_env) = + tcx.infer_ctxt().build_with_typing_env(body.typing_env(tcx)); // FIXME(const_trait_impl) constness let obligation = Obligation::new( tcx, ObligationCause::dummy_with_span(body.span), - ConstCx::new(tcx, body).param_env, + param_env, TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]), ); - let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx)); let mut selcx = SelectionContext::new(&infcx); let Some(impl_src) = selcx.select(&obligation).ok().flatten() else { return false; @@ -434,5 +436,5 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx> ocx.select_all_or_error().is_empty() } - !ty.needs_drop(tcx, ConstCx::new(tcx, body).param_env) + !ty.needs_drop(tcx, ConstCx::new(tcx, body).typing_env) } diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 770cd9c3786..2aad867dc0d 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -467,7 +467,7 @@ pub fn needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { if !seen.insert(ty) { return false; } - if !ty.has_significant_drop(cx.tcx, cx.param_env) { + if !ty.has_significant_drop(cx.tcx, cx.typing_env()) { false } // Check for std types which implement drop, but only for memory allocation. @@ -575,8 +575,9 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { /// Checks if a given type looks safe to be uninitialized. pub fn is_uninit_value_valid_for_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + let typing_env = cx.typing_env().with_reveal_all_normalized(cx.tcx); cx.tcx - .check_validity_requirement((ValidityRequirement::Uninit, cx.param_env.and(ty))) + .check_validity_requirement((ValidityRequirement::Uninit, typing_env.as_query_input(ty))) .unwrap_or_else(|_| is_uninit_value_valid_for_ty_fallback(cx, ty)) } @@ -725,7 +726,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option None, } }, - ty::Alias(ty::Projection, proj) => match cx.tcx.try_normalize_erasing_regions(cx.param_env, ty) { + ty::Alias(ty::Projection, proj) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) { Ok(normalized_ty) if normalized_ty != ty => ty_sig(cx, normalized_ty), _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None)), }, @@ -1111,12 +1112,12 @@ pub fn make_projection<'tcx>( /// succeeds as well as everything checked by `make_projection`. pub fn make_normalized_projection<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, container_id: DefId, assoc_ty: Symbol, args: impl IntoIterator>>, ) -> Option> { - fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option> { + fn helper<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: AliasTy<'tcx>) -> Option> { #[cfg(debug_assertions)] if let Some((i, arg)) = ty .args @@ -1132,7 +1133,7 @@ pub fn make_normalized_projection<'tcx>( ); return None; } - match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) { + match tcx.try_normalize_erasing_regions(typing_env, Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) { Ok(ty) => Some(ty), Err(e) => { debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}"); @@ -1140,7 +1141,7 @@ pub fn make_normalized_projection<'tcx>( }, } } - helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?) + helper(tcx, typing_env, make_projection(tcx, container_id, assoc_ty, args)?) } /// Helper to check if given type has inner mutability such as [`std::cell::Cell`] or @@ -1300,7 +1301,7 @@ pub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl if let Some(deref_did) = cx.tcx.lang_items().deref_trait() && implements_trait(cx, ty, deref_did, &[]) { - make_normalized_projection(cx.tcx, cx.param_env, deref_did, sym::Target, [ty]) + make_normalized_projection(cx.tcx, cx.typing_env(), deref_did, sym::Target, [ty]) } else { None } diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 16fcc26be33..745316913d9 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -12,7 +12,7 @@ use std::{cmp, mem}; use rustc_abi::{BackendRepr, Size}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::{Mutability, RetagKind}; -use rustc_middle::ty::layout::HasParamEnv; +use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::{self, Ty}; use self::diagnostics::{RetagCause, RetagInfo}; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index f92150758dc..255a3578aae 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -1,6 +1,6 @@ use rustc_abi::{BackendRepr, Size}; use rustc_middle::mir::{Mutability, RetagKind}; -use rustc_middle::ty::layout::HasParamEnv; +use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::{self, Ty}; use rustc_span::def_id::DefId; diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 1e56e104918..5ec497ef0ea 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -268,10 +268,14 @@ pub fn create_ecx<'tcx>( entry_type: EntryFnType, config: &MiriConfig, ) -> InterpResult<'tcx, InterpCx<'tcx, MiriMachine<'tcx>>> { - let param_env = ty::ParamEnv::reveal_all(); - let layout_cx = LayoutCx::new(tcx, param_env); - let mut ecx = - InterpCx::new(tcx, rustc_span::DUMMY_SP, param_env, MiriMachine::new(config, layout_cx)); + let typing_env = ty::TypingEnv::fully_monomorphized(); + let layout_cx = LayoutCx::new(tcx, typing_env); + let mut ecx = InterpCx::new( + tcx, + rustc_span::DUMMY_SP, + typing_env.param_env, + MiriMachine::new(config, layout_cx) + ); // Some parts of initialization require a full `InterpCx`. MiriMachine::late_init(&mut ecx, config, { @@ -376,7 +380,7 @@ pub fn create_ecx<'tcx>( let main_ret_ty = main_ret_ty.no_bound_vars().unwrap(); let start_instance = ty::Instance::try_resolve( tcx, - ty::ParamEnv::reveal_all(), + typing_env, start_id, tcx.mk_args(&[ty::GenericArg::from(main_ret_ty)]), ) diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 526030bef2e..4b34f1686a0 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -116,8 +116,8 @@ pub fn resolve_path<'tcx>( /// Gets the layout of a type at a path. #[track_caller] pub fn path_ty_layout<'tcx>(cx: &impl LayoutOf<'tcx>, path: &[&str]) -> TyAndLayout<'tcx> { - let ty = - resolve_path(cx.tcx(), path, Namespace::TypeNS).ty(cx.tcx(), ty::ParamEnv::reveal_all()); + let ty = resolve_path(cx.tcx(), path, Namespace::TypeNS) + .ty(cx.tcx(), cx.typing_env()); cx.layout_of(ty).to_result().ok().unwrap() } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 9668998aaa3..9c1951ec87a 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1127,7 +1127,9 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { }; let info = ecx.get_alloc_info(alloc_id); let def_ty = ecx.tcx.type_of(def_id).instantiate_identity(); - let extern_decl_layout = ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap(); + let extern_decl_layout = ecx.tcx.layout_of( + ecx.typing_env().as_query_input(def_ty) + ).unwrap(); if extern_decl_layout.size != info.size || extern_decl_layout.align.abi != info.align { throw_unsup_format!( "extern static `{link_name}` has been declared as `{krate}::{name}` \ -- cgit 1.4.1-3-g733a5 From f4b516b10c95c7b33d148d1c284d02a331acce2d Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 22 Nov 2024 12:17:50 +0100 Subject: thir building: use typing_env directly --- compiler/rustc_mir_build/src/errors.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 4 +-- compiler/rustc_mir_build/src/thir/cx/mod.rs | 20 +++--------- .../src/thir/pattern/check_match.rs | 35 +++++++------------- compiler/rustc_pattern_analysis/src/rustc.rs | 38 ++++++++-------------- 5 files changed, 32 insertions(+), 67 deletions(-) (limited to 'compiler/rustc_pattern_analysis/src') diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 2e8e0e52719..58487a48184 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -595,7 +595,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo } if let ty::Ref(_, sub_ty, _) = self.ty.kind() { - if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env()) { + if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env) { diag.note(fluent::mir_build_reference_note); } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 47b7f332951..ee9bcce104e 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -284,7 +284,7 @@ impl<'tcx> Cx<'tcx> { let discr_ty = ty.to_ty(tcx); let size = tcx - .layout_of(self.typing_env().as_query_input(discr_ty)) + .layout_of(self.typing_env.as_query_input(discr_ty)) .unwrap_or_else(|e| panic!("could not compute layout for {discr_ty:?}: {e:?}")) .size; @@ -1040,7 +1040,7 @@ impl<'tcx> Cx<'tcx> { // but distinguish between &STATIC and &THREAD_LOCAL as they have different semantics Res::Def(DefKind::Static { .. }, id) => { // this is &raw for extern static or static mut, and & for other statics - let ty = self.tcx.static_ptr_ty(id, self.typing_env()); + let ty = self.tcx.static_ptr_ty(id, self.typing_env); let (temp_lifetime, backwards_incompatible) = self .rvalue_scopes .temporary_scope(self.region_scope_tree, expr.hir_id.local_id); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index d47f7154c4b..a98c2bb61f6 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -12,7 +12,6 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::thir::*; -use rustc_middle::ty::solve::Reveal; use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; use tracing::instrument; @@ -57,7 +56,7 @@ struct Cx<'tcx> { tcx: TyCtxt<'tcx>, thir: Thir<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, region_scope_tree: &'tcx region::ScopeTree, typeck_results: &'tcx ty::TypeckResults<'tcx>, @@ -98,7 +97,9 @@ impl<'tcx> Cx<'tcx> { Cx { tcx, thir: Thir::new(body_type), - param_env: tcx.param_env(def), + // FIXME(#132279): We're in a body, we should use a typing + // mode which reveals the opaque types defined by that body. + typing_env: ty::TypingEnv::non_body_analysis(tcx, def), region_scope_tree: tcx.region_scope_tree(def), typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, @@ -110,20 +111,9 @@ impl<'tcx> Cx<'tcx> { } } - fn typing_mode(&self) -> ty::TypingMode<'tcx> { - debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); - // FIXME(#132279): In case we're in a body, we should use a typing - // mode which reveals the opaque types defined by that body. - ty::TypingMode::non_body_analysis() - } - - fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } - } - #[instrument(level = "debug", skip(self))] fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box> { - pat_from_hir(self.tcx, self.typing_env(), self.typeck_results(), p) + pat_from_hir(self.tcx, self.typing_env, self.typeck_results(), p) } fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option> { diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 37411561600..e55cd35e243 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -8,7 +8,6 @@ use rustc_hir::def::*; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, BindingMode, ByRef, HirId}; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::Reveal; use rustc_lint::Level; use rustc_middle::bug; use rustc_middle::middle::limits::get_limit_size; @@ -43,7 +42,8 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err tcx, thir: &*thir, typeck_results, - param_env: tcx.param_env(def_id), + // FIXME(#132279): We're in a body, should handle opaques. + typing_env: ty::TypingEnv::non_body_analysis(tcx, def_id), lint_level: tcx.local_def_id_to_hir_id(def_id), let_source: LetSource::None, pattern_arena: &pattern_arena, @@ -90,7 +90,7 @@ enum LetSource { struct MatchVisitor<'p, 'tcx> { tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, typeck_results: &'tcx ty::TypeckResults<'tcx>, thir: &'p Thir<'tcx>, lint_level: HirId, @@ -196,15 +196,6 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> { } impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { - fn typing_env(&self) -> ty::TypingEnv<'tcx> { - // FIXME(#132279): We're in a body, should handle opaques. - debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); - ty::TypingEnv { - typing_mode: ty::TypingMode::non_body_analysis(), - param_env: self.param_env, - } - } - #[instrument(level = "trace", skip(self, f))] fn with_let_source(&mut self, let_source: LetSource, f: impl FnOnce(&mut Self)) { let old_let_source = self.let_source; @@ -395,7 +386,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { PatCtxt { tcx: self.tcx, typeck_results: self.typeck_results, - param_env: self.param_env, + typing_env: self.typing_env, module: self.tcx.parent_module(self.lint_level).to_def_id(), dropless_arena: self.dropless_arena, match_lint_level: self.lint_level, @@ -749,8 +740,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { .variant(*variant_index) .inhabited_predicate(self.tcx, *adt) .instantiate(self.tcx, args); - variant_inhabited.apply(self.tcx, cx.typing_env(), cx.module) - && !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env()) + variant_inhabited.apply(self.tcx, cx.typing_env, cx.module) + && !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env) } else { false }; @@ -789,7 +780,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: return; }; - let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env()); + let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env); let sess = cx.tcx.sess; @@ -1054,7 +1045,7 @@ fn find_fallback_pattern_typo<'tcx>( let mut inaccessible = vec![]; let mut imported = vec![]; let mut imported_spans = vec![]; - let infcx = cx.tcx.infer_ctxt().build(ty::TypingMode::non_body_analysis()); + let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env); let parent = cx.tcx.hir().get_parent_item(hir_id); for item in cx.tcx.hir_crate_items(()).free_items() { @@ -1067,7 +1058,7 @@ fn find_fallback_pattern_typo<'tcx>( }; for res in &path.res { if let Res::Def(DefKind::Const, id) = res - && infcx.can_eq(cx.param_env, ty, cx.tcx.type_of(id).instantiate_identity()) + && infcx.can_eq(param_env, ty, cx.tcx.type_of(id).instantiate_identity()) { if cx.tcx.visibility(id).is_accessible_from(parent, cx.tcx) { // The original const is accessible, suggest using it directly. @@ -1088,11 +1079,7 @@ fn find_fallback_pattern_typo<'tcx>( } } if let DefKind::Const = cx.tcx.def_kind(item.owner_id) - && infcx.can_eq( - cx.param_env, - ty, - cx.tcx.type_of(item.owner_id).instantiate_identity(), - ) + && infcx.can_eq(param_env, ty, cx.tcx.type_of(item.owner_id).instantiate_identity()) { // Look for local consts. let item_name = cx.tcx.item_name(item.owner_id.into()); @@ -1311,7 +1298,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( } if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() { - if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env()) { + if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env) { err.note("references are always considered inhabited"); } } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index cc0763ac751..e6887d47396 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -9,7 +9,6 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::middle::stability::EvalResult; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary}; -use rustc_middle::traits::Reveal; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef, @@ -86,7 +85,7 @@ pub struct RustcPatCtxt<'p, 'tcx: 'p> { /// not. E.g., `struct Foo { _private: ! }` cannot be seen to be empty /// outside its module and should not be matchable with an empty match statement. pub module: DefId, - pub param_env: ty::ParamEnv<'tcx>, + pub typing_env: ty::TypingEnv<'tcx>, /// To allocate the result of `self.ctor_sub_tys()` pub dropless_arena: &'p DroplessArena, /// Lint level at the match. @@ -109,17 +108,6 @@ impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> { } impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { - pub fn typing_mode(&self) -> ty::TypingMode<'tcx> { - debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); - // FIXME(#132279): This is inside of a body. If we need to use the `param_env` - // and `typing_mode` we should reveal opaques defined by that body. - ty::TypingMode::non_body_analysis() - } - - pub fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env } - } - /// Type inference occasionally gives us opaque types in places where corresponding patterns /// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited /// types, we use the corresponding concrete type if possible. @@ -151,7 +139,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { !ty.inhabited_predicate(self.tcx).apply_revealing_opaque( self.tcx, - self.typing_env(), + self.typing_env, self.module, &|key| self.reveal_opaque_key(key), ) @@ -191,7 +179,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { variant.fields.iter().map(move |field| { let ty = field.ty(self.tcx, args); // `field.ty()` doesn't normalize after instantiating. - let ty = self.tcx.normalize_erasing_regions(self.typing_env(), ty); + let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty); let ty = self.reveal_opaque_ty(ty); (field, ty) }) @@ -381,7 +369,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let is_inhabited = v .inhabited_predicate(cx.tcx, *def) .instantiate(cx.tcx, args) - .apply_revealing_opaque(cx.tcx, cx.typing_env(), cx.module, &|key| { + .apply_revealing_opaque(cx.tcx, cx.typing_env, cx.module, &|key| { cx.reveal_opaque_key(key) }); // Variants that depend on a disabled unstable feature. @@ -442,7 +430,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { match bdy { PatRangeBoundary::NegInfinity => MaybeInfiniteInt::NegInfinity, PatRangeBoundary::Finite(value) => { - let bits = value.eval_bits(self.tcx, self.typing_env()); + let bits = value.eval_bits(self.tcx, self.typing_env); match *ty.kind() { ty::Int(ity) => { let size = Integer::from_int_ty(&self.tcx, ity).size().bits(); @@ -551,7 +539,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { PatKind::Constant { value } => { match ty.kind() { ty::Bool => { - ctor = match value.try_eval_bool(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bool(cx.tcx, cx.typing_env) { Some(b) => Bool(b), None => Opaque(OpaqueId::new()), }; @@ -559,7 +547,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Char | ty::Int(_) | ty::Uint(_) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { let x = match *ty.kind() { ty::Int(ity) => { @@ -576,7 +564,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F16) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Half::from_bits(bits); @@ -588,7 +576,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F32) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Single::from_bits(bits); @@ -600,7 +588,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F64) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Double::from_bits(bits); @@ -612,7 +600,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { arity = 0; } ty::Float(ty::FloatTy::F128) => { - ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) { + ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) { Some(bits) => { use rustc_apfloat::Float; let value = rustc_apfloat::ieee::Quad::from_bits(bits); @@ -661,8 +649,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Float(fty) => { use rustc_apfloat::Float; - let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env())); - let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env())); + let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env)); + let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env)); match fty { ty::FloatTy::F16 => { use rustc_apfloat::ieee::Half; -- cgit 1.4.1-3-g733a5 From 319843d8cd84ee1ec753f836ce3773d44fe0764b Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 20 Nov 2024 11:31:49 +0100 Subject: no more Reveal :( --- .../src/check/compare_impl_item.rs | 12 +- .../src/check/compare_impl_item/refine.rs | 4 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/infer/canonical/canonicalizer.rs | 2 +- compiler/rustc_infer/src/infer/context.rs | 7 +- compiler/rustc_infer/src/infer/mod.rs | 22 +--- compiler/rustc_infer/src/infer/opaque_types/mod.rs | 4 +- .../rustc_infer/src/infer/relate/generalize.rs | 10 +- compiler/rustc_lint/src/context.rs | 2 - compiler/rustc_middle/src/mir/consts.rs | 8 +- compiler/rustc_middle/src/mir/interpret/queries.rs | 4 +- compiler/rustc_middle/src/query/mod.rs | 8 +- compiler/rustc_middle/src/traits/mod.rs | 2 +- compiler/rustc_middle/src/ty/codec.rs | 4 +- compiler/rustc_middle/src/ty/consts.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 139 ++++----------------- compiler/rustc_middle/src/ty/structural_impls.rs | 1 - compiler/rustc_middle/src/ty/util.rs | 2 +- .../src/thir/pattern/const_to_pat.rs | 2 +- .../src/solve/assembly/mod.rs | 4 +- .../src/solve/eval_ctxt/canonical.rs | 6 +- .../src/solve/eval_ctxt/mod.rs | 4 +- .../src/solve/normalizes_to/mod.rs | 2 +- .../src/solve/normalizes_to/opaque_types.rs | 2 +- .../src/solve/trait_goals.rs | 4 +- compiler/rustc_pattern_analysis/src/rustc.rs | 2 + .../rustc_trait_selection/src/solve/delegate.rs | 2 +- .../rustc_trait_selection/src/traits/auto_trait.rs | 2 - .../src/traits/dyn_compatibility.rs | 2 +- .../rustc_trait_selection/src/traits/effects.rs | 2 +- .../rustc_trait_selection/src/traits/fulfill.rs | 6 +- compiler/rustc_trait_selection/src/traits/mod.rs | 9 +- .../rustc_trait_selection/src/traits/normalize.rs | 18 +-- .../rustc_trait_selection/src/traits/project.rs | 3 +- .../src/traits/query/normalize.rs | 10 +- .../src/traits/select/candidate_assembly.rs | 6 +- .../rustc_trait_selection/src/traits/select/mod.rs | 12 +- compiler/rustc_ty_utils/src/instance.rs | 2 +- compiler/rustc_ty_utils/src/layout.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 11 +- compiler/rustc_type_ir/src/infer_ctxt.rs | 5 +- compiler/rustc_type_ir/src/inherent.rs | 4 +- compiler/rustc_type_ir/src/relate/combine.rs | 2 +- compiler/rustc_type_ir/src/solve/mod.rs | 48 ------- src/tools/clippy/clippy_lints/src/derive.rs | 2 - src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 46 files changed, 112 insertions(+), 299 deletions(-) (limited to 'compiler/rustc_pattern_analysis/src') diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index bd0b0ceb92d..f86ca95a954 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -26,7 +26,7 @@ use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{ - self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal, + self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, }; use tracing::{debug, instrument}; @@ -223,7 +223,7 @@ fn compare_method_predicate_entailment<'tcx>( } let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(caller_bounds=?param_env.caller_bounds()); @@ -508,7 +508,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1793,7 +1793,7 @@ fn compare_const_predicate_entailment<'tcx>( .map(|(predicate, _)| predicate), ); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1946,7 +1946,7 @@ fn compare_type_predicate_entailment<'tcx>( ); } - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(caller_bounds=?param_env.caller_bounds()); @@ -2306,7 +2306,7 @@ fn param_env_with_gat_bounds<'tcx>( }; } - ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing) + ty::ParamEnv::new(tcx.mk_clauses(&predicates)) } /// Manually check here that `async fn foo()` wasn't matched against `fn foo()`, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 25ba52b4d7b..67cbcc1566a 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -6,7 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE}; use rustc_middle::span_bug; -use rustc_middle::traits::{ObligationCause, Reveal}; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, @@ -134,7 +134,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy()); let ref infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 20bc34b8c79..9a70555fede 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -604,7 +604,7 @@ fn augment_param_env<'tcx>( ); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error - ty::ParamEnv::new(bounds, param_env.reveal()) + ty::ParamEnv::new(bounds) } /// We use the following trait as an example throughout this function. diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index f87c43a0ecd..fe66d306ceb 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -72,7 +72,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state, ) .unchecked_map(|(param_env, value)| param_env.and(value)); - CanonicalQueryInput { canonical, typing_mode: self.typing_mode(param_env) } + CanonicalQueryInput { canonical, typing_mode: self.typing_mode() } } /// Canonicalizes a query *response* `V`. When we canonicalize a diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index ecda9c6eb00..1968ed34752 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -20,11 +20,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.next_trait_solver } - fn typing_mode( - &self, - param_env_for_debug_assertion: ty::ParamEnv<'tcx>, - ) -> ty::TypingMode<'tcx> { - self.typing_mode(param_env_for_debug_assertion) + fn typing_mode(&self) -> ty::TypingMode<'tcx> { + self.typing_mode() } fn universe(&self) -> ty::UniverseIndex { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b29dc7f909d..6ba82b80af2 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -43,7 +43,6 @@ use rustc_middle::ty::{ }; use rustc_span::Span; use rustc_span::symbol::Symbol; -use rustc_type_ir::solve::Reveal; use snapshot::undo_log::InferCtxtUndoLogs; use tracing::{debug, instrument}; use type_variable::TypeVariableOrigin; @@ -624,22 +623,7 @@ impl<'tcx> InferCtxt<'tcx> { } #[inline(always)] - pub fn typing_mode( - &self, - param_env_for_debug_assertion: ty::ParamEnv<'tcx>, - ) -> TypingMode<'tcx> { - if cfg!(debug_assertions) { - match (param_env_for_debug_assertion.reveal(), self.typing_mode) { - (Reveal::All, TypingMode::PostAnalysis) - | (Reveal::UserFacing, TypingMode::Coherence | TypingMode::Analysis { .. }) => {} - (r, t) => unreachable!("TypingMode x Reveal mismatch: {r:?} {t:?}"), - } - } - self.typing_mode - } - - #[inline(always)] - pub fn typing_mode_unchecked(&self) -> TypingMode<'tcx> { + pub fn typing_mode(&self) -> TypingMode<'tcx> { self.typing_mode } @@ -1005,7 +989,7 @@ impl<'tcx> InferCtxt<'tcx> { #[inline(always)] pub fn can_define_opaque_ty(&self, id: impl Into) -> bool { - match self.typing_mode_unchecked() { + match self.typing_mode() { TypingMode::Analysis { defining_opaque_types } => { id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id)) } @@ -1290,7 +1274,7 @@ impl<'tcx> InferCtxt<'tcx> { /// which contains the necessary information to use the trait system without /// using canonicalization or carrying this inference context around. pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> { - let typing_mode = match self.typing_mode(param_env) { + let typing_mode = match self.typing_mode() { ty::TypingMode::Coherence => ty::TypingMode::Coherence, // FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible // to handle them without proper canonicalization. This means we may cause cycle diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 0aff4620314..a3af5dea944 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -101,7 +101,7 @@ impl<'tcx> InferCtxt<'tcx> { let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => { let def_id = def_id.expect_local(); - if let ty::TypingMode::Coherence = self.typing_mode(param_env) { + if let ty::TypingMode::Coherence = self.typing_mode() { // See comment on `insert_hidden_type` for why this is sufficient in coherence return Some(self.register_hidden_type( OpaqueTypeKey { def_id, args }, @@ -522,7 +522,7 @@ impl<'tcx> InferCtxt<'tcx> { // value being folded. In simple cases like `-> impl Foo`, // these are the same span, but not in cases like `-> (impl // Foo, impl Bar)`. - match self.typing_mode(param_env) { + match self.typing_mode() { ty::TypingMode::Coherence => { // During intercrate we do not define opaque types but instead always // force ambiguity unless the hidden type is known to not implement diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 4c80bf4e07e..21c47967ead 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -520,10 +520,7 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { // // cc trait-system-refactor-initiative#108 if self.infcx.next_trait_solver() - && !matches!( - self.infcx.typing_mode_unchecked(), - TypingMode::Coherence - ) + && !matches!(self.infcx.typing_mode(), TypingMode::Coherence) && self.in_alias { inner.type_variables().equate(vid, new_var_id); @@ -654,10 +651,7 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { // See the comment for type inference variables // for more details. if self.infcx.next_trait_solver() - && !matches!( - self.infcx.typing_mode_unchecked(), - TypingMode::Coherence - ) + && !matches!(self.infcx.typing_mode(), TypingMode::Coherence) && self.in_alias { variable_table.union(vid, new_var_id); diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 6eec32beab0..7248b192763 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -14,7 +14,6 @@ use rustc_feature::Features; use rustc_hir::def::Res; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; -use rustc_infer::traits::Reveal; use rustc_middle::bug; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; @@ -702,7 +701,6 @@ impl<'tcx> LateContext<'tcx> { /// The typing mode of the currently visited node. Use this when /// building a new `InferCtxt`. pub fn typing_mode(&self) -> TypingMode<'tcx> { - debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing); // FIXME(#132279): In case we're in a body, we should use a typing // mode which reveals the opaque types defined by that body. TypingMode::non_body_analysis() diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index a51370369b8..7983329b0f7 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -105,8 +105,10 @@ impl<'tcx> ConstValue<'tcx> { typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> Option { - let size = - tcx.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(ty)).ok()?.size; + let size = tcx + .layout_of(typing_env.with_post_analysis_normalized(tcx).as_query_input(ty)) + .ok()? + .size; self.try_to_bits(size) } @@ -376,7 +378,7 @@ impl<'tcx> Const<'tcx> { ) -> Option { let int = self.try_eval_scalar_int(tcx, typing_env)?; let size = tcx - .layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(self.ty())) + .layout_of(typing_env.with_post_analysis_normalized(tcx).as_query_input(self.ty())) .ok()? .size; Some(int.to_bits(size)) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 6eeafe18b35..e540f0194ec 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -162,7 +162,7 @@ impl<'tcx> TyCtxt<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = - self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid)); + self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid)); if !span.is_dummy() { // The query doesn't know where it is being invoked, so we need to fix the span. self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span)) @@ -182,7 +182,7 @@ impl<'tcx> TyCtxt<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = - self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid)); + self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid)); debug!(?inputs); if !span.is_dummy() { // The query doesn't know where it is being invoked, so we need to fix the span. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 76338be33aa..f9aeab6210b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1381,10 +1381,10 @@ rustc_queries! { feedable } - /// Like `param_env`, but returns the `ParamEnv` in `Reveal::All` mode. - /// Prefer this over `tcx.param_env(def_id).with_reveal_all_normalized(tcx)`, - /// as this method is more efficient. - query param_env_reveal_all_normalized(def_id: DefId) -> ty::ParamEnv<'tcx> { + /// Like `param_env`, but returns the `ParamEnv` after all opaque types have been + /// replaced with their hidden type. This is used in the old trait solver + /// when in `PostAnalysis` mode and should not be called directly. + query param_env_normalized_for_post_analysis(def_id: DefId) -> ty::ParamEnv<'tcx> { desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 09731d565b6..b8748ec6581 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -23,7 +23,7 @@ use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_span::symbol::Symbol; use rustc_span::{DUMMY_SP, Span}; // FIXME: Remove this import and import via `solve::` -pub use rustc_type_ir::solve::{BuiltinImplSource, Reveal}; +pub use rustc_type_ir::solve::BuiltinImplSource; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 47a84d4b258..aba5719138c 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -174,7 +174,6 @@ impl<'tcx, E: TyEncoder>> Encodable for CtfeProvenance { impl<'tcx, E: TyEncoder>> Encodable for ty::ParamEnv<'tcx> { fn encode(&self, e: &mut E) { self.caller_bounds().encode(e); - self.reveal().encode(e); } } @@ -310,8 +309,7 @@ impl<'tcx, D: TyDecoder>> Decodable for ty::SymbolName<'tcx> impl<'tcx, D: TyDecoder>> Decodable for ty::ParamEnv<'tcx> { fn decode(d: &mut D) -> Self { let caller_bounds = Decodable::decode(d); - let reveal = Decodable::decode(d); - ty::ParamEnv::new(caller_bounds, reveal) + ty::ParamEnv::new(caller_bounds) } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d853edb34c9..c4d86c3210e 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -336,7 +336,7 @@ impl<'tcx> Const<'tcx> { pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option { let (scalar, ty) = self.try_to_scalar()?; let scalar = scalar.try_to_scalar_int().ok()?; - let input = typing_env.with_reveal_all_normalized(tcx).as_query_input(ty); + let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(ty); let size = tcx.layout_of(input).ok()?.size; Some(scalar.to_bits(size)) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a6c875ec618..2b532701904 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -32,7 +32,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; -use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_errors::{Diag, ErrorGuaranteed, StashKey}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; @@ -104,7 +103,6 @@ use crate::metadata::ModChild; use crate::middle::privacy::EffectiveVisibilities; use crate::mir::{Body, CoroutineLayout}; use crate::query::{IntoQueryParam, Providers}; -use crate::traits::{self, Reveal}; use crate::ty; pub use crate::ty::diagnostics::*; use crate::ty::fast_reject::SimplifiedType; @@ -960,147 +958,50 @@ impl<'tcx> rustc_type_ir::visit::Flags for Clauses<'tcx> { /// [dev guide chapter][param_env_guide] for more information. /// /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html -#[derive(Copy, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[derive(HashStable, TypeVisitable, TypeFoldable)] pub struct ParamEnv<'tcx> { - /// This packs both caller bounds and the reveal enum into one pointer. - /// /// Caller bounds are `Obligation`s that the caller must satisfy. This is /// basically the set of bounds on the in-scope type parameters, translated /// into `Obligation`s, and elaborated and normalized. /// /// Use the `caller_bounds()` method to access. - /// - /// Typically, this is `Reveal::UserFacing`, but during codegen we - /// want `Reveal::All`. - /// - /// Note: This is packed, use the reveal() method to access it. - packed: CopyTaggedPtr, ParamTag, true>, + caller_bounds: Clauses<'tcx>, } impl<'tcx> rustc_type_ir::inherent::ParamEnv> for ParamEnv<'tcx> { - fn reveal(self) -> Reveal { - self.reveal() - } - fn caller_bounds(self) -> impl IntoIterator> { self.caller_bounds() } } -#[derive(Copy, Clone)] -struct ParamTag { - reveal: traits::Reveal, -} - -rustc_data_structures::impl_tag! { - impl Tag for ParamTag; - ParamTag { reveal: traits::Reveal::UserFacing }, - ParamTag { reveal: traits::Reveal::All }, -} - -impl<'tcx> fmt::Debug for ParamEnv<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ParamEnv") - .field("caller_bounds", &self.caller_bounds()) - .field("reveal", &self.reveal()) - .finish() - } -} - -impl<'a, 'tcx> HashStable> for ParamEnv<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.caller_bounds().hash_stable(hcx, hasher); - self.reveal().hash_stable(hcx, hasher); - } -} - -impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - Ok(ParamEnv::new( - self.caller_bounds().try_fold_with(folder)?, - self.reveal().try_fold_with(folder)?, - )) - } -} - -impl<'tcx> TypeVisitable> for ParamEnv<'tcx> { - fn visit_with>>(&self, visitor: &mut V) -> V::Result { - try_visit!(self.caller_bounds().visit_with(visitor)); - self.reveal().visit_with(visitor) - } -} - impl<'tcx> ParamEnv<'tcx> { - /// Construct a trait environment suitable for contexts where - /// there are no where-clauses in scope. Hidden types (like `impl - /// Trait`) are left hidden. In majority of cases it is incorrect + /// Construct a trait environment suitable for contexts where there are + /// no where-clauses in scope. In the majority of cases it is incorrect /// to use an empty environment. See the [dev guide section][param_env_guide] /// for information on what a `ParamEnv` is and how to acquire one. /// /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html #[inline] pub fn empty() -> Self { - Self::new(ListWithCachedTypeInfo::empty(), Reveal::UserFacing) + Self::new(ListWithCachedTypeInfo::empty()) } #[inline] pub fn caller_bounds(self) -> Clauses<'tcx> { - self.packed.pointer() - } - - #[inline] - pub fn reveal(self) -> traits::Reveal { - self.packed.tag().reveal - } - - /// Construct a trait environment with no where-clauses in scope - /// where the values of all `impl Trait` and other hidden types - /// are revealed. This is suitable for monomorphized, post-typeck - /// environments like codegen or doing optimizations. - /// - /// N.B., if you want to have predicates in scope, use `ParamEnv::new`, - /// or invoke `param_env.with_reveal_all()`. - #[inline] - pub fn reveal_all() -> Self { - Self::new(ListWithCachedTypeInfo::empty(), Reveal::All) + self.caller_bounds } /// Construct a trait environment with the given set of predicates. #[inline] - pub fn new(caller_bounds: Clauses<'tcx>, reveal: Reveal) -> Self { - ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) } - } - - /// Returns a new parameter environment with the same clauses, but - /// which "reveals" the true results of projections in all cases - /// (even for associated types that are specializable). This is - /// the desired behavior during codegen and certain other special - /// contexts; normally though we want to use `Reveal::UserFacing`, - /// which is the default. - /// All opaque types in the caller_bounds of the `ParamEnv` - /// will be normalized to their underlying types. - /// See PR #65989 and issue #65918 for more details - pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self { - if self.packed.tag().reveal == traits::Reveal::All { - return self; - } - - // No need to reveal opaques with the new solver enabled, - // since we have lazy norm. - if tcx.next_trait_solver_globally() { - return ParamEnv::new(self.caller_bounds(), Reveal::All); - } - - ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All) + pub fn new(caller_bounds: Clauses<'tcx>) -> Self { + ParamEnv { caller_bounds } } /// Returns this same environment but with no caller bounds. #[inline] pub fn without_caller_bounds(self) -> Self { - Self::new(ListWithCachedTypeInfo::empty(), self.reveal()) + Self::new(ListWithCachedTypeInfo::empty()) } /// Creates a pair of param-env and value for use in queries. @@ -1148,7 +1049,7 @@ impl<'tcx> TypingEnv<'tcx> { /// use `TypingMode::PostAnalysis`, they may still have where-clauses /// in scope. pub fn fully_monomorphized() -> TypingEnv<'tcx> { - TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::reveal_all() } + TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::empty() } } /// Create a typing environment for use during analysis outside of a body. @@ -1166,15 +1067,25 @@ impl<'tcx> TypingEnv<'tcx> { pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam) -> TypingEnv<'tcx> { TypingEnv { typing_mode: TypingMode::PostAnalysis, - param_env: tcx.param_env_reveal_all_normalized(def_id), + param_env: tcx.param_env_normalized_for_post_analysis(def_id), } } /// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all /// opaque types in the `param_env`. - pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { - let TypingEnv { typing_mode: _, param_env } = self; - let param_env = param_env.with_reveal_all_normalized(tcx); + pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { + let TypingEnv { typing_mode, param_env } = self; + if let TypingMode::PostAnalysis = typing_mode { + return self; + } + + // No need to reveal opaques with the new solver enabled, + // since we have lazy norm. + let param_env = if tcx.next_trait_solver_globally() { + ParamEnv::new(param_env.caller_bounds()) + } else { + ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds())) + }; TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index e48fac6c7e8..0af0a5f170d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -237,7 +237,6 @@ TrivialTypeTraversalImpls! { crate::mir::coverage::ConditionId, crate::mir::Local, crate::mir::Promoted, - crate::traits::Reveal, crate::ty::adjustment::AutoBorrowMutability, crate::ty::AdtKind, crate::ty::BoundRegion, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 20c3f84bb4d..3250a2605df 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1053,7 +1053,7 @@ impl<'tcx> TypeFolder> for OpaqueTypeExpander<'tcx> { // This is because for default trait methods with RPITITs, we // install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` // predicate, which would trivially cause a cycle when we do - // anything that requires `ParamEnv::with_reveal_all_normalized`. + // anything that requires `TypingEnv::with_post_analysis_normalized`. term: projection_pred.term, }) .upcast(self.tcx) diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index a40134e44e7..06513134a29 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -87,7 +87,7 @@ impl<'tcx> ConstToPat<'tcx> { // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All` // instead of having this logic here let typing_env = - self.tcx.erase_regions(self.typing_env).with_reveal_all_normalized(self.tcx); + self.tcx.erase_regions(self.typing_env).with_post_analysis_normalized(self.tcx); let uv = self.tcx.erase_regions(uv); // try to resolve e.g. associated constants to their definition on an impl, and then diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 545ab15b945..adac35b57cd 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -321,7 +321,7 @@ where let mut candidates = vec![]; - if let TypingMode::Coherence = self.typing_mode(goal.param_env) { + if let TypingMode::Coherence = self.typing_mode() { if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) { return vec![candidate]; } @@ -337,7 +337,7 @@ where self.assemble_param_env_candidates(goal, &mut candidates); - match self.typing_mode(goal.param_env) { + match self.typing_mode() { TypingMode::Coherence => {} TypingMode::Analysis { .. } | TypingMode::PostAnalysis => { self.discard_impls_shadowed_by_env(goal, &mut candidates); diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 2f50070d438..a143af13688 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -55,7 +55,6 @@ where &self, goal: Goal, ) -> (Vec, CanonicalInput) { - let param_env_for_debug_assertion = goal.param_env; let opaque_types = self.delegate.clone_opaque_types_for_query_response(); let (goal, opaque_types) = (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate)); @@ -72,10 +71,7 @@ where .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }), }, ); - let query_input = ty::CanonicalQueryInput { - canonical, - typing_mode: self.typing_mode(param_env_for_debug_assertion), - }; + let query_input = ty::CanonicalQueryInput { canonical, typing_mode: self.typing_mode() }; (orig_values, query_input) } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 979a3794748..40d1576256e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -214,8 +214,8 @@ where D: SolverDelegate, I: Interner, { - pub(super) fn typing_mode(&self, param_env_for_debug_assertion: I::ParamEnv) -> TypingMode { - self.delegate.typing_mode(param_env_for_debug_assertion) + pub(super) fn typing_mode(&self) -> TypingMode { + self.delegate.typing_mode() } pub(super) fn set_is_normalizes_to_goal(&mut self) { diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 6b407640426..33bd1cf2f56 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -71,7 +71,7 @@ where Ok(()) } ty::AliasTermKind::OpaqueTy => { - match self.typing_mode(param_env) { + match self.typing_mode() { // Opaques are never rigid outside of analysis mode. TypingMode::Coherence | TypingMode::PostAnalysis => Err(NoSolution), // During analysis, opaques are only rigid if we may not define it. diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index d1d701695ab..19d17a358ed 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -22,7 +22,7 @@ where let opaque_ty = goal.predicate.alias; let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const"); - match self.typing_mode(goal.param_env) { + match self.typing_mode() { TypingMode::Coherence => { // An impossible opaque type bound is the only way this goal will fail // e.g. assigning `impl Copy := NotCopy` diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index ce16258d180..096dc32ccc9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -67,7 +67,7 @@ where let maximal_certainty = match (impl_polarity, goal.predicate.polarity) { // In intercrate mode, this is ambiguous. But outside of intercrate, // it's not a real impl. - (ty::ImplPolarity::Reservation, _) => match ecx.typing_mode(goal.param_env) { + (ty::ImplPolarity::Reservation, _) => match ecx.typing_mode() { TypingMode::Coherence => Certainty::AMBIGUOUS, TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Err(NoSolution), }, @@ -174,7 +174,7 @@ where // ideally we want to avoid, since we can make progress on this goal // via an alias bound or a locally-inferred hidden type instead. if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() { - match ecx.typing_mode(goal.param_env) { + match ecx.typing_mode() { TypingMode::Coherence | TypingMode::PostAnalysis => { unreachable!("rigid opaque outside of analysis: {goal:?}"); } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index e6887d47396..009d817a1a9 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -111,6 +111,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { /// Type inference occasionally gives us opaque types in places where corresponding patterns /// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited /// types, we use the corresponding concrete type if possible. + // FIXME(#132279): This will be unnecessary once we have a TypingMode which supports revealing + // opaque types defined in a body. #[inline] pub fn reveal_opaque_ty(&self, ty: Ty<'tcx>) -> RevealedTy<'tcx> { fn reveal_inner<'tcx>(cx: &RustcPatCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> RevealedTy<'tcx> { diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 2cc787c8bc5..09bba24ba61 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -204,7 +204,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< // and the obligation is monomorphic, otherwise passes such as // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. - match self.typing_mode_unchecked() { + match self.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { .. } => false, TypingMode::PostAnalysis => { let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index fac0414d714..6730f28893d 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -318,13 +318,11 @@ impl<'tcx> AutoTraitFinder<'tcx> { elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned())); new_env = ty::ParamEnv::new( tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())), - param_env.reveal(), ); } let final_user_env = ty::ParamEnv::new( tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())), - user_env.reveal(), ); debug!( "evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \ diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index cf63f14fb93..78e92e60b23 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -707,7 +707,7 @@ fn receiver_is_dispatchable<'tcx>( let caller_bounds = param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]); - ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds), param_env.reveal()) + ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds)) }; // Receiver: DispatchFromDyn U]> diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 27d3ec160ca..07fb2efb7fe 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -20,7 +20,7 @@ pub fn evaluate_host_effect_obligation<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, obligation: &HostEffectObligation<'tcx>, ) -> Result>, EvaluationFailure> { - if matches!(selcx.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) { + if matches!(selcx.infcx.typing_mode(), TypingMode::Coherence) { span_bug!( obligation.cause.span, "should not select host obligation in old solver in intercrate mode" diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 2ec5f0d2249..a1a2d4f3fb2 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -768,8 +768,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { stalled_on: &mut Vec, ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { let infcx = self.selcx.infcx; - if obligation.predicate.is_global() - && !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence) + if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence) { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. @@ -824,8 +823,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { let tcx = self.selcx.tcx(); let infcx = self.selcx.infcx; - if obligation.predicate.is_global() - && !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence) + if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence) { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 80cef690028..0e89a0c6545 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -423,7 +423,7 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); - let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal()); + let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates)); if !elaborated_env.has_aliases() { return elaborated_env; } @@ -470,8 +470,7 @@ pub fn normalize_param_env_or_error<'tcx>( // here. I believe they should not matter, because we are ignoring TypeOutlives param-env // predicates here anyway. Keeping them here anyway because it seems safer. let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned(); - let outlives_env = - ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env), unnormalized_env.reveal()); + let outlives_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env)); let Ok(outlives_predicates) = do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates) else { @@ -484,7 +483,7 @@ pub fn normalize_param_env_or_error<'tcx>( let mut predicates = non_outlives_predicates; predicates.extend(outlives_predicates); debug!("normalize_param_env_or_error: final predicates={:?}", predicates); - ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal()) + ty::ParamEnv::new(tcx.mk_clauses(&predicates)) } #[derive(Debug)] @@ -612,7 +611,7 @@ pub fn try_evaluate_const<'tcx>( // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All` // instead of having this logic here let typing_env = - tcx.erase_regions(infcx.typing_env(param_env)).with_reveal_all_normalized(tcx); + tcx.erase_regions(infcx.typing_env(param_env)).with_post_analysis_normalized(tcx); let erased_uv = tcx.erase_regions(uv); use rustc_middle::mir::interpret::ErrorHandled; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 5c38d162712..0a2ba2b4b20 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -111,14 +111,13 @@ where pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( infcx: &InferCtxt<'tcx>, - param_env_for_debug_assertion: ty::ParamEnv<'tcx>, value: &T, ) -> bool { let mut flags = ty::TypeFlags::HAS_ALIAS; // Opaques are treated as rigid with `Reveal::UserFacing`, // so we can ignore those. - match infcx.typing_mode(param_env_for_debug_assertion) { + match infcx.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { flags.remove(ty::TypeFlags::HAS_TY_OPAQUE) } @@ -158,11 +157,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { "Normalizing {value:?} without wrapping in a `Binder`" ); - if !needs_normalization(self.selcx.infcx, self.param_env, &value) { - value - } else { - value.fold_with(self) - } + if !needs_normalization(self.selcx.infcx, &value) { value } else { value.fold_with(self) } } } @@ -182,7 +177,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if !needs_normalization(self.selcx.infcx, self.param_env, &ty) { + if !needs_normalization(self.selcx.infcx, &ty) { return ty; } @@ -217,7 +212,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.selcx.infcx.typing_mode(self.param_env) { + match self.selcx.infcx.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { ty.super_fold_with(self) } @@ -407,8 +402,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx #[instrument(skip(self), level = "debug")] fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> { let tcx = self.selcx.tcx(); - if tcx.features().generic_const_exprs() - || !needs_normalization(self.selcx.infcx, self.param_env, &constant) + if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &constant) { constant } else { @@ -426,7 +420,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx #[inline] fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { - if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) { + if p.allow_normalization() && needs_normalization(self.selcx.infcx, &p) { p.super_fold_with(self) } else { p diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index aab854e9caf..2864f277df5 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -10,7 +10,6 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; -pub use rustc_middle::traits::Reveal; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; @@ -975,7 +974,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // and the obligation is monomorphic, otherwise passes such as // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. - match selcx.infcx.typing_mode(obligation.param_env) { + match selcx.infcx.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { .. } => { debug!( assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 5f89894fb82..22cfbb2c840 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { } } - if !needs_normalization(self.infcx, self.param_env, &value) { + if !needs_normalization(self.infcx, &value) { return Ok(Normalized { value, obligations: PredicateObligations::new() }); } @@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { - if !needs_normalization(self.infcx, self.param_env, &ty) { + if !needs_normalization(self.infcx, &ty) { return Ok(ty); } @@ -215,7 +215,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { let res = match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.infcx.typing_mode(self.param_env) { + match self.infcx.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { ty.try_super_fold_with(self)? } @@ -334,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { &mut self, constant: ty::Const<'tcx>, ) -> Result, Self::Error> { - if !needs_normalization(self.infcx, self.param_env, &constant) { + if !needs_normalization(self.infcx, &constant) { return Ok(constant); } @@ -353,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { &mut self, p: ty::Predicate<'tcx>, ) -> Result, Self::Error> { - if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) { + if p.allow_normalization() && needs_normalization(self.infcx, &p) { p.try_super_fold_with(self) } else { Ok(p) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 41d430f06df..32b4567aba4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -760,9 +760,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // Note that this is only sound as projection candidates of opaque types // are always applicable for auto traits. - } else if let TypingMode::Coherence = - self.infcx.typing_mode(obligation.param_env) - { + } else if let TypingMode::Coherence = self.infcx.typing_mode() { // We do not emit auto trait candidates for opaque types in coherence. // Doing so can result in weird dependency cycles. candidates.ambiguous = true; @@ -905,7 +903,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // FIXME(@lcnr): This should probably only trigger during analysis, // disabling candidates during codegen is also questionable. - if let TypingMode::Coherence = self.infcx.typing_mode(param_env) { + if let TypingMode::Coherence = self.infcx.typing_mode() { return None; } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e0c862a81f3..98cddc6bb5c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -222,7 +222,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Enables tracking of intercrate ambiguity causes. See /// the documentation of [`Self::intercrate_ambiguity_causes`] for more. pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) { - assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence); + assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence); assert!(self.intercrate_ambiguity_causes.is_none()); self.intercrate_ambiguity_causes = Some(FxIndexSet::default()); debug!("selcx: enable_tracking_intercrate_ambiguity_causes"); @@ -234,7 +234,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn take_intercrate_ambiguity_causes( &mut self, ) -> FxIndexSet> { - assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence); + assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence); self.intercrate_ambiguity_causes.take().unwrap_or_default() } @@ -1027,7 +1027,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: PolyTraitObligation<'tcx>, ) -> Result { - if !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) + if !matches!(self.infcx.typing_mode(), TypingMode::Coherence) && obligation.is_global() && obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param()) { @@ -1459,7 +1459,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> { let obligation = &stack.obligation; - match self.infcx.typing_mode(obligation.param_env) { + match self.infcx.typing_mode() { TypingMode::Coherence => {} TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Ok(()), } @@ -1489,7 +1489,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return false; } - match self.infcx.typing_mode(param_env) { + match self.infcx.typing_mode() { // Avoid using the global cache during coherence and just rely // on the local cache. It is really just a simplification to // avoid us having to fear that coherence results "pollute" @@ -2518,7 +2518,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested_obligations.extend(obligations); if impl_trait_header.polarity == ty::ImplPolarity::Reservation - && !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) + && !matches!(self.infcx.typing_mode(), TypingMode::Coherence) { debug!("reservation impls only apply in intercrate mode"); return Err(()); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 29fc92e1f2f..98c31f5ce0f 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -155,7 +155,7 @@ fn resolve_associated_item<'tcx>( return Ok(None); } - let typing_env = typing_env.with_reveal_all_normalized(tcx); + let typing_env = typing_env.with_post_analysis_normalized(tcx); let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); let args = rcvr_args.rebase_onto(tcx, trait_def_id, impl_data.args); let args = translate_args( diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 092e140a600..2fcdf6433fa 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -49,7 +49,7 @@ fn layout_of<'tcx>( // Optimization: We convert to RevealAll and convert opaque types in the where bounds // to their hidden types. This reduces overall uncached invocations of `layout_of` and // is thus a small performance improvement. - let typing_env = typing_env.with_reveal_all_normalized(tcx); + let typing_env = typing_env.with_post_analysis_normalized(tcx); let unnormalized_ty = ty; // FIXME: We might want to have two different versions of `layout_of`: diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 292e777f288..61f2262dfe8 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -158,8 +158,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let local_did = def_id.as_local(); - let unnormalized_env = - ty::ParamEnv::new(tcx.mk_clauses(&predicates), traits::Reveal::UserFacing); + let unnormalized_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates)); let body_id = local_did.unwrap_or(CRATE_DEF_ID); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); @@ -249,8 +248,10 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { } } -fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { - tcx.param_env(def_id).with_reveal_all_normalized(tcx) +fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { + // This is a bit ugly but the easiest way to avoid code duplication. + let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id); + typing_env.with_post_analysis_normalized(tcx).param_env } /// If the given trait impl enables exploiting the former order dependence of trait objects, @@ -362,7 +363,7 @@ pub(crate) fn provide(providers: &mut Providers) { asyncness, adt_sized_constraint, param_env, - param_env_reveal_all_normalized, + param_env_normalized_for_post_analysis, self_ty_of_trait_impl_enabling_order_dep_trait_object_hack, defaultness, unsizing_params_for_adt, diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index b01d3dc5269..c2b43416623 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -70,10 +70,7 @@ pub trait InferCtxtLike: Sized { true } - fn typing_mode( - &self, - param_env_for_debug_assertion: ::ParamEnv, - ) -> TypingMode; + fn typing_mode(&self) -> TypingMode; fn universe(&self) -> ty::UniverseIndex; fn create_next_universe(&self) -> ty::UniverseIndex; diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index f7e0570bdd5..3793d2c5241 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -11,7 +11,7 @@ use rustc_ast_ir::Mutability; use crate::elaborate::Elaboratable; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; -use crate::solve::{AdtDestructorKind, Reveal}; +use crate::solve::AdtDestructorKind; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{self as ty, CollectAndApply, Interner, UpcastFrom}; @@ -542,8 +542,6 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { } pub trait ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable { - fn reveal(self) -> Reveal; - fn caller_bounds(self) -> impl IntoIterator; } diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 53751f7711a..6e5912cd290 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -129,7 +129,7 @@ where (ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => { assert!(!infcx.next_trait_solver()); - match infcx.typing_mode(relation.param_env()) { + match infcx.typing_mode() { // During coherence, opaque types should be treated as *possibly* // equal to any other type. This is an // extremely heavy hammer, but can be relaxed in a forwards-compatible diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 13081f3154b..8fe512026e5 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -10,54 +10,6 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; -/// Depending on the stage of compilation, we want projection to be -/// more or less conservative. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] -pub enum Reveal { - /// At type-checking time, we refuse to project any associated - /// type that is marked `default`. Non-`default` ("final") types - /// are always projected. This is necessary in general for - /// soundness of specialization. However, we *could* allow - /// projections in fully-monomorphic cases. We choose not to, - /// because we prefer for `default type` to force the type - /// definition to be treated abstractly by any consumers of the - /// impl. Concretely, that means that the following example will - /// fail to compile: - /// - /// ```compile_fail,E0308 - /// #![feature(specialization)] - /// trait Assoc { - /// type Output; - /// } - /// - /// impl Assoc for T { - /// default type Output = bool; - /// } - /// - /// fn main() { - /// let x: <() as Assoc>::Output = true; - /// } - /// ``` - /// - /// We also do not reveal the hidden type of opaque types during - /// type-checking. - UserFacing, - - /// At codegen time, all monomorphic projections will succeed. - /// Also, `impl Trait` is normalized to the concrete type, - /// which has to be already collected by type-checking. - /// - /// NOTE: as `impl Trait`'s concrete type should *never* - /// be observable directly by the user, `Reveal::All` - /// should not be used by checks which may expose - /// type equality or type contents to the user. - /// There are some exceptions, e.g., around auto traits and - /// transmute-checking, which expose some details, but - /// not the whole concrete type of the `impl Trait`. - All, -} - pub type CanonicalInput::Predicate> = ty::CanonicalQueryInput>; pub type CanonicalResponse = Canonical>; diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 3b6b3c89858..1a34b87e42a 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -11,7 +11,6 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; -use rustc_middle::traits::Reveal; use rustc_middle::ty::{ self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, TraitPredicate, Ty, TyCtxt, Upcast, }; @@ -516,7 +515,6 @@ fn typing_env_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId .upcast(tcx) }), )), - Reveal::UserFacing, ); ty::TypingEnv { typing_mode: ty::TypingMode::non_body_analysis(), diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 3498606dfd3..03e1a814a86 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -575,7 +575,7 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { /// Checks if a given type looks safe to be uninitialized. pub fn is_uninit_value_valid_for_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - let typing_env = cx.typing_env().with_reveal_all_normalized(cx.tcx); + let typing_env = cx.typing_env().with_post_analysis_normalized(cx.tcx); cx.tcx .check_validity_requirement((ValidityRequirement::Uninit, typing_env.as_query_input(ty))) .unwrap_or_else(|_| is_uninit_value_valid_for_ty_fallback(cx, ty)) -- cgit 1.4.1-3-g733a5