diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 5bb78d172531..abc33e84139f 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1328,7 +1328,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Clause::TypeOutlives(_) => { // Do nothing, we deal with regions separately } - ty::Clause::RegionOutlives(_) => bug!(), + ty::Clause::RegionOutlives(_) | ty::Clause::ConstArgHasType(..) => bug!(), }, ty::PredicateKind::WellFormed(_) | ty::PredicateKind::AliasEq(..) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 02f77f9d6afb..2562a1739f50 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -517,6 +517,7 @@ fn trait_predicate_kind<'tcx>( ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::Projection(_)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::WellFormed(_) | ty::PredicateKind::Subtype(_) diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index ecd6849426db..9ee6785970c4 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -54,6 +54,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::WellFormed(..) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::ObjectSafe(..) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e9c899f95ea7..5b641be062be 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -663,6 +663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index ffe04bc7294e..0e3a16ac7172 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -826,6 +826,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } ty::PredicateKind::Subtype(..) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index a8e668d81eae..83f3d5a74fb4 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -21,6 +21,7 @@ pub fn explicit_outlives_bounds<'tcx>( .filter_map(move |kind| match kind { ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::Trait(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Subtype(..) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 68b39c5f00fb..c1f0a6e98340 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -297,6 +297,9 @@ impl<'tcx> Elaborator<'tcx> { ty::PredicateKind::AliasEq(..) => { // No } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => { + // Nothing to elaborate + } } } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 9bbd017c339c..11fb1f80a111 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1595,6 +1595,8 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { Clause(Clause::TypeOutlives(..)) | Clause(Clause::RegionOutlives(..)) => "lifetime", + // `ConstArgHasType` is never global as `ct` is always a param + Clause(Clause::ConstArgHasType(..)) | // Ignore projections, as they can only be global // if the trait bound is global Clause(Clause::Projection(..)) | diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index c9aa0ec66d56..91241ff404f4 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -251,6 +251,10 @@ impl FlagComputation { self.add_ty(ty); self.add_region(region); } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + self.add_const(ct); + self.add_ty(ty); + } ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: _, a, b }) => { self.add_ty(a); self.add_ty(b); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d1b686a0b086..4b4f62b67f21 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -552,6 +552,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Clause(Clause::RegionOutlives(_)) | PredicateKind::Clause(Clause::TypeOutlives(_)) | PredicateKind::Clause(Clause::Projection(_)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::AliasEq(..) | PredicateKind::ObjectSafe(_) | PredicateKind::ClosureKind(_, _, _) @@ -590,6 +591,10 @@ pub enum Clause<'tcx> { /// `where ::Name == X`, approximately. /// See the `ProjectionPredicate` struct for details. Projection(ProjectionPredicate<'tcx>), + + /// Ensures that a const generic argument to a parameter `const N: u8` + /// is of type `u8`. + ConstArgHasType(Const<'tcx>, Ty<'tcx>), } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] @@ -1193,6 +1198,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::Trait(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(Clause::Projection(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) @@ -1213,6 +1219,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::Projection(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(Clause::Trait(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) @@ -1233,6 +1240,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(Clause::TypeOutlives(data)) => Some(predicate.rebind(data)), PredicateKind::Clause(Clause::Trait(..)) + | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::Clause(Clause::Projection(..)) | PredicateKind::AliasEq(..) | PredicateKind::Subtype(..) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 64d218e7e7a6..1e59983583b1 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2822,15 +2822,18 @@ define_print_and_forward_display! { ty::PredicateKind::Clause(ty::Clause::RegionOutlives(predicate)) => p!(print(predicate)), ty::PredicateKind::Clause(ty::Clause::TypeOutlives(predicate)) => p!(print(predicate)), ty::PredicateKind::Clause(ty::Clause::Projection(predicate)) => p!(print(predicate)), + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + p!("the constant `", print(ct), "` has type `", print(ty), "`") + }, ty::PredicateKind::WellFormed(arg) => p!(print(arg), " well-formed"), ty::PredicateKind::ObjectSafe(trait_def_id) => { p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe") } - ty::PredicateKind::ClosureKind(closure_def_id, _closure_substs, kind) => { - p!("the closure `", + ty::PredicateKind::ClosureKind(closure_def_id, _closure_substs, kind) => p!( + "the closure `", print_value_path(closure_def_id, &[]), - write("` implements the trait `{}`", kind)) - } + write("` implements the trait `{}`", kind) + ), ty::PredicateKind::ConstEvaluatable(ct) => { p!("the constant `", print(ct), "` can be evaluated") } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 97ee2b1fc5dd..d8dbd04f4389 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -147,6 +147,7 @@ impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { impl<'tcx> fmt::Debug for ty::Clause<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { + ty::Clause::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"), ty::Clause::Trait(ref a) => a.fmt(f), ty::Clause::RegionOutlives(ref pair) => pair.fmt(f), ty::Clause::TypeOutlives(ref pair) => pair.fmt(f), diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 28aa3d527059..217851ba1d93 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -290,6 +290,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::Clause::RegionOutlives(predicate)) => { self.compute_region_outlives_goal(Goal { param_env, predicate }) } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => { + unimplemented!() + } ty::PredicateKind::Subtype(predicate) => { self.compute_subtype_goal(Goal { param_env, predicate }) } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 3adb15cb4412..9776cc57af8e 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -830,6 +830,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // and these don't correspond to adding any new bounds to // the `ParamEnv`. ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index adc4e950dff2..026522008117 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1282,6 +1282,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { span, "AliasEq predicate should never be the predicate cause of a SelectionError" ), + + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => { + // FIXME: don't know how selection error works so unsure when this is reachable (if it is) + unimplemented!() + } } } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 19d47d33f671..59be80236f81 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -313,6 +313,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::WellFormed(_) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(..) @@ -600,6 +601,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::AliasEq(..) => { bug!("AliasEq is only used for new solver") } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => { + unimplemented!() + } }, } } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 4963f2d75faa..93c3364de8f5 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -327,6 +327,10 @@ fn predicate_references_self<'tcx>( // possible alternatives. data.projection_ty.substs[1..].iter().any(has_self_ty).then_some(sp) } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(_ct, ty)) => { + has_self_ty(&ty.into()).then_some(sp) + } + ty::PredicateKind::AliasEq(..) => bug!("`AliasEq` not allowed as assumption"), ty::PredicateKind::WellFormed(..) @@ -362,6 +366,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0) } ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index bd0871259c3d..2cfaaf1d376f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -993,6 +993,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { bug!("AliasEq is only used for new solver") } ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => { + unimplemented!() + } } }) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5cfb6cf332e1..6a881c233db0 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -163,6 +163,10 @@ pub fn predicate_obligations<'tcx>( ty::TermKind::Const(c) => c.into(), }) } + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { + wf.compute(ct.into()); + wf.compute(ty.into()); + } ty::PredicateKind::WellFormed(arg) => { wf.compute(arg); } @@ -922,6 +926,7 @@ pub(crate) fn required_region_bounds<'tcx>( match obligation.predicate.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::Trait(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::WellFormed(..) diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 9abbd0c5b344..7635f4bfec3b 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -117,6 +117,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi // We can defer this, but ultimately we'll want to express // some of these in terms of chalk operations. ty::PredicateKind::ClosureKind(..) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) @@ -646,6 +648,7 @@ impl<'tcx> LowerInto<'tcx, Option None, + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::AliasEq(..) @@ -780,6 +783,7 @@ impl<'tcx> LowerInto<'tcx, Option None, ty::PredicateKind::WellFormed(_ty) => None, + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) | ty::PredicateKind::AliasEq(..) diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 93f9b66e0f85..abf0c1c5f3e9 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -99,6 +99,9 @@ fn compute_implied_outlives_bounds<'tcx>( }; match pred { ty::PredicateKind::Clause(ty::Clause::Trait(..)) + // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound + // if we ever support that + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 07e716cda42c..2c18a0340507 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -60,6 +60,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) => false, ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasEq(..) | ty::PredicateKind::WellFormed(..) | ty::PredicateKind::ObjectSafe(..) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 42276495a51f..0c70d31ed607 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -320,6 +320,7 @@ pub(crate) fn clean_predicate<'tcx>( // FIXME(generic_const_exprs): should this do something? ty::PredicateKind::ConstEvaluatable(..) => None, ty::PredicateKind::WellFormed(..) => None, + ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::Subtype(..) | ty::PredicateKind::AliasEq(..) diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 26b1d0197499..1a35fe05067f 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -30,7 +30,8 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) ty::Clause::RegionOutlives(_) | ty::Clause::TypeOutlives(_) | ty::Clause::Projection(_) - | ty::Clause::Trait(..), + | ty::Clause::Trait(..) + | ty::Clause::ConstArgHasType(..), ) | ty::PredicateKind::WellFormed(_) | ty::PredicateKind::ConstEvaluatable(..)