authorbors <bors@rust-lang.org> 2024-02-17 11:44:02 UTC
committerbors <bors@rust-lang.org> 2024-02-17 11:44:02 UTC
logba824a2e25948a86596ccf7594afe548020e86e6
tree4bb2823fcd915a42bc7f10cef4d4f2b067e1ba36
parentdfdbe30004a095ad63951c4cd6e10a9a971a7399
parente266a1230767cdbf1c1fd107e7caf0c67ab3e8c7

Auto merge of #121227 - Nadrieril:rollup-n6qky3z, r=Nadrieril

Rollup of 8 pull requests Successful merges: - #119032 (Use a hardcoded constant instead of calling OpenProcessToken.) - #120932 (const_mut_refs: allow mutable pointers to statics) - #121059 (Add and use a simple extension trait derive macro in the compiler) - #121135 (coverage: Discard spans that fill the entire function body) - #121187 (Add examples to document the return type of quickselect functions) - #121191 (Add myself to review rotation (and a rustbot ping)) - #121192 (Give some intrinsics fallback bodies) - #121197 (Ensure `./configure` works when `configure.py` path contains spaces) r? `@ghost` `@rustbot` modify labels: rollup

65 files changed, 720 insertions(+), 1151 deletions(-)

compiler/rustc_ast_lowering/src/lib.rs+3-10
......@@ -57,6 +57,7 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5757use rustc_hir::def_id::{LocalDefId, LocalDefIdMap, CRATE_DEF_ID, LOCAL_CRATE};
5858use rustc_hir::{ConstArg, GenericArg, ItemLocalMap, ParamName, TraitCandidate};
5959use rustc_index::{Idx, IndexSlice, IndexVec};
60use rustc_macros::extension;
6061use rustc_middle::span_bug;
6162use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
6263use rustc_session::parse::{add_feature_diagnostics, feature_err};
......@@ -190,16 +191,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
190191 }
191192}
192193
193trait ResolverAstLoweringExt {
194 fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>>;
195 fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
196 fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
197 fn get_label_res(&self, id: NodeId) -> Option<NodeId>;
198 fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
199 fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
200}
201
202impl ResolverAstLoweringExt for ResolverAstLowering {
194#[extension(trait ResolverAstLoweringExt)]
195impl ResolverAstLowering {
203196 fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
204197 if let ExprKind::Path(None, path) = &expr.kind {
205198 // Don't perform legacy const generics rewriting if the path already
compiler/rustc_borrowck/src/facts.rs+3-12
......@@ -2,6 +2,7 @@ use crate::location::{LocationIndex, LocationTable};
22use crate::BorrowIndex;
33use polonius_engine::AllFacts as PoloniusFacts;
44use polonius_engine::Atom;
5use rustc_macros::extension;
56use rustc_middle::mir::Local;
67use rustc_middle::ty::{RegionVid, TyCtxt};
78use rustc_mir_dataflow::move_paths::MovePathIndex;
......@@ -24,20 +25,10 @@ impl polonius_engine::FactTypes for RustcFacts {
2425
2526pub type AllFacts = PoloniusFacts<RustcFacts>;
2627
27pub(crate) trait AllFactsExt {
28#[extension(pub(crate) trait AllFactsExt)]
29impl AllFacts {
2830 /// Returns `true` if there is a need to gather `AllFacts` given the
2931 /// current `-Z` flags.
30 fn enabled(tcx: TyCtxt<'_>) -> bool;
31
32 fn write_to_dir(
33 &self,
34 dir: impl AsRef<Path>,
35 location_table: &LocationTable,
36 ) -> Result<(), Box<dyn Error>>;
37}
38
39impl AllFactsExt for AllFacts {
40 /// Return
4132 fn enabled(tcx: TyCtxt<'_>) -> bool {
4233 tcx.sess.opts.unstable_opts.nll_facts
4334 || tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled()
compiler/rustc_borrowck/src/place_ext.rs+3-11
......@@ -1,24 +1,16 @@
11use crate::borrow_set::LocalsStateAtExit;
22use rustc_hir as hir;
3use rustc_macros::extension;
34use rustc_middle::mir::ProjectionElem;
45use rustc_middle::mir::{Body, Mutability, Place};
56use rustc_middle::ty::{self, TyCtxt};
67
7/// Extension methods for the `Place` type.
8pub trait PlaceExt<'tcx> {
8#[extension(pub trait PlaceExt<'tcx>)]
9impl<'tcx> Place<'tcx> {
910 /// Returns `true` if we can safely ignore borrows of this place.
1011 /// This is true whenever there is no action that the user can do
1112 /// to the place `self` that would invalidate the borrow. This is true
1213 /// for borrows of raw pointer dereferents as well as shared references.
13 fn ignore_borrow(
14 &self,
15 tcx: TyCtxt<'tcx>,
16 body: &Body<'tcx>,
17 locals_state_at_exit: &LocalsStateAtExit,
18 ) -> bool;
19}
20
21impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
2214 fn ignore_borrow(
2315 &self,
2416 tcx: TyCtxt<'tcx>,
compiler/rustc_borrowck/src/region_infer/opaque_types.rs+3-9
......@@ -6,6 +6,7 @@ use rustc_hir::OpaqueTyOrigin;
66use rustc_infer::infer::InferCtxt;
77use rustc_infer::infer::TyCtxtInferExt as _;
88use rustc_infer::traits::{Obligation, ObligationCause};
9use rustc_macros::extension;
910use rustc_middle::traits::DefiningAnchor;
1011use rustc_middle::ty::visit::TypeVisitableExt;
1112use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
......@@ -225,15 +226,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
225226 }
226227}
227228
228pub trait InferCtxtExt<'tcx> {
229 fn infer_opaque_definition_from_instantiation(
230 &self,
231 opaque_type_key: OpaqueTypeKey<'tcx>,
232 instantiated_ty: OpaqueHiddenType<'tcx>,
233 ) -> Ty<'tcx>;
234}
235
236impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
229#[extension(pub trait InferCtxtExt<'tcx>)]
230impl<'tcx> InferCtxt<'tcx> {
237231 /// Given the fully resolved, instantiated type for an opaque
238232 /// type, i.e., the value of an inference variable like C1 or C2
239233 /// (*), computes the "definition type" for an opaque type
compiler/rustc_borrowck/src/universal_regions.rs+3-21
......@@ -22,6 +22,7 @@ use rustc_hir::lang_items::LangItem;
2222use rustc_hir::BodyOwnerKind;
2323use rustc_index::IndexVec;
2424use rustc_infer::infer::NllRegionVariableOrigin;
25use rustc_macros::extension;
2526use rustc_middle::ty::fold::TypeFoldable;
2627use rustc_middle::ty::print::with_no_trimmed_paths;
2728use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt};
......@@ -793,27 +794,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
793794 }
794795}
795796
796trait InferCtxtExt<'tcx> {
797 fn replace_free_regions_with_nll_infer_vars<T>(
798 &self,
799 origin: NllRegionVariableOrigin,
800 value: T,
801 ) -> T
802 where
803 T: TypeFoldable<TyCtxt<'tcx>>;
804
805 fn replace_bound_regions_with_nll_infer_vars<T>(
806 &self,
807 origin: NllRegionVariableOrigin,
808 all_outlive_scope: LocalDefId,
809 value: ty::Binder<'tcx, T>,
810 indices: &mut UniversalRegionIndices<'tcx>,
811 ) -> T
812 where
813 T: TypeFoldable<TyCtxt<'tcx>>;
814}
815
816impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
797#[extension(trait InferCtxtExt<'tcx>)]
798impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
817799 #[instrument(skip(self), level = "debug")]
818800 fn replace_free_regions_with_nll_infer_vars<T>(
819801 &self,
compiler/rustc_const_eval/src/transform/check_consts/check.rs+33-4
......@@ -344,7 +344,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
344344 visitor.visit_ty(ty);
345345 }
346346
347 fn check_mut_borrow(&mut self, local: Local, kind: hir::BorrowKind) {
347 fn check_mut_borrow(&mut self, place: &Place<'_>, kind: hir::BorrowKind) {
348348 match self.const_kind() {
349349 // In a const fn all borrows are transient or point to the places given via
350350 // references in the arguments (so we already checked them with
......@@ -355,10 +355,19 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
355355 // to mutable memory.
356356 hir::ConstContext::ConstFn => self.check_op(ops::TransientMutBorrow(kind)),
357357 _ => {
358 // For indirect places, we are not creating a new permanent borrow, it's just as
359 // transient as the already existing one. For reborrowing references this is handled
360 // at the top of `visit_rvalue`, but for raw pointers we handle it here.
361 // Pointers/references to `static mut` and cases where the `*` is not the first
362 // projection also end up here.
358363 // Locals with StorageDead do not live beyond the evaluation and can
359364 // thus safely be borrowed without being able to be leaked to the final
360365 // value of the constant.
361 if self.local_has_storage_dead(local) {
366 // Note: This is only sound if every local that has a `StorageDead` has a
367 // `StorageDead` in every control flow path leading to a `return` terminator.
368 // The good news is that interning will detect if any unexpected mutable
369 // pointer slips through.
370 if place.is_indirect() || self.local_has_storage_dead(place.local) {
362371 self.check_op(ops::TransientMutBorrow(kind));
363372 } else {
364373 self.check_op(ops::MutBorrow(kind));
......@@ -390,6 +399,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
390399 trace!("visit_rvalue: rvalue={:?} location={:?}", rvalue, location);
391400
392401 // Special-case reborrows to be more like a copy of a reference.
402 // FIXME: this does not actually handle all reborrows. It only detects cases where `*` is the outermost
403 // projection of the borrowed place, it skips deref'ing raw pointers and it skips `static`.
404 // All those cases are handled below with shared/mutable borrows.
405 // Once `const_mut_refs` is stable, we should be able to entirely remove this special case.
406 // (`const_refs_to_cell` is not needed, we already allow all borrows of indirect places anyway.)
393407 match *rvalue {
394408 Rvalue::Ref(_, kind, place) => {
395409 if let Some(reborrowed_place_ref) = place_as_reborrow(self.tcx, self.body, place) {
......@@ -460,7 +474,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
460474
461475 if !is_allowed {
462476 self.check_mut_borrow(
463 place.local,
477 place,
464478 if matches!(rvalue, Rvalue::Ref(..)) {
465479 hir::BorrowKind::Ref
466480 } else {
......@@ -478,7 +492,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
478492 place.as_ref(),
479493 );
480494
481 if borrowed_place_has_mut_interior {
495 // If the place is indirect, this is basically a reborrow. We have a reborrow
496 // special case above, but for raw pointers and pointers/references to `static` and
497 // when the `*` is not the first projection, `place_as_reborrow` does not recognize
498 // them as such, so we end up here. This should probably be considered a
499 // `TransientCellBorrow` (we consider the equivalent mutable case a
500 // `TransientMutBorrow`), but such reborrows got accidentally stabilized already and
501 // it is too much of a breaking change to take back.
502 if borrowed_place_has_mut_interior && !place.is_indirect() {
482503 match self.const_kind() {
483504 // In a const fn all borrows are transient or point to the places given via
484505 // references in the arguments (so we already checked them with
......@@ -495,6 +516,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
495516 // final value.
496517 // Note: This is only sound if every local that has a `StorageDead` has a
497518 // `StorageDead` in every control flow path leading to a `return` terminator.
519 // The good news is that interning will detect if any unexpected mutable
520 // pointer slips through.
498521 if self.local_has_storage_dead(place.local) {
499522 self.check_op(ops::TransientCellBorrow);
500523 } else {
......@@ -948,6 +971,12 @@ fn place_as_reborrow<'tcx>(
948971) -> Option<PlaceRef<'tcx>> {
949972 match place.as_ref().last_projection() {
950973 Some((place_base, ProjectionElem::Deref)) => {
974 // FIXME: why do statics and raw pointers get excluded here? This makes
975 // some code involving mutable pointers unstable, but it is unclear
976 // why that code is treated differently from mutable references.
977 // Once TransientMutBorrow and TransientCellBorrow are stable,
978 // this can probably be cleaned up without any behavioral changes.
979
951980 // A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const`
952981 // that points to the allocation for the static. Don't treat these as reborrows.
953982 if body.local_decls[place_base.local].is_ref_to_static() {
compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs+24
......@@ -74,6 +74,13 @@ pub trait Qualif {
7474 adt: AdtDef<'tcx>,
7575 args: GenericArgsRef<'tcx>,
7676 ) -> bool;
77
78 /// Returns `true` if this `Qualif` behaves sructurally for pointers and references:
79 /// the pointer/reference qualifies if and only if the pointee qualifies.
80 ///
81 /// (This is currently `false` for all our instances, but that may change in the future. Also,
82 /// by keeping it abstract, the handling of `Deref` in `in_place` becomes more clear.)
83 fn deref_structural<'tcx>(cx: &ConstCx<'_, 'tcx>) -> bool;
7784}
7885
7986/// Constant containing interior mutability (`UnsafeCell<T>`).
......@@ -103,6 +110,10 @@ impl Qualif for HasMutInterior {
103110 // It arises structurally for all other types.
104111 adt.is_unsafe_cell()
105112 }
113
114 fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
115 false
116 }
106117}
107118
108119/// Constant containing an ADT that implements `Drop`.
......@@ -131,6 +142,10 @@ impl Qualif for NeedsDrop {
131142 ) -> bool {
132143 adt.has_dtor(cx.tcx)
133144 }
145
146 fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
147 false
148 }
134149}
135150
136151/// Constant containing an ADT that implements non-const `Drop`.
......@@ -210,6 +225,10 @@ impl Qualif for NeedsNonConstDrop {
210225 ) -> bool {
211226 adt.has_non_const_dtor(cx.tcx)
212227 }
228
229 fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
230 false
231 }
213232}
214233
215234// FIXME: Use `mir::visit::Visitor` for the `in_*` functions if/when it supports early return.
......@@ -303,6 +322,11 @@ where
303322 return false;
304323 }
305324
325 if matches!(elem, ProjectionElem::Deref) && !Q::deref_structural(cx) {
326 // We have to assume that this qualifies.
327 return true;
328 }
329
306330 place = place_base;
307331 }
308332
compiler/rustc_hir_analysis/src/check/intrinsic.rs+3-3
......@@ -407,9 +407,9 @@ pub fn check_intrinsic_type(
407407 }
408408 sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
409409
410 sym::assume => (0, 0, vec![tcx.types.bool], Ty::new_unit(tcx)),
411 sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
412 sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
410 sym::assume => (0, 1, vec![tcx.types.bool], Ty::new_unit(tcx)),
411 sym::likely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
412 sym::unlikely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
413413
414414 sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
415415 sym::write_via_move => {
compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs+3-11
......@@ -14,6 +14,7 @@ use rustc_hir::def::{DefKind, Res};
1414use rustc_hir::def_id::LocalDefId;
1515use rustc_hir::intravisit::{self, Visitor};
1616use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node};
17use rustc_macros::extension;
1718use rustc_middle::bug;
1819use rustc_middle::hir::nested_filter;
1920use rustc_middle::middle::resolve_bound_vars::*;
......@@ -27,17 +28,8 @@ use std::fmt;
2728
2829use crate::errors;
2930
30trait RegionExt {
31 fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg);
32
33 fn late(index: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg);
34
35 fn id(&self) -> Option<DefId>;
36
37 fn shifted(self, amount: u32) -> ResolvedArg;
38}
39
40impl RegionExt for ResolvedArg {
31#[extension(trait RegionExt)]
32impl ResolvedArg {
4133 fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
4234 debug!("ResolvedArg::early: def_id={:?}", param.def_id);
4335 (param.def_id, ResolvedArg::EarlyBound(param.def_id.to_def_id()))
compiler/rustc_infer/src/infer/canonical/instantiate.rs+6-20
......@@ -13,12 +13,16 @@ use rustc_middle::ty::{self, TyCtxt};
1313
1414/// FIXME(-Znext-solver): This or public because it is shared with the
1515/// new trait solver implementation. We should deduplicate canonicalization.
16pub trait CanonicalExt<'tcx, V> {
16#[extension(pub trait CanonicalExt<'tcx, V>)]
17impl<'tcx, V> Canonical<'tcx, V> {
1718 /// Instantiate the wrapped value, replacing each canonical value
1819 /// with the value given in `var_values`.
1920 fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
2021 where
21 V: TypeFoldable<TyCtxt<'tcx>>;
22 V: TypeFoldable<TyCtxt<'tcx>>,
23 {
24 self.instantiate_projected(tcx, var_values, |value| value.clone())
25 }
2226
2327 /// Allows one to apply a instantiation to some subset of
2428 /// `self.value`. Invoke `projection_fn` with `self.value` to get
......@@ -26,24 +30,6 @@ pub trait CanonicalExt<'tcx, V> {
2630 /// variables bound in `self` (usually this extracts from subset
2731 /// of `self`). Apply the instantiation `var_values` to this value
2832 /// V, replacing each of the canonical variables.
29 fn instantiate_projected<T>(
30 &self,
31 tcx: TyCtxt<'tcx>,
32 var_values: &CanonicalVarValues<'tcx>,
33 projection_fn: impl FnOnce(&V) -> T,
34 ) -> T
35 where
36 T: TypeFoldable<TyCtxt<'tcx>>;
37}
38
39impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> {
40 fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
41 where
42 V: TypeFoldable<TyCtxt<'tcx>>,
43 {
44 self.instantiate_projected(tcx, var_values, |value| value.clone())
45 }
46
4733 fn instantiate_projected<T>(
4834 &self,
4935 tcx: TyCtxt<'tcx>,
compiler/rustc_infer/src/infer/error_reporting/mod.rs+2-13
......@@ -2786,19 +2786,8 @@ pub enum FailureCode {
27862786 Error0644,
27872787}
27882788
2789pub trait ObligationCauseExt<'tcx> {
2790 fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode;
2791
2792 fn as_failure_code_diag(
2793 &self,
2794 terr: TypeError<'tcx>,
2795 span: Span,
2796 subdiags: Vec<TypeErrorAdditionalDiags>,
2797 ) -> ObligationCauseFailureCode;
2798 fn as_requirement_str(&self) -> &'static str;
2799}
2800
2801impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
2789#[extension(pub trait ObligationCauseExt<'tcx>)]
2790impl<'tcx> ObligationCause<'tcx> {
28022791 fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode {
28032792 use self::FailureCode::*;
28042793 use crate::traits::ObligationCauseCode::*;
compiler/rustc_infer/src/infer/mod.rs+2-5
......@@ -626,11 +626,8 @@ pub struct InferCtxtBuilder<'tcx> {
626626 next_trait_solver: bool,
627627}
628628
629pub trait TyCtxtInferExt<'tcx> {
630 fn infer_ctxt(self) -> InferCtxtBuilder<'tcx>;
631}
632
633impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
629#[extension(pub trait TyCtxtInferExt<'tcx>)]
630impl<'tcx> TyCtxt<'tcx> {
634631 fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
635632 InferCtxtBuilder {
636633 tcx: self,
compiler/rustc_infer/src/traits/engine.rs+3-12
......@@ -52,18 +52,8 @@ pub trait TraitEngine<'tcx>: 'tcx {
5252 ) -> Vec<PredicateObligation<'tcx>>;
5353}
5454
55pub trait TraitEngineExt<'tcx> {
56 fn register_predicate_obligations(
57 &mut self,
58 infcx: &InferCtxt<'tcx>,
59 obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
60 );
61
62 #[must_use]
63 fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
64}
65
66impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
55#[extension(pub trait TraitEngineExt<'tcx>)]
56impl<'tcx, T: ?Sized + TraitEngine<'tcx>> T {
6757 fn register_predicate_obligations(
6858 &mut self,
6959 infcx: &InferCtxt<'tcx>,
......@@ -74,6 +64,7 @@ impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
7464 }
7565 }
7666
67 #[must_use]
7768 fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
7869 let errors = self.select_where_possible(infcx);
7970 if !errors.is_empty() {
compiler/rustc_macros/src/extension.rs created+154
......@@ -0,0 +1,154 @@
1use proc_macro2::Ident;
2use quote::quote;
3use syn::parse::{Parse, ParseStream};
4use syn::punctuated::Punctuated;
5use syn::spanned::Spanned;
6use syn::{
7 braced, parse_macro_input, Attribute, Generics, ImplItem, Pat, PatIdent, Path, Signature,
8 Token, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, Type, Visibility,
9};
10
11pub(crate) fn extension(
12 attr: proc_macro::TokenStream,
13 input: proc_macro::TokenStream,
14) -> proc_macro::TokenStream {
15 let ExtensionAttr { vis, trait_ } = parse_macro_input!(attr as ExtensionAttr);
16 let Impl { attrs, generics, self_ty, items } = parse_macro_input!(input as Impl);
17 let headers: Vec<_> = items
18 .iter()
19 .map(|item| match item {
20 ImplItem::Fn(f) => TraitItem::Fn(TraitItemFn {
21 attrs: scrub_attrs(&f.attrs),
22 sig: scrub_header(f.sig.clone()),
23 default: None,
24 semi_token: Some(Token![;](f.block.span())),
25 }),
26 ImplItem::Const(ct) => TraitItem::Const(TraitItemConst {
27 attrs: scrub_attrs(&ct.attrs),
28 const_token: ct.const_token,
29 ident: ct.ident.clone(),
30 generics: ct.generics.clone(),
31 colon_token: ct.colon_token,
32 ty: ct.ty.clone(),
33 default: None,
34 semi_token: ct.semi_token,
35 }),
36 ImplItem::Type(ty) => TraitItem::Type(TraitItemType {
37 attrs: scrub_attrs(&ty.attrs),
38 type_token: ty.type_token,
39 ident: ty.ident.clone(),
40 generics: ty.generics.clone(),
41 colon_token: None,
42 bounds: Punctuated::new(),
43 default: None,
44 semi_token: ty.semi_token,
45 }),
46 ImplItem::Macro(mac) => TraitItem::Macro(TraitItemMacro {
47 attrs: scrub_attrs(&mac.attrs),
48 mac: mac.mac.clone(),
49 semi_token: mac.semi_token,
50 }),
51 ImplItem::Verbatim(stream) => TraitItem::Verbatim(stream.clone()),
52 _ => unimplemented!(),
53 })
54 .collect();
55
56 quote! {
57 #(#attrs)*
58 #vis trait #trait_ {
59 #(#headers)*
60 }
61
62 impl #generics #trait_ for #self_ty {
63 #(#items)*
64 }
65 }
66 .into()
67}
68
69/// Only keep `#[doc]` attrs.
70fn scrub_attrs(attrs: &[Attribute]) -> Vec<Attribute> {
71 attrs
72 .into_iter()
73 .cloned()
74 .filter(|attr| {
75 let ident = &attr.path().segments[0].ident;
76 ident == "doc" || ident == "must_use"
77 })
78 .collect()
79}
80
81/// Scrub arguments so that they're valid for trait signatures.
82fn scrub_header(mut sig: Signature) -> Signature {
83 for (idx, input) in sig.inputs.iter_mut().enumerate() {
84 match input {
85 syn::FnArg::Receiver(rcvr) => {
86 // `mut self` -> `self`
87 if rcvr.reference.is_none() {
88 rcvr.mutability.take();
89 }
90 }
91 syn::FnArg::Typed(arg) => match &mut *arg.pat {
92 Pat::Ident(arg) => {
93 // `ref mut ident @ pat` -> `ident`
94 arg.by_ref.take();
95 arg.mutability.take();
96 arg.subpat.take();
97 }
98 _ => {
99 // `pat` -> `__arg0`
100 arg.pat = Box::new(
101 PatIdent {
102 attrs: vec![],
103 by_ref: None,
104 mutability: None,
105 ident: Ident::new(&format!("__arg{idx}"), arg.pat.span()),
106 subpat: None,
107 }
108 .into(),
109 )
110 }
111 },
112 }
113 }
114 sig
115}
116
117struct ExtensionAttr {
118 vis: Visibility,
119 trait_: Path,
120}
121
122impl Parse for ExtensionAttr {
123 fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
124 let vis = input.parse()?;
125 let _: Token![trait] = input.parse()?;
126 let trait_ = input.parse()?;
127 Ok(ExtensionAttr { vis, trait_ })
128 }
129}
130
131struct Impl {
132 attrs: Vec<Attribute>,
133 generics: Generics,
134 self_ty: Type,
135 items: Vec<ImplItem>,
136}
137
138impl Parse for Impl {
139 fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
140 let attrs = input.call(Attribute::parse_outer)?;
141 let _: Token![impl] = input.parse()?;
142 let generics = input.parse()?;
143 let self_ty = input.parse()?;
144
145 let content;
146 let _brace_token = braced!(content in input);
147 let mut items = Vec::new();
148 while !content.is_empty() {
149 items.push(content.parse()?);
150 }
151
152 Ok(Impl { attrs, generics, self_ty, items })
153 }
154}
compiler/rustc_macros/src/lib.rs+6
......@@ -14,6 +14,7 @@ use proc_macro::TokenStream;
1414
1515mod current_version;
1616mod diagnostics;
17mod extension;
1718mod hash_stable;
1819mod lift;
1920mod query;
......@@ -40,6 +41,11 @@ pub fn symbols(input: TokenStream) -> TokenStream {
4041 symbols::symbols(input.into()).into()
4142}
4243
44#[proc_macro_attribute]
45pub fn extension(attr: TokenStream, input: TokenStream) -> TokenStream {
46 extension::extension(attr, input)
47}
48
4349decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
4450decl_derive!(
4551 [HashStable_Generic, attributes(stable_hasher)] =>
compiler/rustc_middle/src/ty/layout.rs+4-20
......@@ -23,20 +23,8 @@ use std::fmt;
2323use std::num::NonZero;
2424use std::ops::Bound;
2525
26pub trait IntegerExt {
27 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
28 fn from_int_ty<C: HasDataLayout>(cx: &C, ity: ty::IntTy) -> Integer;
29 fn from_uint_ty<C: HasDataLayout>(cx: &C, uty: ty::UintTy) -> Integer;
30 fn repr_discr<'tcx>(
31 tcx: TyCtxt<'tcx>,
32 ty: Ty<'tcx>,
33 repr: &ReprOptions,
34 min: i128,
35 max: i128,
36 ) -> (Integer, bool);
37}
38
39impl IntegerExt for Integer {
26#[extension(pub trait IntegerExt)]
27impl Integer {
4028 #[inline]
4129 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx> {
4230 match (*self, signed) {
......@@ -123,12 +111,8 @@ impl IntegerExt for Integer {
123111 }
124112}
125113
126pub trait PrimitiveExt {
127 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
128 fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
129}
130
131impl PrimitiveExt for Primitive {
114#[extension(pub trait PrimitiveExt)]
115impl Primitive {
132116 #[inline]
133117 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
134118 match *self {
compiler/rustc_middle/src/ty/util.rs+2-7
......@@ -96,13 +96,8 @@ impl<'tcx> Discr<'tcx> {
9696 }
9797}
9898
99pub trait IntTypeExt {
100 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
101 fn disr_incr<'tcx>(&self, tcx: TyCtxt<'tcx>, val: Option<Discr<'tcx>>) -> Option<Discr<'tcx>>;
102 fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Discr<'tcx>;
103}
104
105impl IntTypeExt for IntegerType {
99#[extension(pub trait IntTypeExt)]
100impl IntegerType {
106101 fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
107102 match self {
108103 IntegerType::Pointer(true) => tcx.types.isize,
compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs+9-4
......@@ -132,18 +132,23 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
132132 bcb_data.basic_blocks.iter().flat_map(move |&bb| {
133133 let data = &mir_body[bb];
134134
135 let unexpand = move |expn_span| {
136 unexpand_into_body_span_with_visible_macro(expn_span, body_span)
137 // Discard any spans that fill the entire body, because they tend
138 // to represent compiler-inserted code, e.g. implicitly returning `()`.
139 .filter(|(span, _)| !span.source_equal(body_span))
140 };
141
135142 let statement_spans = data.statements.iter().filter_map(move |statement| {
136143 let expn_span = filtered_statement_span(statement)?;
137 let (span, visible_macro) =
138 unexpand_into_body_span_with_visible_macro(expn_span, body_span)?;
144 let (span, visible_macro) = unexpand(expn_span)?;
139145
140146 Some(SpanFromMir::new(span, visible_macro, bcb, is_closure_like(statement)))
141147 });
142148
143149 let terminator_span = Some(data.terminator()).into_iter().filter_map(move |terminator| {
144150 let expn_span = filtered_terminator_span(terminator)?;
145 let (span, visible_macro) =
146 unexpand_into_body_span_with_visible_macro(expn_span, body_span)?;
151 let (span, visible_macro) = unexpand(expn_span)?;
147152
148153 Some(SpanFromMir::new(span, visible_macro, bcb, false))
149154 });
compiler/rustc_trait_selection/src/infer.rs+26-56
......@@ -17,49 +17,8 @@ use std::fmt::Debug;
1717
1818pub use rustc_infer::infer::*;
1919
20pub trait InferCtxtExt<'tcx> {
21 fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool;
22
23 fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool;
24
25 /// Check whether a `ty` implements given trait(trait_def_id) without side-effects.
26 ///
27 /// The inputs are:
28 ///
29 /// - the def-id of the trait
30 /// - the type parameters of the trait, including the self-type
31 /// - the parameter environment
32 ///
33 /// Invokes `evaluate_obligation`, so in the event that evaluating
34 /// `Ty: Trait` causes overflow, EvaluatedToErrStackDependent
35 /// (or EvaluatedToAmbigStackDependent) will be returned.
36 fn type_implements_trait(
37 &self,
38 trait_def_id: DefId,
39 params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
40 param_env: ty::ParamEnv<'tcx>,
41 ) -> traits::EvaluationResult;
42
43 /// Returns `Some` if a type implements a trait shallowly, without side-effects,
44 /// along with any errors that would have been reported upon further obligation
45 /// processing.
46 ///
47 /// - If this returns `Some([])`, then the trait holds modulo regions.
48 /// - If this returns `Some([errors..])`, then the trait has an impl for
49 /// the self type, but some nested obligations do not hold.
50 /// - If this returns `None`, no implementation that applies could be found.
51 ///
52 /// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
53 /// this will probably only ever return `Some([])` or `None`.
54 fn type_implements_trait_shallow(
55 &self,
56 trait_def_id: DefId,
57 ty: Ty<'tcx>,
58 param_env: ty::ParamEnv<'tcx>,
59 ) -> Option<Vec<traits::FulfillmentError<'tcx>>>;
60}
61
62impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
20#[extension(pub trait InferCtxtExt<'tcx>)]
21impl<'tcx> InferCtxt<'tcx> {
6322 fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
6423 let ty = self.resolve_vars_if_possible(ty);
6524
......@@ -81,6 +40,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
8140 traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)
8241 }
8342
43 /// Check whether a `ty` implements given trait(trait_def_id) without side-effects.
44 ///
45 /// The inputs are:
46 ///
47 /// - the def-id of the trait
48 /// - the type parameters of the trait, including the self-type
49 /// - the parameter environment
50 ///
51 /// Invokes `evaluate_obligation`, so in the event that evaluating
52 /// `Ty: Trait` causes overflow, EvaluatedToErrStackDependent
53 /// (or EvaluatedToAmbigStackDependent) will be returned.
8454 #[instrument(level = "debug", skip(self, params), ret)]
8555 fn type_implements_trait(
8656 &self,
......@@ -99,6 +69,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
9969 self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr)
10070 }
10171
72 /// Returns `Some` if a type implements a trait shallowly, without side-effects,
73 /// along with any errors that would have been reported upon further obligation
74 /// processing.
75 ///
76 /// - If this returns `Some([])`, then the trait holds modulo regions.
77 /// - If this returns `Some([errors..])`, then the trait has an impl for
78 /// the self type, but some nested obligations do not hold.
79 /// - If this returns `None`, no implementation that applies could be found.
80 ///
81 /// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
82 /// this will probably only ever return `Some([])` or `None`.
10283 fn type_implements_trait_shallow(
10384 &self,
10485 trait_def_id: DefId,
......@@ -124,19 +105,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
124105 }
125106}
126107
127pub trait InferCtxtBuilderExt<'tcx> {
128 fn enter_canonical_trait_query<K, R>(
129 self,
130 canonical_key: &Canonical<'tcx, K>,
131 operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
132 ) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
133 where
134 K: TypeFoldable<TyCtxt<'tcx>>,
135 R: Debug + TypeFoldable<TyCtxt<'tcx>>,
136 Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>;
137}
138
139impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
108#[extension(pub trait InferCtxtBuilderExt<'tcx>)]
109impl<'tcx> InferCtxtBuilder<'tcx> {
140110 /// The "main method" for a canonicalized trait query. Given the
141111 /// canonical key `canonical_key`, this method will create a new
142112 /// inference context, instantiate the key, and run your operation
compiler/rustc_trait_selection/src/regions.rs+2-8
......@@ -3,20 +3,14 @@ use rustc_infer::infer::{InferCtxt, RegionResolutionError};
33use rustc_middle::traits::query::NoSolution;
44use rustc_middle::traits::ObligationCause;
55
6pub trait InferCtxtRegionExt<'tcx> {
6#[extension(pub trait InferCtxtRegionExt<'tcx>)]
7impl<'tcx> InferCtxt<'tcx> {
78 /// Resolve regions, using the deep normalizer to normalize any type-outlives
89 /// obligations in the process. This is in `rustc_trait_selection` because
910 /// we need to normalize.
1011 ///
1112 /// Prefer this method over `resolve_regions_with_normalize`, unless you are
1213 /// doing something specific for normalization.
13 fn resolve_regions(
14 &self,
15 outlives_env: &OutlivesEnvironment<'tcx>,
16 ) -> Vec<RegionResolutionError<'tcx>>;
17}
18
19impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
2014 fn resolve_regions(
2115 &self,
2216 outlives_env: &OutlivesEnvironment<'tcx>,
compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs+2-12
......@@ -131,22 +131,12 @@ pub enum GenerateProofTree {
131131 Never,
132132}
133133
134pub trait InferCtxtEvalExt<'tcx> {
134#[extension(pub trait InferCtxtEvalExt<'tcx>)]
135impl<'tcx> InferCtxt<'tcx> {
135136 /// Evaluates a goal from **outside** of the trait solver.
136137 ///
137138 /// Using this while inside of the solver is wrong as it uses a new
138139 /// search graph which would break cycle detection.
139 fn evaluate_root_goal(
140 &self,
141 goal: Goal<'tcx, ty::Predicate<'tcx>>,
142 generate_proof_tree: GenerateProofTree,
143 ) -> (
144 Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>,
145 Option<inspect::GoalEvaluation<'tcx>>,
146 );
147}
148
149impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
150140 #[instrument(level = "debug", skip(self))]
151141 fn evaluate_root_goal(
152142 &self,
compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs+2-8
......@@ -17,14 +17,8 @@ use crate::solve::inspect::ProofTreeBuilder;
1717use crate::traits::StructurallyNormalizeExt;
1818use crate::traits::TraitEngineExt;
1919
20pub trait InferCtxtSelectExt<'tcx> {
21 fn select_in_new_trait_solver(
22 &self,
23 obligation: &PolyTraitObligation<'tcx>,
24 ) -> SelectionResult<'tcx, Selection<'tcx>>;
25}
26
27impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
20#[extension(pub trait InferCtxtSelectExt<'tcx>)]
21impl<'tcx> InferCtxt<'tcx> {
2822 fn select_in_new_trait_solver(
2923 &self,
3024 obligation: &PolyTraitObligation<'tcx>,
compiler/rustc_trait_selection/src/solve/inspect/analyse.rs+2-9
......@@ -216,15 +216,8 @@ pub trait ProofTreeVisitor<'tcx> {
216216 fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> ControlFlow<Self::BreakTy>;
217217}
218218
219pub trait ProofTreeInferCtxtExt<'tcx> {
220 fn visit_proof_tree<V: ProofTreeVisitor<'tcx>>(
221 &self,
222 goal: Goal<'tcx, ty::Predicate<'tcx>>,
223 visitor: &mut V,
224 ) -> ControlFlow<V::BreakTy>;
225}
226
227impl<'tcx> ProofTreeInferCtxtExt<'tcx> for InferCtxt<'tcx> {
219#[extension(pub trait ProofTreeInferCtxtExt<'tcx>)]
220impl<'tcx> InferCtxt<'tcx> {
228221 fn visit_proof_tree<V: ProofTreeVisitor<'tcx>>(
229222 &self,
230223 goal: Goal<'tcx, ty::Predicate<'tcx>>,
compiler/rustc_trait_selection/src/solve/mod.rs+2-5
......@@ -61,11 +61,8 @@ enum GoalEvaluationKind {
6161 Nested { is_normalizes_to_hack: IsNormalizesToHack },
6262}
6363
64trait CanonicalResponseExt {
65 fn has_no_inference_or_external_constraints(&self) -> bool;
66}
67
68impl<'tcx> CanonicalResponseExt for Canonical<'tcx, Response<'tcx>> {
64#[extension(trait CanonicalResponseExt)]
65impl<'tcx> Canonical<'tcx, Response<'tcx>> {
6966 fn has_no_inference_or_external_constraints(&self) -> bool {
7067 self.value.external_constraints.region_constraints.is_empty()
7168 && self.value.var_values.is_identity()
compiler/rustc_trait_selection/src/traits/engine.rs+2-5
......@@ -27,11 +27,8 @@ use rustc_middle::ty::TypeFoldable;
2727use rustc_middle::ty::Variance;
2828use rustc_middle::ty::{self, Ty, TyCtxt};
2929
30pub trait TraitEngineExt<'tcx> {
31 fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>;
32}
33
34impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
30#[extension(pub trait TraitEngineExt<'tcx>)]
31impl<'tcx> dyn TraitEngine<'tcx> {
3532 fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
3633 if infcx.next_trait_solver() {
3734 Box::new(NextFulfillmentCtxt::new(infcx))
compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs+5-32
......@@ -11,38 +11,8 @@ use super::ArgKind;
1111
1212pub use rustc_infer::traits::error_reporting::*;
1313
14pub trait InferCtxtExt<'tcx> {
15 /// Given some node representing a fn-like thing in the HIR map,
16 /// returns a span and `ArgKind` information that describes the
17 /// arguments it expects. This can be supplied to
18 /// `report_arg_count_mismatch`.
19 fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Option<Span>, Vec<ArgKind>)>;
20
21 /// Reports an error when the number of arguments needed by a
22 /// trait match doesn't match the number that the expression
23 /// provides.
24 fn report_arg_count_mismatch(
25 &self,
26 span: Span,
27 found_span: Option<Span>,
28 expected_args: Vec<ArgKind>,
29 found_args: Vec<ArgKind>,
30 is_closure: bool,
31 closure_pipe_span: Option<Span>,
32 ) -> DiagnosticBuilder<'tcx>;
33
34 /// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
35 /// in that order, and returns the generic type corresponding to the
36 /// argument of that trait (corresponding to the closure arguments).
37 fn type_implements_fn_trait(
38 &self,
39 param_env: ty::ParamEnv<'tcx>,
40 ty: ty::Binder<'tcx, Ty<'tcx>>,
41 polarity: ty::ImplPolarity,
42 ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()>;
43}
44
45impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
14#[extension(pub trait InferCtxtExt<'tcx>)]
15impl<'tcx> InferCtxt<'tcx> {
4616 /// Given some node representing a fn-like thing in the HIR map,
4717 /// returns a span and `ArgKind` information that describes the
4818 /// arguments it expects. This can be supplied to
......@@ -229,6 +199,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
229199 err
230200 }
231201
202 /// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
203 /// in that order, and returns the generic type corresponding to the
204 /// argument of that trait (corresponding to the closure arguments).
232205 fn type_implements_fn_trait(
233206 &self,
234207 param_env: ty::ParamEnv<'tcx>,
compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs+2-19
......@@ -23,24 +23,6 @@ use crate::errors::{
2323
2424use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt;
2525
26pub trait TypeErrCtxtExt<'tcx> {
27 /*private*/
28 fn impl_similar_to(
29 &self,
30 trait_ref: ty::PolyTraitRef<'tcx>,
31 obligation: &PredicateObligation<'tcx>,
32 ) -> Option<(DefId, GenericArgsRef<'tcx>)>;
33
34 /*private*/
35 fn describe_enclosure(&self, def_id: LocalDefId) -> Option<&'static str>;
36
37 fn on_unimplemented_note(
38 &self,
39 trait_ref: ty::PolyTraitRef<'tcx>,
40 obligation: &PredicateObligation<'tcx>,
41 ) -> OnUnimplementedNote;
42}
43
4426/// The symbols which are always allowed in a format string
4527static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
4628 kw::SelfUpper,
......@@ -56,7 +38,8 @@ static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
5638 sym::Trait,
5739];
5840
59impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
41#[extension(pub trait TypeErrCtxtExt<'tcx>)]
42impl<'tcx> TypeErrCtxt<'_, 'tcx> {
6043 fn impl_similar_to(
6144 &self,
6245 trait_ref: ty::PolyTraitRef<'tcx>,
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs+2-274
......@@ -106,279 +106,6 @@ impl<'tcx, 'a> CoroutineData<'tcx, 'a> {
106106 }
107107}
108108
109// This trait is public to expose the diagnostics methods to clippy.
110pub trait TypeErrCtxtExt<'tcx> {
111 fn suggest_restricting_param_bound(
112 &self,
113 err: &mut Diagnostic,
114 trait_pred: ty::PolyTraitPredicate<'tcx>,
115 associated_item: Option<(&'static str, Ty<'tcx>)>,
116 body_id: LocalDefId,
117 );
118
119 fn suggest_dereferences(
120 &self,
121 obligation: &PredicateObligation<'tcx>,
122 err: &mut Diagnostic,
123 trait_pred: ty::PolyTraitPredicate<'tcx>,
124 ) -> bool;
125
126 fn get_closure_name(
127 &self,
128 def_id: DefId,
129 err: &mut Diagnostic,
130 msg: Cow<'static, str>,
131 ) -> Option<Symbol>;
132
133 fn suggest_fn_call(
134 &self,
135 obligation: &PredicateObligation<'tcx>,
136 err: &mut Diagnostic,
137 trait_pred: ty::PolyTraitPredicate<'tcx>,
138 ) -> bool;
139
140 fn check_for_binding_assigned_block_without_tail_expression(
141 &self,
142 obligation: &PredicateObligation<'tcx>,
143 err: &mut Diagnostic,
144 trait_pred: ty::PolyTraitPredicate<'tcx>,
145 );
146
147 fn suggest_add_clone_to_arg(
148 &self,
149 obligation: &PredicateObligation<'tcx>,
150 err: &mut Diagnostic,
151 trait_pred: ty::PolyTraitPredicate<'tcx>,
152 ) -> bool;
153
154 fn extract_callable_info(
155 &self,
156 body_id: LocalDefId,
157 param_env: ty::ParamEnv<'tcx>,
158 found: Ty<'tcx>,
159 ) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)>;
160
161 fn suggest_add_reference_to_arg(
162 &self,
163 obligation: &PredicateObligation<'tcx>,
164 err: &mut Diagnostic,
165 trait_pred: ty::PolyTraitPredicate<'tcx>,
166 has_custom_message: bool,
167 ) -> bool;
168
169 fn suggest_borrowing_for_object_cast(
170 &self,
171 err: &mut Diagnostic,
172 obligation: &PredicateObligation<'tcx>,
173 self_ty: Ty<'tcx>,
174 object_ty: Ty<'tcx>,
175 );
176
177 fn suggest_remove_reference(
178 &self,
179 obligation: &PredicateObligation<'tcx>,
180 err: &mut Diagnostic,
181 trait_pred: ty::PolyTraitPredicate<'tcx>,
182 ) -> bool;
183
184 fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic);
185
186 fn suggest_change_mut(
187 &self,
188 obligation: &PredicateObligation<'tcx>,
189 err: &mut Diagnostic,
190 trait_pred: ty::PolyTraitPredicate<'tcx>,
191 );
192
193 fn suggest_semicolon_removal(
194 &self,
195 obligation: &PredicateObligation<'tcx>,
196 err: &mut Diagnostic,
197 span: Span,
198 trait_pred: ty::PolyTraitPredicate<'tcx>,
199 ) -> bool;
200
201 fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span>;
202
203 fn suggest_impl_trait(
204 &self,
205 err: &mut Diagnostic,
206 obligation: &PredicateObligation<'tcx>,
207 trait_pred: ty::PolyTraitPredicate<'tcx>,
208 ) -> bool;
209
210 fn point_at_returns_when_relevant(
211 &self,
212 err: &mut DiagnosticBuilder<'tcx>,
213 obligation: &PredicateObligation<'tcx>,
214 );
215
216 fn report_closure_arg_mismatch(
217 &self,
218 span: Span,
219 found_span: Option<Span>,
220 found: ty::PolyTraitRef<'tcx>,
221 expected: ty::PolyTraitRef<'tcx>,
222 cause: &ObligationCauseCode<'tcx>,
223 found_node: Option<Node<'_>>,
224 param_env: ty::ParamEnv<'tcx>,
225 ) -> DiagnosticBuilder<'tcx>;
226
227 fn note_conflicting_fn_args(
228 &self,
229 err: &mut Diagnostic,
230 cause: &ObligationCauseCode<'tcx>,
231 expected: Ty<'tcx>,
232 found: Ty<'tcx>,
233 param_env: ty::ParamEnv<'tcx>,
234 );
235
236 fn note_conflicting_closure_bounds(
237 &self,
238 cause: &ObligationCauseCode<'tcx>,
239 err: &mut DiagnosticBuilder<'tcx>,
240 );
241
242 fn suggest_fully_qualified_path(
243 &self,
244 err: &mut Diagnostic,
245 item_def_id: DefId,
246 span: Span,
247 trait_ref: DefId,
248 );
249
250 fn maybe_note_obligation_cause_for_async_await(
251 &self,
252 err: &mut Diagnostic,
253 obligation: &PredicateObligation<'tcx>,
254 ) -> bool;
255
256 fn note_obligation_cause_for_async_await(
257 &self,
258 err: &mut Diagnostic,
259 interior_or_upvar_span: CoroutineInteriorOrUpvar,
260 is_async: bool,
261 outer_coroutine: Option<DefId>,
262 trait_pred: ty::TraitPredicate<'tcx>,
263 target_ty: Ty<'tcx>,
264 obligation: &PredicateObligation<'tcx>,
265 next_code: Option<&ObligationCauseCode<'tcx>>,
266 );
267
268 fn note_obligation_cause_code<T>(
269 &self,
270 body_id: LocalDefId,
271 err: &mut Diagnostic,
272 predicate: T,
273 param_env: ty::ParamEnv<'tcx>,
274 cause_code: &ObligationCauseCode<'tcx>,
275 obligated_types: &mut Vec<Ty<'tcx>>,
276 seen_requirements: &mut FxHashSet<DefId>,
277 ) where
278 T: ToPredicate<'tcx>;
279
280 /// Suggest to await before try: future? => future.await?
281 fn suggest_await_before_try(
282 &self,
283 err: &mut Diagnostic,
284 obligation: &PredicateObligation<'tcx>,
285 trait_pred: ty::PolyTraitPredicate<'tcx>,
286 span: Span,
287 );
288
289 fn suggest_floating_point_literal(
290 &self,
291 obligation: &PredicateObligation<'tcx>,
292 err: &mut Diagnostic,
293 trait_ref: &ty::PolyTraitRef<'tcx>,
294 );
295
296 fn suggest_derive(
297 &self,
298 obligation: &PredicateObligation<'tcx>,
299 err: &mut Diagnostic,
300 trait_pred: ty::PolyTraitPredicate<'tcx>,
301 );
302
303 fn suggest_dereferencing_index(
304 &self,
305 obligation: &PredicateObligation<'tcx>,
306 err: &mut Diagnostic,
307 trait_pred: ty::PolyTraitPredicate<'tcx>,
308 );
309
310 fn suggest_option_method_if_applicable(
311 &self,
312 failed_pred: ty::Predicate<'tcx>,
313 param_env: ty::ParamEnv<'tcx>,
314 err: &mut Diagnostic,
315 expr: &hir::Expr<'_>,
316 );
317
318 fn note_function_argument_obligation(
319 &self,
320 body_id: LocalDefId,
321 err: &mut Diagnostic,
322 arg_hir_id: HirId,
323 parent_code: &ObligationCauseCode<'tcx>,
324 param_env: ty::ParamEnv<'tcx>,
325 predicate: ty::Predicate<'tcx>,
326 call_hir_id: HirId,
327 );
328
329 fn look_for_iterator_item_mistakes(
330 &self,
331 assocs_in_this_method: &[Option<(Span, (DefId, Ty<'tcx>))>],
332 typeck_results: &TypeckResults<'tcx>,
333 type_diffs: &[TypeError<'tcx>],
334 param_env: ty::ParamEnv<'tcx>,
335 path_segment: &hir::PathSegment<'_>,
336 args: &[hir::Expr<'_>],
337 err: &mut Diagnostic,
338 );
339
340 fn point_at_chain(
341 &self,
342 expr: &hir::Expr<'_>,
343 typeck_results: &TypeckResults<'tcx>,
344 type_diffs: Vec<TypeError<'tcx>>,
345 param_env: ty::ParamEnv<'tcx>,
346 err: &mut Diagnostic,
347 );
348
349 fn probe_assoc_types_at_expr(
350 &self,
351 type_diffs: &[TypeError<'tcx>],
352 span: Span,
353 prev_ty: Ty<'tcx>,
354 body_id: hir::HirId,
355 param_env: ty::ParamEnv<'tcx>,
356 ) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>>;
357
358 fn suggest_convert_to_slice(
359 &self,
360 err: &mut Diagnostic,
361 obligation: &PredicateObligation<'tcx>,
362 trait_ref: ty::PolyTraitRef<'tcx>,
363 candidate_impls: &[ImplCandidate<'tcx>],
364 span: Span,
365 );
366
367 fn explain_hrtb_projection(
368 &self,
369 diag: &mut Diagnostic,
370 pred: ty::PolyTraitPredicate<'tcx>,
371 param_env: ty::ParamEnv<'tcx>,
372 cause: &ObligationCause<'tcx>,
373 );
374
375 fn suggest_desugaring_async_fn_in_trait(
376 &self,
377 err: &mut Diagnostic,
378 trait_ref: ty::PolyTraitRef<'tcx>,
379 );
380}
381
382109fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
383110 (
384111 generics.tail_span_for_predicate_suggestion(),
......@@ -509,7 +236,8 @@ pub fn suggest_restriction<'tcx>(
509236 }
510237}
511238
512impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
239#[extension(pub trait TypeErrCtxtExt<'tcx>)]
240impl<'tcx> TypeErrCtxt<'_, 'tcx> {
513241 fn suggest_restricting_param_bound(
514242 &self,
515243 err: &mut Diagnostic,
compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs+11-275
......@@ -57,78 +57,8 @@ use super::{
5757
5858pub use rustc_infer::traits::error_reporting::*;
5959
60pub trait TypeErrCtxtExt<'tcx> {
61 fn build_overflow_error<T>(
62 &self,
63 predicate: &T,
64 span: Span,
65 suggest_increasing_limit: bool,
66 ) -> DiagnosticBuilder<'tcx>
67 where
68 T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
69
70 fn report_overflow_error<T>(
71 &self,
72 predicate: &T,
73 span: Span,
74 suggest_increasing_limit: bool,
75 mutate: impl FnOnce(&mut Diagnostic),
76 ) -> !
77 where
78 T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
79
80 fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed;
81
82 fn report_fulfillment_errors(&self, errors: Vec<FulfillmentError<'tcx>>) -> ErrorGuaranteed;
83
84 fn report_overflow_obligation<T>(
85 &self,
86 obligation: &Obligation<'tcx, T>,
87 suggest_increasing_limit: bool,
88 ) -> !
89 where
90 T: ToPredicate<'tcx> + Clone;
91
92 fn suggest_new_overflow_limit(&self, err: &mut Diagnostic);
93
94 fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> !;
95
96 /// The `root_obligation` parameter should be the `root_obligation` field
97 /// from a `FulfillmentError`. If no `FulfillmentError` is available,
98 /// then it should be the same as `obligation`.
99 fn report_selection_error(
100 &self,
101 obligation: PredicateObligation<'tcx>,
102 root_obligation: &PredicateObligation<'tcx>,
103 error: &SelectionError<'tcx>,
104 ) -> ErrorGuaranteed;
105
106 fn emit_specialized_closure_kind_error(
107 &self,
108 obligation: &PredicateObligation<'tcx>,
109 trait_ref: ty::PolyTraitRef<'tcx>,
110 ) -> Option<ErrorGuaranteed>;
111
112 fn fn_arg_obligation(
113 &self,
114 obligation: &PredicateObligation<'tcx>,
115 ) -> Result<(), ErrorGuaranteed>;
116
117 fn try_conversion_context(
118 &self,
119 obligation: &PredicateObligation<'tcx>,
120 trait_ref: ty::TraitRef<'tcx>,
121 err: &mut Diagnostic,
122 ) -> bool;
123
124 fn report_const_param_not_wf(
125 &self,
126 ty: Ty<'tcx>,
127 obligation: &PredicateObligation<'tcx>,
128 ) -> DiagnosticBuilder<'tcx>;
129}
130
131impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
60#[extension(pub trait TypeErrCtxtExt<'tcx>)]
61impl<'tcx> TypeErrCtxt<'_, 'tcx> {
13262 fn report_fulfillment_errors(
13363 &self,
13464 mut errors: Vec<FulfillmentError<'tcx>>,
......@@ -382,6 +312,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
382312 err.emit()
383313 }
384314
315 /// The `root_obligation` parameter should be the `root_obligation` field
316 /// from a `FulfillmentError`. If no `FulfillmentError` is available,
317 /// then it should be the same as `obligation`.
385318 fn report_selection_error(
386319 &self,
387320 mut obligation: PredicateObligation<'tcx>,
......@@ -1393,209 +1326,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
13931326 }
13941327}
13951328
1396pub(super) trait InferCtxtPrivExt<'tcx> {
1397 // returns if `cond` not occurring implies that `error` does not occur - i.e., that
1398 // `error` occurring implies that `cond` occurs.
1399 fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool;
1400
1401 fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed;
1402
1403 fn report_projection_error(
1404 &self,
1405 obligation: &PredicateObligation<'tcx>,
1406 error: &MismatchedProjectionTypes<'tcx>,
1407 ) -> ErrorGuaranteed;
1408
1409 fn maybe_detailed_projection_msg(
1410 &self,
1411 pred: ty::ProjectionPredicate<'tcx>,
1412 normalized_ty: ty::Term<'tcx>,
1413 expected_ty: ty::Term<'tcx>,
1414 ) -> Option<String>;
1415
1416 fn fuzzy_match_tys(
1417 &self,
1418 a: Ty<'tcx>,
1419 b: Ty<'tcx>,
1420 ignoring_lifetimes: bool,
1421 ) -> Option<CandidateSimilarity>;
1422
1423 fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str;
1424
1425 fn find_similar_impl_candidates(
1426 &self,
1427 trait_pred: ty::PolyTraitPredicate<'tcx>,
1428 ) -> Vec<ImplCandidate<'tcx>>;
1429
1430 fn report_similar_impl_candidates(
1431 &self,
1432 impl_candidates: &[ImplCandidate<'tcx>],
1433 trait_ref: ty::PolyTraitRef<'tcx>,
1434 body_def_id: LocalDefId,
1435 err: &mut Diagnostic,
1436 other: bool,
1437 param_env: ty::ParamEnv<'tcx>,
1438 ) -> bool;
1439
1440 fn report_similar_impl_candidates_for_root_obligation(
1441 &self,
1442 obligation: &PredicateObligation<'tcx>,
1443 trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
1444 body_def_id: LocalDefId,
1445 err: &mut Diagnostic,
1446 );
1447
1448 /// Gets the parent trait chain start
1449 fn get_parent_trait_ref(
1450 &self,
1451 code: &ObligationCauseCode<'tcx>,
1452 ) -> Option<(Ty<'tcx>, Option<Span>)>;
1453
1454 /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
1455 /// with the same path as `trait_ref`, a help message about
1456 /// a probable version mismatch is added to `err`
1457 fn note_version_mismatch(
1458 &self,
1459 err: &mut Diagnostic,
1460 trait_ref: &ty::PolyTraitRef<'tcx>,
1461 ) -> bool;
1462
1463 /// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
1464 /// `trait_ref`.
1465 ///
1466 /// For this to work, `new_self_ty` must have no escaping bound variables.
1467 fn mk_trait_obligation_with_new_self_ty(
1468 &self,
1469 param_env: ty::ParamEnv<'tcx>,
1470 trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
1471 ) -> PredicateObligation<'tcx>;
1472
1473 fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> ErrorGuaranteed;
1474
1475 fn predicate_can_apply(
1476 &self,
1477 param_env: ty::ParamEnv<'tcx>,
1478 pred: ty::PolyTraitPredicate<'tcx>,
1479 ) -> bool;
1480
1481 fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>);
1482
1483 fn suggest_unsized_bound_if_applicable(
1484 &self,
1485 err: &mut Diagnostic,
1486 obligation: &PredicateObligation<'tcx>,
1487 );
1488
1489 fn annotate_source_of_ambiguity(
1490 &self,
1491 err: &mut Diagnostic,
1492 impls: &[ambiguity::Ambiguity],
1493 predicate: ty::Predicate<'tcx>,
1494 );
1495
1496 fn maybe_suggest_unsized_generics(&self, err: &mut Diagnostic, span: Span, node: Node<'tcx>);
1497
1498 fn maybe_indirection_for_unsized(
1499 &self,
1500 err: &mut Diagnostic,
1501 item: &'tcx Item<'tcx>,
1502 param: &'tcx GenericParam<'tcx>,
1503 ) -> bool;
1504
1505 fn is_recursive_obligation(
1506 &self,
1507 obligated_types: &mut Vec<Ty<'tcx>>,
1508 cause_code: &ObligationCauseCode<'tcx>,
1509 ) -> bool;
1510
1511 fn get_standard_error_message(
1512 &self,
1513 trait_predicate: &ty::PolyTraitPredicate<'tcx>,
1514 message: Option<String>,
1515 predicate_is_const: bool,
1516 append_const_msg: Option<AppendConstMessage>,
1517 post_message: String,
1518 ) -> String;
1519
1520 fn get_safe_transmute_error_and_reason(
1521 &self,
1522 obligation: PredicateObligation<'tcx>,
1523 trait_ref: ty::PolyTraitRef<'tcx>,
1524 span: Span,
1525 ) -> GetSafeTransmuteErrorAndReason;
1526
1527 fn add_tuple_trait_message(
1528 &self,
1529 obligation_cause_code: &ObligationCauseCode<'tcx>,
1530 err: &mut Diagnostic,
1531 );
1532
1533 fn try_to_add_help_message(
1534 &self,
1535 obligation: &PredicateObligation<'tcx>,
1536 trait_ref: ty::PolyTraitRef<'tcx>,
1537 trait_predicate: &ty::PolyTraitPredicate<'tcx>,
1538 err: &mut Diagnostic,
1539 span: Span,
1540 is_fn_trait: bool,
1541 suggested: bool,
1542 unsatisfied_const: bool,
1543 );
1544
1545 fn add_help_message_for_fn_trait(
1546 &self,
1547 trait_ref: ty::PolyTraitRef<'tcx>,
1548 err: &mut Diagnostic,
1549 implemented_kind: ty::ClosureKind,
1550 params: ty::Binder<'tcx, Ty<'tcx>>,
1551 );
1552
1553 fn maybe_add_note_for_unsatisfied_const(
1554 &self,
1555 trait_predicate: &ty::PolyTraitPredicate<'tcx>,
1556 err: &mut Diagnostic,
1557 span: Span,
1558 ) -> UnsatisfiedConst;
1559
1560 fn report_closure_error(
1561 &self,
1562 obligation: &PredicateObligation<'tcx>,
1563 closure_def_id: DefId,
1564 found_kind: ty::ClosureKind,
1565 kind: ty::ClosureKind,
1566 trait_prefix: &'static str,
1567 ) -> DiagnosticBuilder<'tcx>;
1568
1569 fn report_cyclic_signature_error(
1570 &self,
1571 obligation: &PredicateObligation<'tcx>,
1572 found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
1573 expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
1574 terr: TypeError<'tcx>,
1575 ) -> DiagnosticBuilder<'tcx>;
1576
1577 fn report_opaque_type_auto_trait_leakage(
1578 &self,
1579 obligation: &PredicateObligation<'tcx>,
1580 def_id: DefId,
1581 ) -> DiagnosticBuilder<'tcx>;
1582
1583 fn report_signature_mismatch_error(
1584 &self,
1585 obligation: &PredicateObligation<'tcx>,
1586 span: Span,
1587 found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
1588 expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
1589 ) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed>;
1590
1591 fn report_not_const_evaluatable_error(
1592 &self,
1593 obligation: &PredicateObligation<'tcx>,
1594 span: Span,
1595 ) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed>;
1596}
1597
1598impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1329#[extension(pub(super) trait InferCtxtPrivExt<'tcx>)]
1330impl<'tcx> TypeErrCtxt<'_, 'tcx> {
15991331 // returns if `cond` not occurring implies that `error` does not occur - i.e., that
16001332 // `error` occurring implies that `cond` occurs.
16011333 fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool {
......@@ -2414,6 +2146,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
24142146 suggested
24152147 }
24162148
2149 /// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
2150 /// `trait_ref`.
2151 ///
2152 /// For this to work, `new_self_ty` must have no escaping bound variables.
24172153 fn mk_trait_obligation_with_new_self_ty(
24182154 &self,
24192155 param_env: ty::ParamEnv<'tcx>,
compiler/rustc_trait_selection/src/traits/outlives_bounds.rs+5-20
......@@ -11,25 +11,6 @@ pub use rustc_middle::traits::query::OutlivesBound;
1111
1212pub type BoundsCompat<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
1313pub type Bounds<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
14pub trait InferCtxtExt<'a, 'tcx> {
15 /// Do *NOT* call this directly.
16 fn implied_bounds_tys_compat(
17 &'a self,
18 param_env: ty::ParamEnv<'tcx>,
19 body_id: LocalDefId,
20 tys: &'a FxIndexSet<Ty<'tcx>>,
21 compat: bool,
22 ) -> BoundsCompat<'a, 'tcx>;
23
24 /// If `-Z no-implied-bounds-compat` is set, calls `implied_bounds_tys_compat`
25 /// with `compat` set to `true`, otherwise `false`.
26 fn implied_bounds_tys(
27 &'a self,
28 param_env: ty::ParamEnv<'tcx>,
29 body_id: LocalDefId,
30 tys: &'a FxIndexSet<Ty<'tcx>>,
31 ) -> Bounds<'a, 'tcx>;
32}
3314
3415/// Implied bounds are region relationships that we deduce
3516/// automatically. The idea is that (e.g.) a caller must check that a
......@@ -130,7 +111,9 @@ fn implied_outlives_bounds<'a, 'tcx>(
130111 bounds
131112}
132113
133impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
114#[extension(pub trait InferCtxtExt<'a, 'tcx>)]
115impl<'a, 'tcx: 'a> InferCtxt<'tcx> {
116 /// Do *NOT* call this directly.
134117 fn implied_bounds_tys_compat(
135118 &'a self,
136119 param_env: ParamEnv<'tcx>,
......@@ -142,6 +125,8 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
142125 .flat_map(move |ty| implied_outlives_bounds(self, param_env, body_id, *ty, compat))
143126 }
144127
128 /// If `-Z no-implied-bounds-compat` is set, calls `implied_bounds_tys_compat`
129 /// with `compat` set to `true`, otherwise `false`.
145130 fn implied_bounds_tys(
146131 &'a self,
147132 param_env: ParamEnv<'tcx>,
compiler/rustc_trait_selection/src/traits/project.rs+12-21
......@@ -52,12 +52,22 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>;
5252
5353pub(super) struct InProgress;
5454
55pub trait NormalizeExt<'tcx> {
55#[extension(pub trait NormalizeExt<'tcx>)]
56impl<'tcx> At<'_, 'tcx> {
5657 /// Normalize a value using the `AssocTypeNormalizer`.
5758 ///
5859 /// This normalization should be used when the type contains inference variables or the
5960 /// projection may be fallible.
60 fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>;
61 fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> {
62 if self.infcx.next_trait_solver() {
63 InferOk { value, obligations: Vec::new() }
64 } else {
65 let mut selcx = SelectionContext::new(self.infcx);
66 let Normalized { value, obligations } =
67 normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
68 InferOk { value, obligations }
69 }
70 }
6171
6272 /// Deeply normalizes `value`, replacing all aliases which can by normalized in
6373 /// the current environment. In the new solver this errors in case normalization
......@@ -73,25 +83,6 @@ pub trait NormalizeExt<'tcx> {
7383 /// existing fulfillment context in the old solver. Once we also eagerly prove goals with
7484 /// the old solver or have removed the old solver, remove `traits::fully_normalize` and
7585 /// rename this function to `At::fully_normalize`.
76 fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
77 self,
78 value: T,
79 fulfill_cx: &mut dyn TraitEngine<'tcx>,
80 ) -> Result<T, Vec<FulfillmentError<'tcx>>>;
81}
82
83impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
84 fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> {
85 if self.infcx.next_trait_solver() {
86 InferOk { value, obligations: Vec::new() }
87 } else {
88 let mut selcx = SelectionContext::new(self.infcx);
89 let Normalized { value, obligations } =
90 normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
91 InferOk { value, obligations }
92 }
93 }
94
9586 fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
9687 self,
9788 value: T,
compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs+5-29
......@@ -4,32 +4,8 @@ use crate::infer::canonical::OriginalQueryValues;
44use crate::infer::InferCtxt;
55use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext};
66
7pub trait InferCtxtExt<'tcx> {
8 fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool;
9
10 fn predicate_must_hold_considering_regions(
11 &self,
12 obligation: &PredicateObligation<'tcx>,
13 ) -> bool;
14
15 fn predicate_must_hold_modulo_regions(&self, obligation: &PredicateObligation<'tcx>) -> bool;
16
17 fn evaluate_obligation(
18 &self,
19 obligation: &PredicateObligation<'tcx>,
20 ) -> Result<EvaluationResult, OverflowError>;
21
22 // Helper function that canonicalizes and runs the query. If an
23 // overflow results, we re-run it in the local context so we can
24 // report a nice error.
25 /*crate*/
26 fn evaluate_obligation_no_overflow(
27 &self,
28 obligation: &PredicateObligation<'tcx>,
29 ) -> EvaluationResult;
30}
31
32impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
7#[extension(pub trait InferCtxtExt<'tcx>)]
8impl<'tcx> InferCtxt<'tcx> {
339 /// Evaluates whether the predicate can be satisfied (by any means)
3410 /// in the given `ParamEnv`.
3511 fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool {
......@@ -114,9 +90,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
11490 }
11591 }
11692
117 // Helper function that canonicalizes and runs the query. If an
118 // overflow results, we re-run it in the local context so we can
119 // report a nice error.
93 /// Helper function that canonicalizes and runs the query. If an
94 /// overflow results, we re-run it in the local context so we can
95 /// report a nice error.
12096 fn evaluate_obligation_no_overflow(
12197 &self,
12298 obligation: &PredicateObligation<'tcx>,
compiler/rustc_trait_selection/src/traits/query/normalize.rs+8-14
......@@ -22,20 +22,8 @@ use super::NoSolution;
2222
2323pub use rustc_middle::traits::query::NormalizationResult;
2424
25pub trait QueryNormalizeExt<'tcx> {
26 /// Normalize a value using the `QueryNormalizer`.
27 ///
28 /// This normalization should *only* be used when the projection does not
29 /// have possible ambiguity or may not be well-formed.
30 ///
31 /// After codegen, when lifetimes do not matter, it is preferable to instead
32 /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
33 fn query_normalize<T>(self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
34 where
35 T: TypeFoldable<TyCtxt<'tcx>>;
36}
37
38impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
25#[extension(pub trait QueryNormalizeExt<'tcx>)]
26impl<'cx, 'tcx> At<'cx, 'tcx> {
3927 /// Normalize `value` in the context of the inference context,
4028 /// yielding a resulting type, or an error if `value` cannot be
4129 /// normalized. If you don't care about regions, you should prefer
......@@ -49,6 +37,12 @@ impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
4937 /// normalizing, but for now should be used only when we actually
5038 /// know that normalization will succeed, since error reporting
5139 /// and other details are still "under development".
40 ///
41 /// This normalization should *only* be used when the projection does not
42 /// have possible ambiguity or may not be well-formed.
43 ///
44 /// After codegen, when lifetimes do not matter, it is preferable to instead
45 /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
5246 fn query_normalize<T>(self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
5347 where
5448 T: TypeFoldable<TyCtxt<'tcx>>,
compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs+4-30
......@@ -33,20 +33,8 @@ enum Inserted<'tcx> {
3333 ShouldRecurseOn(DefId),
3434}
3535
36trait ChildrenExt<'tcx> {
37 fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId);
38 fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId);
39
40 fn insert(
41 &mut self,
42 tcx: TyCtxt<'tcx>,
43 impl_def_id: DefId,
44 simplified_self: Option<SimplifiedType>,
45 overlap_mode: OverlapMode,
46 ) -> Result<Inserted<'tcx>, OverlapError<'tcx>>;
47}
48
49impl<'tcx> ChildrenExt<'tcx> for Children {
36#[extension(trait ChildrenExt<'tcx>)]
37impl<'tcx> Children {
5038 /// Insert an impl into this set of children without comparing to any existing impls.
5139 fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
5240 let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
......@@ -247,22 +235,8 @@ where
247235 }
248236}
249237
250pub trait GraphExt<'tcx> {
251 /// Insert a local impl into the specialization graph. If an existing impl
252 /// conflicts with it (has overlap, but neither specializes the other),
253 /// information about the area of overlap is returned in the `Err`.
254 fn insert(
255 &mut self,
256 tcx: TyCtxt<'tcx>,
257 impl_def_id: DefId,
258 overlap_mode: OverlapMode,
259 ) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>>;
260
261 /// Insert cached metadata mapping from a child impl back to its parent.
262 fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId);
263}
264
265impl<'tcx> GraphExt<'tcx> for Graph {
238#[extension(pub trait GraphExt<'tcx>)]
239impl<'tcx> Graph {
266240 /// Insert a local impl into the specialization graph. If an existing impl
267241 /// conflicts with it (has overlap, but neither specializes the other),
268242 /// information about the area of overlap is returned in the `Err`.
compiler/rustc_trait_selection/src/traits/structural_normalize.rs+2-9
......@@ -5,15 +5,8 @@ use rustc_middle::ty::{self, Ty};
55
66use crate::traits::{NormalizeExt, Obligation};
77
8pub trait StructurallyNormalizeExt<'tcx> {
9 fn structurally_normalize(
10 &self,
11 ty: Ty<'tcx>,
12 fulfill_cx: &mut dyn TraitEngine<'tcx>,
13 ) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>>;
14}
15
16impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
8#[extension(pub trait StructurallyNormalizeExt<'tcx>)]
9impl<'tcx> At<'_, 'tcx> {
1710 fn structurally_normalize(
1811 &self,
1912 ty: Ty<'tcx>,
configure+2-2
......@@ -1,6 +1,6 @@
11#!/bin/sh
22
3script="$(dirname $0)"/src/bootstrap/configure.py
3script="$(dirname "$0")"/src/bootstrap/configure.py
44
55try() {
66 cmd=$1
......@@ -15,4 +15,4 @@ try python3 "$@"
1515try python2.7 "$@"
1616try python27 "$@"
1717try python2 "$@"
18exec python $script "$@"
18exec python "$script" "$@"
library/core/src/intrinsics.rs+59-43
......@@ -937,52 +937,68 @@ extern "rust-intrinsic" {
937937 #[rustc_nounwind]
938938 pub fn unreachable() -> !;
939939
940 /// Informs the optimizer that a condition is always true.
941 /// If the condition is false, the behavior is undefined.
942 ///
943 /// No code is generated for this intrinsic, but the optimizer will try
944 /// to preserve it (and its condition) between passes, which may interfere
945 /// with optimization of surrounding code and reduce performance. It should
946 /// not be used if the invariant can be discovered by the optimizer on its
947 /// own, or if it does not enable any significant optimizations.
948 ///
949 /// This intrinsic does not have a stable counterpart.
950 #[rustc_const_stable(feature = "const_assume", since = "1.77.0")]
951 #[rustc_nounwind]
952 pub fn assume(b: bool);
940}
953941
954 /// Hints to the compiler that branch condition is likely to be true.
955 /// Returns the value passed to it.
956 ///
957 /// Any use other than with `if` statements will probably not have an effect.
958 ///
959 /// Note that, unlike most intrinsics, this is safe to call;
960 /// it does not require an `unsafe` block.
961 /// Therefore, implementations must not require the user to uphold
962 /// any safety invariants.
963 ///
964 /// This intrinsic does not have a stable counterpart.
965 #[rustc_const_unstable(feature = "const_likely", issue = "none")]
966 #[rustc_safe_intrinsic]
967 #[rustc_nounwind]
968 pub fn likely(b: bool) -> bool;
942/// Informs the optimizer that a condition is always true.
943/// If the condition is false, the behavior is undefined.
944///
945/// No code is generated for this intrinsic, but the optimizer will try
946/// to preserve it (and its condition) between passes, which may interfere
947/// with optimization of surrounding code and reduce performance. It should
948/// not be used if the invariant can be discovered by the optimizer on its
949/// own, or if it does not enable any significant optimizations.
950///
951/// This intrinsic does not have a stable counterpart.
952#[rustc_const_stable(feature = "const_assume", since = "1.77.0")]
953#[rustc_nounwind]
954#[unstable(feature = "core_intrinsics", issue = "none")]
955#[cfg_attr(not(bootstrap), rustc_intrinsic)]
956pub const unsafe fn assume(b: bool) {
957 if !b {
958 // SAFETY: the caller must guarantee the argument is never `false`
959 unsafe { unreachable() }
960 }
961}
969962
970 /// Hints to the compiler that branch condition is likely to be false.
971 /// Returns the value passed to it.
972 ///
973 /// Any use other than with `if` statements will probably not have an effect.
974 ///
975 /// Note that, unlike most intrinsics, this is safe to call;
976 /// it does not require an `unsafe` block.
977 /// Therefore, implementations must not require the user to uphold
978 /// any safety invariants.
979 ///
980 /// This intrinsic does not have a stable counterpart.
981 #[rustc_const_unstable(feature = "const_likely", issue = "none")]
982 #[rustc_safe_intrinsic]
983 #[rustc_nounwind]
984 pub fn unlikely(b: bool) -> bool;
963/// Hints to the compiler that branch condition is likely to be true.
964/// Returns the value passed to it.
965///
966/// Any use other than with `if` statements will probably not have an effect.
967///
968/// Note that, unlike most intrinsics, this is safe to call;
969/// it does not require an `unsafe` block.
970/// Therefore, implementations must not require the user to uphold
971/// any safety invariants.
972///
973/// This intrinsic does not have a stable counterpart.
974#[rustc_const_unstable(feature = "const_likely", issue = "none")]
975#[unstable(feature = "core_intrinsics", issue = "none")]
976#[cfg_attr(not(bootstrap), rustc_intrinsic)]
977#[rustc_nounwind]
978pub const fn likely(b: bool) -> bool {
979 b
980}
981
982/// Hints to the compiler that branch condition is likely to be false.
983/// Returns the value passed to it.
984///
985/// Any use other than with `if` statements will probably not have an effect.
986///
987/// Note that, unlike most intrinsics, this is safe to call;
988/// it does not require an `unsafe` block.
989/// Therefore, implementations must not require the user to uphold
990/// any safety invariants.
991///
992/// This intrinsic does not have a stable counterpart.
993#[rustc_const_unstable(feature = "const_likely", issue = "none")]
994#[unstable(feature = "core_intrinsics", issue = "none")]
995#[cfg_attr(not(bootstrap), rustc_intrinsic)]
996#[rustc_nounwind]
997pub const fn unlikely(b: bool) -> bool {
998 b
999}
9851000
1001extern "rust-intrinsic" {
9861002 /// Executes a breakpoint trap, for inspection by a debugger.
9871003 ///
9881004 /// This intrinsic does not have a stable counterpart.
library/core/src/slice/mod.rs+21-6
......@@ -3016,8 +3016,13 @@ impl<T> [T] {
30163016 /// ```
30173017 /// let mut v = [-5i32, 4, 2, -3, 1];
30183018 ///
3019 /// // Find the median
3020 /// v.select_nth_unstable(2);
3019 /// // Find the items less than or equal to the median, the median, and greater than or equal to
3020 /// // the median.
3021 /// let (lesser, median, greater) = v.select_nth_unstable(2);
3022 ///
3023 /// assert!(lesser == [-3, -5] || lesser == [-5, -3]);
3024 /// assert_eq!(median, &mut 1);
3025 /// assert!(greater == [4, 2] || greater == [2, 4]);
30213026 ///
30223027 /// // We are only guaranteed the slice will be one of the following, based on the way we sort
30233028 /// // about the specified index.
......@@ -3067,8 +3072,13 @@ impl<T> [T] {
30673072 /// ```
30683073 /// let mut v = [-5i32, 4, 2, -3, 1];
30693074 ///
3070 /// // Find the median as if the slice were sorted in descending order.
3071 /// v.select_nth_unstable_by(2, |a, b| b.cmp(a));
3075 /// // Find the items less than or equal to the median, the median, and greater than or equal to
3076 /// // the median as if the slice were sorted in descending order.
3077 /// let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
3078 ///
3079 /// assert!(lesser == [4, 2] || lesser == [2, 4]);
3080 /// assert_eq!(median, &mut 1);
3081 /// assert!(greater == [-3, -5] || greater == [-5, -3]);
30723082 ///
30733083 /// // We are only guaranteed the slice will be one of the following, based on the way we sort
30743084 /// // about the specified index.
......@@ -3122,8 +3132,13 @@ impl<T> [T] {
31223132 /// ```
31233133 /// let mut v = [-5i32, 4, 1, -3, 2];
31243134 ///
3125 /// // Return the median as if the array were sorted according to absolute value.
3126 /// v.select_nth_unstable_by_key(2, |a| a.abs());
3135 /// // Find the items less than or equal to the median, the median, and greater than or equal to
3136 /// // the median as if the slice were sorted according to absolute value.
3137 /// let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
3138 ///
3139 /// assert!(lesser == [1, 2] || lesser == [2, 1]);
3140 /// assert_eq!(median, &mut -3);
3141 /// assert!(greater == [4, -5] || greater == [-5, 4]);
31273142 ///
31283143 /// // We are only guaranteed the slice will be one of the following, based on the way we sort
31293144 /// // about the specified index.
library/std/src/sys/pal/windows/os.rs+25-5
......@@ -318,13 +318,33 @@ pub fn temp_dir() -> PathBuf {
318318 super::fill_utf16_buf(|buf, sz| unsafe { c::GetTempPath2W(sz, buf) }, super::os2path).unwrap()
319319}
320320
321#[cfg(not(target_vendor = "uwp"))]
321#[cfg(all(not(target_vendor = "uwp"), not(target_vendor = "win7")))]
322fn home_dir_crt() -> Option<PathBuf> {
323 unsafe {
324 // Defined in processthreadsapi.h.
325 const CURRENT_PROCESS_TOKEN: usize = -4_isize as usize;
326
327 super::fill_utf16_buf(
328 |buf, mut sz| {
329 match c::GetUserProfileDirectoryW(
330 ptr::invalid_mut(CURRENT_PROCESS_TOKEN),
331 buf,
332 &mut sz,
333 ) {
334 0 if api::get_last_error().code != c::ERROR_INSUFFICIENT_BUFFER => 0,
335 0 => sz,
336 _ => sz - 1, // sz includes the null terminator
337 }
338 },
339 super::os2path,
340 )
341 .ok()
342 }
343}
344
345#[cfg(target_vendor = "win7")]
322346fn home_dir_crt() -> Option<PathBuf> {
323347 unsafe {
324 // The magic constant -4 can be used as the token passed to GetUserProfileDirectoryW below
325 // instead of us having to go through these multiple steps to get a token. However this is
326 // not implemented on Windows 7, only Windows 8 and up. When we drop support for Windows 7
327 // we can simplify this code. See #90144 for details.
328348 use crate::sys::handle::Handle;
329349
330350 let me = c::GetCurrentProcess();
tests/coverage/closure_unit_return.cov-map created+34
......@@ -0,0 +1,34 @@
1Function name: closure_unit_return::explicit_unit
2Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 01, 01, 10, 01, 05, 05, 02, 02]
3Number of files: 1
4- file 0 => global file 1
5Number of expressions: 0
6Number of file 0 mappings: 2
7- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 16)
8- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2)
9
10Function name: closure_unit_return::explicit_unit::{closure#0} (unused)
11Raw bytes (9): 0x[01, 01, 00, 01, 00, 08, 16, 02, 06]
12Number of files: 1
13- file 0 => global file 1
14Number of expressions: 0
15Number of file 0 mappings: 1
16- Code(Zero) at (prev + 8, 22) to (start + 2, 6)
17
18Function name: closure_unit_return::implicit_unit
19Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 01, 10, 01, 05, 05, 02, 02]
20Number of files: 1
21- file 0 => global file 1
22Number of expressions: 0
23Number of file 0 mappings: 2
24- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 16)
25- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2)
26
27Function name: closure_unit_return::implicit_unit::{closure#0} (unused)
28Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 16, 02, 06]
29Number of files: 1
30- file 0 => global file 1
31Number of expressions: 0
32Number of file 0 mappings: 1
33- Code(Zero) at (prev + 17, 22) to (start + 2, 6)
34
tests/coverage/closure_unit_return.coverage created+30
......@@ -0,0 +1,30 @@
1 LL| |#![feature(coverage_attribute)]
2 LL| |// edition: 2021
3 LL| |
4 LL| |// Regression test for an inconsistency between functions that return the value
5 LL| |// of their trailing expression, and functions that implicitly return `()`.
6 LL| |
7 LL| 1|fn explicit_unit() {
8 LL| 1| let closure = || {
9 LL| 0| ();
10 LL| 0| };
11 LL| |
12 LL| 1| drop(closure);
13 LL| 1| () // explicit return of trailing value
14 LL| 1|}
15 LL| |
16 LL| 1|fn implicit_unit() {
17 LL| 1| let closure = || {
18 LL| 0| ();
19 LL| 0| };
20 LL| |
21 LL| 1| drop(closure);
22 LL| 1| // implicit return of `()`
23 LL| 1|}
24 LL| |
25 LL| |#[coverage(off)]
26 LL| |fn main() {
27 LL| | explicit_unit();
28 LL| | implicit_unit();
29 LL| |}
30
tests/coverage/closure_unit_return.rs created+29
......@@ -0,0 +1,29 @@
1#![feature(coverage_attribute)]
2// edition: 2021
3
4// Regression test for an inconsistency between functions that return the value
5// of their trailing expression, and functions that implicitly return `()`.
6
7fn explicit_unit() {
8 let closure = || {
9 ();
10 };
11
12 drop(closure);
13 () // explicit return of trailing value
14}
15
16fn implicit_unit() {
17 let closure = || {
18 ();
19 };
20
21 drop(closure);
22 // implicit return of `()`
23}
24
25#[coverage(off)]
26fn main() {
27 explicit_unit();
28 implicit_unit();
29}
tests/coverage/coverage_attr_closure.cov-map+4-4
......@@ -15,14 +15,14 @@ Number of file 0 mappings: 1
1515- Code(Zero) at (prev + 29, 19) to (start + 2, 6)
1616
1717Function name: coverage_attr_closure::contains_closures_on
18Raw bytes (19): 0x[01, 01, 00, 03, 01, 0f, 01, 02, 05, 01, 04, 06, 02, 05, 01, 04, 06, 01, 02]
18Raw bytes (19): 0x[01, 01, 00, 03, 01, 0f, 01, 01, 1a, 01, 05, 09, 00, 1b, 01, 04, 01, 00, 02]
1919Number of files: 1
2020- file 0 => global file 1
2121Number of expressions: 0
2222Number of file 0 mappings: 3
23- Code(Counter(0)) at (prev + 15, 1) to (start + 2, 5)
24- Code(Counter(0)) at (prev + 4, 6) to (start + 2, 5)
25- Code(Counter(0)) at (prev + 4, 6) to (start + 1, 2)
23- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 26)
24- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 27)
25- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
2626
2727Function name: coverage_attr_closure::contains_closures_on::{closure#0} (unused)
2828Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 13, 02, 06]
tests/coverage/coverage_attr_closure.coverage+4-4
......@@ -14,13 +14,13 @@
1414 LL| |#[coverage(on)]
1515 LL| 1|fn contains_closures_on() {
1616 LL| 1| let _local_closure_on = #[coverage(on)]
17 LL| 1| |input: &str| {
17 LL| 0| |input: &str| {
1818 LL| 0| println!("{input}");
19 LL| 1| };
19 LL| 0| };
2020 LL| 1| let _local_closure_off = #[coverage(off)]
21 LL| 1| |input: &str| {
21 LL| | |input: &str| {
2222 LL| | println!("{input}");
23 LL| 1| };
23 LL| | };
2424 LL| 1|}
2525 LL| |
2626 LL| |#[coverage(off)]
tests/coverage/inline-dead.cov-map+3-3
......@@ -22,13 +22,13 @@ Number of file 0 mappings: 4
2222 = (Zero + (c0 - Zero))
2323
2424Function name: inline_dead::main
25Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0d, 01, 05, 06, 02, 02]
25Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0a, 01, 06, 05, 01, 02]
2626Number of files: 1
2727- file 0 => global file 1
2828Number of expressions: 0
2929Number of file 0 mappings: 2
30- Code(Counter(0)) at (prev + 4, 1) to (start + 3, 13)
31- Code(Counter(0)) at (prev + 5, 6) to (start + 2, 2)
30- Code(Counter(0)) at (prev + 4, 1) to (start + 3, 10)
31- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 2)
3232
3333Function name: inline_dead::main::{closure#0}
3434Raw bytes (23): 0x[01, 01, 02, 00, 06, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 03, 01, 05, 00, 06]
tests/coverage/macro_name_span.cov-map+2-2
......@@ -1,10 +1,10 @@
11Function name: macro_name_span::affected_function
2Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 02, 06]
2Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 01, 40]
33Number of files: 1
44- file 0 => global file 1
55Number of expressions: 0
66Number of file 0 mappings: 1
7- Code(Counter(0)) at (prev + 22, 28) to (start + 2, 6)
7- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 64)
88
99Function name: macro_name_span::main
1010Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
tests/coverage/macro_name_span.coverage+1-1
......@@ -21,6 +21,6 @@
2121 LL| |macro_name_span_helper::macro_that_defines_a_function! {
2222 LL| 1| fn affected_function() {
2323 LL| 1| macro_with_an_unreasonably_and_egregiously_long_name!();
24 LL| 1| }
24 LL| | }
2525 LL| |}
2626
tests/coverage/unicode.cov-map-8
......@@ -27,14 +27,6 @@ Number of file 0 mappings: 9
2727- Code(Expression(5, Add)) at (prev + 2, 5) to (start + 1, 2)
2828 = (c4 + ((((c0 + c1) - c1) - c2) + c3))
2929
30Function name: unicode::サビ
31Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 14, 00, 18]
32Number of files: 1
33- file 0 => global file 1
34Number of expressions: 0
35Number of file 0 mappings: 1
36- Code(Counter(0)) at (prev + 30, 20) to (start + 0, 24)
37
3830Function name: unicode::他 (unused)
3931Raw bytes (9): 0x[01, 01, 00, 01, 00, 1e, 19, 00, 25]
4032Number of files: 1
tests/coverage/unicode.coverage+1-2
......@@ -29,8 +29,7 @@
2929 LL| |
3030 LL| |macro_rules! macro_that_defines_a_function {
3131 LL| | (fn $名:ident () $体:tt) => {
32 LL| 1| fn $名 () $体 fn 他 () {}
33 ^0
32 LL| 0| fn $名 () $体 fn 他 () {}
3433 LL| | }
3534 LL| |}
3635 LL| |
tests/ui/consts/const-ref-to-static-linux-vtable.rs created+43
......@@ -0,0 +1,43 @@
1//@check-pass
2//! This is the reduced version of the "Linux kernel vtable" use-case.
3#![feature(const_mut_refs, const_refs_to_static)]
4use std::ptr::addr_of_mut;
5
6#[repr(C)]
7struct ThisModule(i32);
8
9trait Module {
10 const THIS_MODULE_PTR: *mut ThisModule;
11}
12
13struct MyModule;
14
15// Generated by a macro.
16extern "C" {
17 static mut THIS_MODULE: ThisModule;
18}
19
20// Generated by a macro.
21impl Module for MyModule {
22 const THIS_MODULE_PTR: *mut ThisModule = unsafe { addr_of_mut!(THIS_MODULE) };
23}
24
25struct Vtable {
26 module: *mut ThisModule,
27 foo_fn: fn(*mut ()) -> i32,
28}
29
30trait Foo {
31 type Mod: Module;
32
33 fn foo(&mut self) -> i32;
34}
35
36fn generate_vtable<T: Foo>() -> &'static Vtable {
37 &Vtable {
38 module: T::Mod::THIS_MODULE_PTR,
39 foo_fn: |ptr| unsafe { &mut *ptr.cast::<T>() }.foo(),
40 }
41}
42
43fn main() {}
tests/ui/consts/issue-17718-const-bad-values.rs+1
......@@ -6,5 +6,6 @@ const C1: &'static mut [usize] = &mut [];
66static mut S: usize = 3;
77const C2: &'static mut usize = unsafe { &mut S };
88//~^ ERROR: referencing statics in constants
9//~| ERROR: mutable references are not allowed
910
1011fn main() {}
tests/ui/consts/issue-17718-const-bad-values.stderr+11-1
......@@ -16,7 +16,17 @@ LL | const C2: &'static mut usize = unsafe { &mut S };
1616 = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
1717 = help: to fix this, the value can be extracted to a `const` and then used.
1818
19error: aborting due to 2 previous errors
19error[E0658]: mutable references are not allowed in constants
20 --> $DIR/issue-17718-const-bad-values.rs:7:41
21 |
22LL | const C2: &'static mut usize = unsafe { &mut S };
23 | ^^^^^^
24 |
25 = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
26 = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
27 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
28
29error: aborting due to 3 previous errors
2030
2131Some errors have detailed explanations: E0658, E0764.
2232For more information about an error, try `rustc --explain E0658`.
tests/ui/consts/miri_unleashed/box.stderr+1-1
......@@ -16,7 +16,7 @@ help: skipping check for `const_mut_refs` feature
1616 |
1717LL | &mut *(Box::new(0))
1818 | ^^^^^^^^^^^^^^^^^^^
19help: skipping check that does not even have a feature gate
19help: skipping check for `const_mut_refs` feature
2020 --> $DIR/box.rs:8:5
2121 |
2222LL | &mut *(Box::new(0))
tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr+1-1
......@@ -114,7 +114,7 @@ help: skipping check for `const_refs_to_static` feature
114114 |
115115LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
116116 | ^^^
117help: skipping check that does not even have a feature gate
117help: skipping check for `const_mut_refs` feature
118118 --> $DIR/mutable_references_err.rs:32:35
119119 |
120120LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr+1-1
......@@ -114,7 +114,7 @@ help: skipping check for `const_refs_to_static` feature
114114 |
115115LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
116116 | ^^^
117help: skipping check that does not even have a feature gate
117help: skipping check for `const_mut_refs` feature
118118 --> $DIR/mutable_references_err.rs:32:35
119119 |
120120LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
tests/ui/consts/mut-ptr-to-static.rs created+40
......@@ -0,0 +1,40 @@
1//@run-pass
2#![feature(const_mut_refs)]
3#![feature(sync_unsafe_cell)]
4
5use std::cell::SyncUnsafeCell;
6use std::ptr;
7
8#[repr(C)]
9struct SyncPtr {
10 foo: *mut u32,
11}
12unsafe impl Sync for SyncPtr {}
13
14static mut STATIC: u32 = 42;
15
16static INTERIOR_MUTABLE_STATIC: SyncUnsafeCell<u32> = SyncUnsafeCell::new(42);
17
18// A static that mutably points to STATIC.
19static PTR: SyncPtr = SyncPtr {
20 foo: unsafe { ptr::addr_of_mut!(STATIC) },
21};
22static INTERIOR_MUTABLE_PTR: SyncPtr = SyncPtr {
23 foo: ptr::addr_of!(INTERIOR_MUTABLE_STATIC) as *mut u32,
24};
25
26fn main() {
27 let ptr = PTR.foo;
28 unsafe {
29 assert_eq!(*ptr, 42);
30 *ptr = 0;
31 assert_eq!(*PTR.foo, 0);
32 }
33
34 let ptr = INTERIOR_MUTABLE_PTR.foo;
35 unsafe {
36 assert_eq!(*ptr, 42);
37 *ptr = 0;
38 assert_eq!(*INTERIOR_MUTABLE_PTR.foo, 0);
39 }
40}
tests/ui/error-codes/E0017.rs+4-4
......@@ -1,3 +1,5 @@
1#![feature(const_mut_refs)]
2
13static X: i32 = 1;
24const C: i32 = 2;
35static mut M: i32 = 3;
......@@ -5,14 +7,12 @@ static mut M: i32 = 3;
57const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
68//~| WARN taking a mutable
79
8static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0658
9//~| ERROR cannot borrow
10//~| ERROR mutable references are not allowed
10static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow immutable static item `X` as mutable
1111
1212static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
1313//~| WARN taking a mutable
1414
15static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR mutable references are not
15static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
1616//~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
1717
1818fn main() {}
tests/ui/error-codes/E0017.stderr+7-29
......@@ -14,7 +14,7 @@ LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { addr_of_mut!(M) };
1414 | ~~~~~~~~~~~~~~~
1515
1616warning: taking a mutable reference to a `const` item
17 --> $DIR/E0017.rs:5:30
17 --> $DIR/E0017.rs:7:30
1818 |
1919LL | const CR: &'static mut i32 = &mut C;
2020 | ^^^^^^
......@@ -22,36 +22,20 @@ LL | const CR: &'static mut i32 = &mut C;
2222 = note: each usage of a `const` item creates a new temporary
2323 = note: the mutable reference will refer to this temporary, not the original `const` item
2424note: `const` item defined here
25 --> $DIR/E0017.rs:2:1
25 --> $DIR/E0017.rs:4:1
2626 |
2727LL | const C: i32 = 2;
2828 | ^^^^^^^^^^^^
2929 = note: `#[warn(const_item_mutation)]` on by default
3030
3131error[E0764]: mutable references are not allowed in the final value of constants
32 --> $DIR/E0017.rs:5:30
32 --> $DIR/E0017.rs:7:30
3333 |
3434LL | const CR: &'static mut i32 = &mut C;
3535 | ^^^^^^
3636
37error[E0658]: mutation through a reference is not allowed in statics
38 --> $DIR/E0017.rs:8:39
39 |
40LL | static STATIC_REF: &'static mut i32 = &mut X;
41 | ^^^^^^
42 |
43 = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
44 = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
45 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
46
47error[E0764]: mutable references are not allowed in the final value of statics
48 --> $DIR/E0017.rs:8:39
49 |
50LL | static STATIC_REF: &'static mut i32 = &mut X;
51 | ^^^^^^
52
5337error[E0596]: cannot borrow immutable static item `X` as mutable
54 --> $DIR/E0017.rs:8:39
38 --> $DIR/E0017.rs:10:39
5539 |
5640LL | static STATIC_REF: &'static mut i32 = &mut X;
5741 | ^^^^^^ cannot borrow as mutable
......@@ -65,7 +49,7 @@ LL | static CONST_REF: &'static mut i32 = &mut C;
6549 = note: each usage of a `const` item creates a new temporary
6650 = note: the mutable reference will refer to this temporary, not the original `const` item
6751note: `const` item defined here
68 --> $DIR/E0017.rs:2:1
52 --> $DIR/E0017.rs:4:1
6953 |
7054LL | const C: i32 = 2;
7155 | ^^^^^^^^^^^^
......@@ -76,13 +60,7 @@ error[E0764]: mutable references are not allowed in the final value of statics
7660LL | static CONST_REF: &'static mut i32 = &mut C;
7761 | ^^^^^^
7862
79error[E0764]: mutable references are not allowed in the final value of statics
80 --> $DIR/E0017.rs:15:52
81 |
82LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
83 | ^^^^^^
84
85error: aborting due to 6 previous errors; 3 warnings emitted
63error: aborting due to 3 previous errors; 3 warnings emitted
8664
87Some errors have detailed explanations: E0596, E0658, E0764.
65Some errors have detailed explanations: E0596, E0764.
8866For more information about an error, try `rustc --explain E0596`.
tests/ui/error-codes/E0388.rs+1-3
......@@ -3,9 +3,7 @@ const C: i32 = 2;
33
44const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
55 //~| WARN taking a mutable
6static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow
7 //~| ERROR E0658
8 //~| ERROR mutable references are not allowed
6static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0658
97
108static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
119 //~| WARN taking a mutable
tests/ui/error-codes/E0388.stderr+6-18
......@@ -19,7 +19,7 @@ error[E0764]: mutable references are not allowed in the final value of constants
1919LL | const CR: &'static mut i32 = &mut C;
2020 | ^^^^^^
2121
22error[E0658]: mutation through a reference is not allowed in statics
22error[E0658]: mutable references are not allowed in statics
2323 --> $DIR/E0388.rs:6:39
2424 |
2525LL | static STATIC_REF: &'static mut i32 = &mut X;
......@@ -29,20 +29,8 @@ LL | static STATIC_REF: &'static mut i32 = &mut X;
2929 = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
3030 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3131
32error[E0764]: mutable references are not allowed in the final value of statics
33 --> $DIR/E0388.rs:6:39
34 |
35LL | static STATIC_REF: &'static mut i32 = &mut X;
36 | ^^^^^^
37
38error[E0596]: cannot borrow immutable static item `X` as mutable
39 --> $DIR/E0388.rs:6:39
40 |
41LL | static STATIC_REF: &'static mut i32 = &mut X;
42 | ^^^^^^ cannot borrow as mutable
43
4432warning: taking a mutable reference to a `const` item
45 --> $DIR/E0388.rs:10:38
33 --> $DIR/E0388.rs:8:38
4634 |
4735LL | static CONST_REF: &'static mut i32 = &mut C;
4836 | ^^^^^^
......@@ -56,12 +44,12 @@ LL | const C: i32 = 2;
5644 | ^^^^^^^^^^^^
5745
5846error[E0764]: mutable references are not allowed in the final value of statics
59 --> $DIR/E0388.rs:10:38
47 --> $DIR/E0388.rs:8:38
6048 |
6149LL | static CONST_REF: &'static mut i32 = &mut C;
6250 | ^^^^^^
6351
64error: aborting due to 5 previous errors; 2 warnings emitted
52error: aborting due to 3 previous errors; 2 warnings emitted
6553
66Some errors have detailed explanations: E0596, E0658, E0764.
67For more information about an error, try `rustc --explain E0596`.
54Some errors have detailed explanations: E0658, E0764.
55For more information about an error, try `rustc --explain E0658`.
tests/ui/intrinsics/safe-intrinsic-mismatch.rs+4-4
......@@ -5,12 +5,12 @@
55extern "rust-intrinsic" {
66 fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch
77 //~^ ERROR intrinsic safety mismatch
8
9 #[rustc_safe_intrinsic]
10 fn assume(b: bool); //~ ERROR intrinsic safety mismatch
11 //~^ ERROR intrinsic safety mismatch
128}
139
10#[rustc_intrinsic]
11const fn assume(_b: bool) {} //~ ERROR intrinsic safety mismatch
12//~| ERROR intrinsic has wrong type
13
1414#[rustc_intrinsic]
1515const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
1616//~^ ERROR intrinsic safety mismatch
tests/ui/intrinsics/safe-intrinsic-mismatch.stderr+11-10
......@@ -4,12 +4,6 @@ error: intrinsic safety mismatch between list of intrinsics within the compiler
44LL | fn size_of<T>() -> usize;
55 | ^^^^^^^^^^^^^^^^^^^^^^^^
66
7error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
8 --> $DIR/safe-intrinsic-mismatch.rs:10:5
9 |
10LL | fn assume(b: bool);
11 | ^^^^^^^^^^^^^^^^^^
12
137error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
148 --> $DIR/safe-intrinsic-mismatch.rs:6:5
159 |
......@@ -19,12 +13,19 @@ LL | fn size_of<T>() -> usize;
1913 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
2014
2115error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
22 --> $DIR/safe-intrinsic-mismatch.rs:10:5
16 --> $DIR/safe-intrinsic-mismatch.rs:11:1
2317 |
24LL | fn assume(b: bool);
25 | ^^^^^^^^^^^^^^^^^^
18LL | const fn assume(_b: bool) {}
19 | ^^^^^^^^^^^^^^^^^^^^^^^^^
20
21error[E0308]: intrinsic has wrong type
22 --> $DIR/safe-intrinsic-mismatch.rs:11:16
2623 |
27 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
24LL | const fn assume(_b: bool) {}
25 | ^ expected unsafe fn, found normal fn
26 |
27 = note: expected signature `unsafe fn(_)`
28 found signature `fn(_)`
2829
2930error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate`
3031 --> $DIR/safe-intrinsic-mismatch.rs:15:1
tests/ui/reify-intrinsic.rs+2-3
......@@ -13,10 +13,9 @@ fn b() {
1313}
1414
1515fn c() {
16 let _ = [
17 std::intrinsics::likely,
16 let _: [unsafe extern "rust-intrinsic" fn(bool) -> bool; 2] = [
17 std::intrinsics::likely, //~ ERROR cannot coerce
1818 std::intrinsics::unlikely,
19 //~^ ERROR cannot coerce
2019 ];
2120}
2221
tests/ui/reify-intrinsic.stderr+5-6
......@@ -16,14 +16,13 @@ LL | let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize)
1616 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1717
1818error[E0308]: cannot coerce intrinsics to function pointers
19 --> $DIR/reify-intrinsic.rs:18:9
19 --> $DIR/reify-intrinsic.rs:17:9
2020 |
21LL | std::intrinsics::unlikely,
22 | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
21LL | std::intrinsics::likely,
22 | ^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
2323 |
24 = note: expected fn item `extern "rust-intrinsic" fn(_) -> _ {likely}`
25 found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}`
26 = note: different fn items have unique types, even if their signatures are the same
24 = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(_) -> _`
25 found fn item `fn(_) -> _ {likely}`
2726
2827error: aborting due to 3 previous errors
2928
triagebot.toml+7-2
......@@ -480,12 +480,16 @@ cc = ["@lcnr", "@compiler-errors"]
480480message = "Some changes occurred in diagnostic error codes"
481481cc = ["@GuillaumeGomez"]
482482
483[mentions."compiler/rustc_mir_build/src/build/matches"]
484message = "Some changes occurred in match lowering"
485cc = ["@Nadrieril"]
486
483487[mentions."compiler/rustc_mir_build/src/thir/pattern"]
484message = "Some changes might have occurred in exhaustiveness checking"
488message = "Some changes occurred in match checking"
485489cc = ["@Nadrieril"]
486490
487491[mentions."compiler/rustc_pattern_analysis"]
488message = "Some changes might have occurred in exhaustiveness checking"
492message = "Some changes occurred in exhaustiveness checking"
489493cc = ["@Nadrieril"]
490494
491495[mentions."library/core/src/intrinsics/simd.rs"]
......@@ -659,6 +663,7 @@ compiler-team = [
659663]
660664compiler-team-contributors = [
661665 "@TaKO8Ki",
666 "@Nadrieril",
662667 "@nnethercote",
663668 "@fmease",
664669]