diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-01-26 23:45:22 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-26 23:45:22 +0100 |
| commit | e2b2bfe10ce5d36e9568173cb6cb9c7456b03a61 (patch) | |
| tree | a7ac618fc130011154e20d0c431a4ed7fb8a91e0 /compiler/rustc_middle/src | |
| parent | e249812597cb1a57ff704e340a62fbe2d22c7565 (diff) | |
| parent | 8b76cad0a7e4a7743d4dd44dd53f077f3d0b8924 (diff) | |
| download | rust-e2b2bfe10ce5d36e9568173cb6cb9c7456b03a61.tar.gz rust-e2b2bfe10ce5d36e9568173cb6cb9c7456b03a61.zip | |
Rollup merge of #92256 - fee1-dead:improve-selection-err, r=oli-obk
Improve selection errors for `~const` trait bounds
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/traits/mod.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 43 |
3 files changed, 64 insertions, 6 deletions
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index b7ccfac8063..1123cab8076 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -402,7 +402,7 @@ impl ObligationCauseCode<'_> { // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ObligationCauseCode<'_>, 40); +static_assert_size!(ObligationCauseCode<'_>, 48); #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum StatementAsExpression { @@ -440,11 +440,11 @@ pub struct IfExpressionCause { #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] pub struct DerivedObligationCause<'tcx> { - /// The trait reference of the parent obligation that led to the + /// The trait predicate of the parent obligation that led to the /// current obligation. Note that only trait obligations lead to - /// derived obligations, so we just store the trait reference here + /// derived obligations, so we just store the trait predicate here /// directly. - pub parent_trait_ref: ty::PolyTraitRef<'tcx>, + pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>, /// The parent trait had this cause. pub parent_code: Lrc<ObligationCauseCode<'tcx>>, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 64c00c353ca..6174c922e2d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -766,6 +766,17 @@ impl<'tcx> TraitPredicate<'tcx> { *param_env = param_env.with_constness(self.constness.and(param_env.constness())) } } + + /// Remap the constness of this predicate before emitting it for diagnostics. + pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) { + // this is different to `remap_constness` that callees want to print this predicate + // in case of selection errors. `T: ~const Drop` bounds cannot end up here when the + // param_env is not const because we it is always satisfied in non-const contexts. + if let hir::Constness::NotConst = param_env.constness() { + self.constness = ty::BoundConstness::NotConst; + } + } + pub fn def_id(self) -> DefId { self.trait_ref.def_id } @@ -784,6 +795,14 @@ impl<'tcx> PolyTraitPredicate<'tcx> { pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> { self.map_bound(|trait_ref| trait_ref.self_ty()) } + + /// Remap the constness of this predicate before emitting it for diagnostics. + pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) { + *self = self.map_bound(|mut p| { + p.remap_constness_diag(param_env); + p + }); + } } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 00a1256d684..ddcc8680d83 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2413,6 +2413,29 @@ impl<'tcx> ty::Binder<'tcx, ty::TraitRef<'tcx>> { } } +#[derive(Copy, Clone, TypeFoldable, Lift)] +pub struct TraitPredPrintModifiersAndPath<'tcx>(ty::TraitPredicate<'tcx>); + +impl<'tcx> fmt::Debug for TraitPredPrintModifiersAndPath<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl<'tcx> ty::TraitPredicate<'tcx> { + pub fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { + TraitPredPrintModifiersAndPath(self) + } +} + +impl<'tcx> ty::PolyTraitPredicate<'tcx> { + pub fn print_modifiers_and_trait_path( + self, + ) -> ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>> { + self.map_bound(TraitPredPrintModifiersAndPath) + } +} + forward_display_to_print! { Ty<'tcx>, &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, @@ -2427,6 +2450,7 @@ forward_display_to_print! { ty::Binder<'tcx, TraitRefPrintOnlyTraitName<'tcx>>, ty::Binder<'tcx, ty::FnSig<'tcx>>, ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, + ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>>, ty::Binder<'tcx, ty::SubtypePredicate<'tcx>>, ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>, ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>, @@ -2491,6 +2515,18 @@ define_print_and_forward_display! { p!(print_def_path(self.0.def_id, &[])); } + TraitPredPrintModifiersAndPath<'tcx> { + if let ty::BoundConstness::ConstIfConst = self.0.constness { + p!("~const ") + } + + if let ty::ImplPolarity::Negative = self.0.polarity { + p!("!") + } + + p!(print(self.0.trait_ref.print_only_trait_path())); + } + ty::ParamTy { p!(write("{}", self.name)) } @@ -2508,8 +2544,11 @@ define_print_and_forward_display! { } ty::TraitPredicate<'tcx> { - p!(print(self.trait_ref.self_ty()), ": ", - print(self.trait_ref.print_only_trait_path())) + p!(print(self.trait_ref.self_ty()), ": "); + if let ty::BoundConstness::ConstIfConst = self.constness { + p!("~const "); + } + p!(print(self.trait_ref.print_only_trait_path())) } ty::ProjectionPredicate<'tcx> { |
