Skip to content

Commit 947c0de

Browse files
nikomatsakisMark-Simulacrum
authored andcommitted
introduce a Coerce predicate
1 parent 5a8edc0 commit 947c0de

File tree

24 files changed

+153
-2
lines changed

24 files changed

+153
-2
lines changed

Diff for: compiler/rustc_infer/src/infer/mod.rs

+29
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,35 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
969969
);
970970
}
971971

972+
/// Processes a `Coerce` predicate from the fulfillment context.
973+
/// This is NOT the preferred way to handle coercion, which is to
974+
/// invoke `FnCtxt::coerce` or a similar method (see `coercion.rs`).
975+
///
976+
/// This method here is actually a fallback that winds up being
977+
/// invoked when `FnCtxt::coerce` encounters unresolved type variables
978+
/// and records a coercion predicate. Presently, this method is equivalent
979+
/// to `subtype_predicate` -- that is, "coercing" `a` to `b` winds up
980+
/// actually requiring `a <: b`. This is of course a valid coercion,
981+
/// but it's not as flexible as `FnCtxt::coerce` would be.
982+
///
983+
/// (We may refactor this in the future, but there are a number of
984+
/// practical obstacles. Among other things, `FnCtxt::coerce` presently
985+
/// records adjustments that are required on the HIR in order to perform
986+
/// the coercion, and we don't currently have a way to manage that.)
987+
pub fn coerce_predicate(
988+
&self,
989+
cause: &ObligationCause<'tcx>,
990+
param_env: ty::ParamEnv<'tcx>,
991+
predicate: ty::PolyCoercePredicate<'tcx>,
992+
) -> Option<InferResult<'tcx, ()>> {
993+
let subtype_predicate = predicate.map_bound(|p| ty::SubtypePredicate {
994+
a_is_expected: false, // when coercing from `a` to `b`, `b` is expected
995+
a: p.a,
996+
b: p.b,
997+
});
998+
self.subtype_predicate(cause, param_env, subtype_predicate)
999+
}
1000+
9721001
pub fn subtype_predicate(
9731002
&self,
9741003
cause: &ObligationCause<'tcx>,

Diff for: compiler/rustc_infer/src/infer/outlives/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub fn explicit_outlives_bounds<'tcx>(
1919
.filter_map(move |kind| match kind {
2020
ty::PredicateKind::Projection(..)
2121
| ty::PredicateKind::Trait(..)
22+
| ty::PredicateKind::Coerce(..)
2223
| ty::PredicateKind::Subtype(..)
2324
| ty::PredicateKind::WellFormed(..)
2425
| ty::PredicateKind::ObjectSafe(..)

Diff for: compiler/rustc_infer/src/traits/util.rs

+4
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ impl Elaborator<'tcx> {
158158
// Currently, we do not "elaborate" predicates like `X <: Y`,
159159
// though conceivably we might.
160160
}
161+
ty::PredicateKind::Coerce(..) => {
162+
// Currently, we do not "elaborate" predicates like `X -> Y`,
163+
// though conceivably we might.
164+
}
161165
ty::PredicateKind::Projection(..) => {
162166
// Nothing to elaborate in a projection predicate.
163167
}

Diff for: compiler/rustc_lint/src/builtin.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
16521652
ObjectSafe(..) |
16531653
ClosureKind(..) |
16541654
Subtype(..) |
1655+
Coerce(..) |
16551656
ConstEvaluatable(..) |
16561657
ConstEquate(..) |
16571658
TypeWellFormedFromEnv(..) => continue,

Diff for: compiler/rustc_middle/src/ty/flags.rs

+4
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ impl FlagComputation {
231231
self.add_ty(a);
232232
self.add_ty(b);
233233
}
234+
ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
235+
self.add_ty(a);
236+
self.add_ty(b);
237+
}
234238
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
235239
self.add_projection_ty(projection_ty);
236240
self.add_ty(ty);

Diff for: compiler/rustc_middle/src/ty/mod.rs

+28
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,22 @@ pub enum PredicateKind<'tcx> {
485485
ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind),
486486

487487
/// `T1 <: T2`
488+
///
489+
/// This obligation is created most often when we have two
490+
/// unresolved type variables and hence don't have enough
491+
/// information to process the subtyping obligation yet.
488492
Subtype(SubtypePredicate<'tcx>),
489493

494+
/// `T1` coerced to `T2`
495+
///
496+
/// Like a subtyping obligation, this is created most often
497+
/// when we have two unresolved type variables and hence
498+
/// don't have enough information to process the coercion
499+
/// obligation yet. At the moment, we actually process coercions
500+
/// very much like subtyping and don't handle the full coercion
501+
/// logic.
502+
Coerce(CoercePredicate<'tcx>),
503+
490504
/// Constant initializer must evaluate successfully.
491505
ConstEvaluatable(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
492506

@@ -655,6 +669,9 @@ pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'t
655669
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>;
656670
pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>;
657671

672+
/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
673+
/// whether the `a` type is the type that we should label as "expected" when
674+
/// presenting user diagnostics.
658675
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
659676
#[derive(HashStable, TypeFoldable)]
660677
pub struct SubtypePredicate<'tcx> {
@@ -664,6 +681,15 @@ pub struct SubtypePredicate<'tcx> {
664681
}
665682
pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
666683

684+
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
685+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
686+
#[derive(HashStable, TypeFoldable)]
687+
pub struct CoercePredicate<'tcx> {
688+
pub a: Ty<'tcx>,
689+
pub b: Ty<'tcx>,
690+
}
691+
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
692+
667693
/// This kind of predicate has no *direct* correspondent in the
668694
/// syntax, but it roughly corresponds to the syntactic forms:
669695
///
@@ -806,6 +832,7 @@ impl<'tcx> Predicate<'tcx> {
806832
}
807833
PredicateKind::Projection(..)
808834
| PredicateKind::Subtype(..)
835+
| PredicateKind::Coerce(..)
809836
| PredicateKind::RegionOutlives(..)
810837
| PredicateKind::WellFormed(..)
811838
| PredicateKind::ObjectSafe(..)
@@ -824,6 +851,7 @@ impl<'tcx> Predicate<'tcx> {
824851
PredicateKind::Trait(..)
825852
| PredicateKind::Projection(..)
826853
| PredicateKind::Subtype(..)
854+
| PredicateKind::Coerce(..)
827855
| PredicateKind::RegionOutlives(..)
828856
| PredicateKind::WellFormed(..)
829857
| PredicateKind::ObjectSafe(..)

Diff for: compiler/rustc_middle/src/ty/print/pretty.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2236,6 +2236,10 @@ define_print_and_forward_display! {
22362236
p!(print(self.a), " <: ", print(self.b))
22372237
}
22382238

2239+
ty::CoercePredicate<'tcx> {
2240+
p!(print(self.a), " -> ", print(self.b))
2241+
}
2242+
22392243
ty::TraitPredicate<'tcx> {
22402244
p!(print(self.trait_ref.self_ty()), ": ",
22412245
print(self.trait_ref.print_only_trait_path()))
@@ -2268,6 +2272,7 @@ define_print_and_forward_display! {
22682272
p!(print(data))
22692273
}
22702274
ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
2275+
ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
22712276
ty::PredicateKind::RegionOutlives(predicate) => p!(print(predicate)),
22722277
ty::PredicateKind::TypeOutlives(predicate) => p!(print(predicate)),
22732278
ty::PredicateKind::Projection(predicate) => p!(print(predicate)),

Diff for: compiler/rustc_middle/src/ty/structural_impls.rs

+9
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ impl fmt::Debug for ty::PredicateKind<'tcx> {
179179
match *self {
180180
ty::PredicateKind::Trait(ref a) => a.fmt(f),
181181
ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
182+
ty::PredicateKind::Coerce(ref pair) => pair.fmt(f),
182183
ty::PredicateKind::RegionOutlives(ref pair) => pair.fmt(f),
183184
ty::PredicateKind::TypeOutlives(ref pair) => pair.fmt(f),
184185
ty::PredicateKind::Projection(ref pair) => pair.fmt(f),
@@ -380,6 +381,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
380381
}
381382
}
382383

384+
impl<'a, 'tcx> Lift<'tcx> for ty::CoercePredicate<'a> {
385+
type Lifted = ty::CoercePredicate<'tcx>;
386+
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::CoercePredicate<'tcx>> {
387+
tcx.lift((self.a, self.b)).map(|(a, b)| ty::CoercePredicate { a, b })
388+
}
389+
}
390+
383391
impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
384392
type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
385393
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@@ -420,6 +428,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
420428
match self {
421429
ty::PredicateKind::Trait(data) => tcx.lift(data).map(ty::PredicateKind::Trait),
422430
ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype),
431+
ty::PredicateKind::Coerce(data) => tcx.lift(data).map(ty::PredicateKind::Coerce),
423432
ty::PredicateKind::RegionOutlives(data) => {
424433
tcx.lift(data).map(ty::PredicateKind::RegionOutlives)
425434
}

Diff for: compiler/rustc_mir/src/transform/check_consts/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,8 @@ impl Checker<'mir, 'tcx> {
420420
ty::PredicateKind::ClosureKind(..) => {
421421
bug!("closure kind predicate on function: {:#?}", predicate)
422422
}
423-
ty::PredicateKind::Subtype(_) => {
424-
bug!("subtype predicate on function: {:#?}", predicate)
423+
ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) => {
424+
bug!("subtype/coerce predicate on function: {:#?}", predicate)
425425
}
426426
ty::PredicateKind::Trait(pred) => {
427427
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {

Diff for: compiler/rustc_trait_selection/src/opaque_types.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,7 @@ crate fn required_region_bounds(
11191119
ty::PredicateKind::Projection(..)
11201120
| ty::PredicateKind::Trait(..)
11211121
| ty::PredicateKind::Subtype(..)
1122+
| ty::PredicateKind::Coerce(..)
11221123
| ty::PredicateKind::WellFormed(..)
11231124
| ty::PredicateKind::ObjectSafe(..)
11241125
| ty::PredicateKind::ClosureKind(..)

Diff for: compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
565565
span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
566566
}
567567

568+
ty::PredicateKind::Coerce(predicate) => {
569+
// Errors for Coerce predicates show up as
570+
// `FulfillmentErrorCode::CodeSubtypeError`,
571+
// not selection error.
572+
span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate)
573+
}
574+
568575
ty::PredicateKind::RegionOutlives(predicate) => {
569576
let predicate = bound_predicate.rebind(predicate);
570577
let predicate = self.resolve_vars_if_possible(predicate);

Diff for: compiler/rustc_trait_selection/src/traits/fulfill.rs

+26
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
402402
| ty::PredicateKind::ObjectSafe(_)
403403
| ty::PredicateKind::ClosureKind(..)
404404
| ty::PredicateKind::Subtype(_)
405+
| ty::PredicateKind::Coerce(_)
405406
| ty::PredicateKind::ConstEvaluatable(..)
406407
| ty::PredicateKind::ConstEquate(..) => {
407408
let pred = infcx.replace_bound_vars_with_placeholders(binder);
@@ -517,6 +518,31 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
517518
}
518519
}
519520

521+
ty::PredicateKind::Coerce(coerce) => {
522+
match self.selcx.infcx().coerce_predicate(
523+
&obligation.cause,
524+
obligation.param_env,
525+
Binder::dummy(coerce),
526+
) {
527+
None => {
528+
// None means that both are unresolved.
529+
pending_obligation.stalled_on = vec![
530+
TyOrConstInferVar::maybe_from_ty(coerce.a).unwrap(),
531+
TyOrConstInferVar::maybe_from_ty(coerce.b).unwrap(),
532+
];
533+
ProcessResult::Unchanged
534+
}
535+
Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
536+
Some(Err(err)) => {
537+
let expected_found = ExpectedFound::new(false, coerce.a, coerce.b);
538+
ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError(
539+
expected_found,
540+
err,
541+
))
542+
}
543+
}
544+
}
545+
520546
ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
521547
match const_evaluatable::is_const_evaluatable(
522548
self.selcx.infcx(),

Diff for: compiler/rustc_trait_selection/src/traits/object_safety.rs

+2
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ fn predicate_references_self(
308308
| ty::PredicateKind::RegionOutlives(..)
309309
| ty::PredicateKind::ClosureKind(..)
310310
| ty::PredicateKind::Subtype(..)
311+
| ty::PredicateKind::Coerce(..)
311312
| ty::PredicateKind::ConstEvaluatable(..)
312313
| ty::PredicateKind::ConstEquate(..)
313314
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
@@ -336,6 +337,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
336337
}
337338
ty::PredicateKind::Projection(..)
338339
| ty::PredicateKind::Subtype(..)
340+
| ty::PredicateKind::Coerce(..)
339341
| ty::PredicateKind::RegionOutlives(..)
340342
| ty::PredicateKind::WellFormed(..)
341343
| ty::PredicateKind::ObjectSafe(..)

Diff for: compiler/rustc_trait_selection/src/traits/select/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
512512
}
513513
}
514514

515+
ty::PredicateKind::Coerce(p) => {
516+
let p = bound_predicate.rebind(p);
517+
// Does this code ever run?
518+
match self.infcx.coerce_predicate(&obligation.cause, obligation.param_env, p) {
519+
Some(Ok(InferOk { mut obligations, .. })) => {
520+
self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
521+
self.evaluate_predicates_recursively(
522+
previous_stack,
523+
obligations.into_iter(),
524+
)
525+
}
526+
Some(Err(_)) => Ok(EvaluatedToErr),
527+
None => Ok(EvaluatedToAmbig),
528+
}
529+
}
530+
515531
ty::PredicateKind::WellFormed(arg) => match wf::obligations(
516532
self.infcx,
517533
obligation.param_env,

Diff for: compiler/rustc_trait_selection/src/traits/wf.rs

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ pub fn predicate_obligations<'a, 'tcx>(
128128
wf.compute(a.into());
129129
wf.compute(b.into());
130130
}
131+
ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
132+
wf.compute(a.into());
133+
wf.compute(b.into());
134+
}
131135
ty::PredicateKind::ConstEvaluatable(def, substs) => {
132136
let obligations = wf.nominal_obligations(def.did, substs);
133137
wf.out.extend(obligations);

Diff for: compiler/rustc_traits/src/chalk/lowering.rs

+4
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
109109
| ty::PredicateKind::ObjectSafe(..)
110110
| ty::PredicateKind::ClosureKind(..)
111111
| ty::PredicateKind::Subtype(..)
112+
| ty::PredicateKind::Coerce(..)
112113
| ty::PredicateKind::ConstEvaluatable(..)
113114
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
114115
};
@@ -193,6 +194,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
193194
// some of these in terms of chalk operations.
194195
ty::PredicateKind::ClosureKind(..)
195196
| ty::PredicateKind::Subtype(..)
197+
| ty::PredicateKind::Coerce(..)
196198
| ty::PredicateKind::ConstEvaluatable(..)
197199
| ty::PredicateKind::ConstEquate(..) => {
198200
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
@@ -592,6 +594,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
592594
ty::PredicateKind::ObjectSafe(..)
593595
| ty::PredicateKind::ClosureKind(..)
594596
| ty::PredicateKind::Subtype(..)
597+
| ty::PredicateKind::Coerce(..)
595598
| ty::PredicateKind::ConstEvaluatable(..)
596599
| ty::PredicateKind::ConstEquate(..)
597600
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
@@ -719,6 +722,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
719722
| ty::PredicateKind::ObjectSafe(..)
720723
| ty::PredicateKind::ClosureKind(..)
721724
| ty::PredicateKind::Subtype(..)
725+
| ty::PredicateKind::Coerce(..)
722726
| ty::PredicateKind::ConstEvaluatable(..)
723727
| ty::PredicateKind::ConstEquate(..)
724728
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {

Diff for: compiler/rustc_traits/src/implied_outlives_bounds.rs

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ fn compute_implied_outlives_bounds<'tcx>(
9999
Some(pred) => match pred {
100100
ty::PredicateKind::Trait(..)
101101
| ty::PredicateKind::Subtype(..)
102+
| ty::PredicateKind::Coerce(..)
102103
| ty::PredicateKind::Projection(..)
103104
| ty::PredicateKind::ClosureKind(..)
104105
| ty::PredicateKind::ObjectSafe(..)

Diff for: compiler/rustc_traits/src/normalize_erasing_regions.rs

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ fn not_outlives_predicate(p: &ty::Predicate<'tcx>) -> bool {
6565
| ty::PredicateKind::ObjectSafe(..)
6666
| ty::PredicateKind::ClosureKind(..)
6767
| ty::PredicateKind::Subtype(..)
68+
| ty::PredicateKind::Coerce(..)
6869
| ty::PredicateKind::ConstEvaluatable(..)
6970
| ty::PredicateKind::ConstEquate(..)
7071
| ty::PredicateKind::TypeWellFormedFromEnv(..) => true,

Diff for: compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
812812
Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation))
813813
}
814814
ty::PredicateKind::Subtype(..) => None,
815+
ty::PredicateKind::Coerce(..) => None,
815816
ty::PredicateKind::RegionOutlives(..) => None,
816817
ty::PredicateKind::TypeOutlives(..) => None,
817818
ty::PredicateKind::WellFormed(..) => None,

Diff for: compiler/rustc_typeck/src/check/method/probe.rs

+1
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
841841
}
842842
}
843843
ty::PredicateKind::Subtype(..)
844+
| ty::PredicateKind::Coerce(..)
844845
| ty::PredicateKind::Projection(..)
845846
| ty::PredicateKind::RegionOutlives(..)
846847
| ty::PredicateKind::WellFormed(..)

Diff for: compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs

+1
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ fn trait_predicate_kind<'tcx>(
407407
| ty::PredicateKind::Projection(_)
408408
| ty::PredicateKind::WellFormed(_)
409409
| ty::PredicateKind::Subtype(_)
410+
| ty::PredicateKind::Coerce(_)
410411
| ty::PredicateKind::ObjectSafe(_)
411412
| ty::PredicateKind::ClosureKind(..)
412413
| ty::PredicateKind::ConstEvaluatable(..)

Diff for: compiler/rustc_typeck/src/outlives/explicit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
5656
| ty::PredicateKind::ObjectSafe(..)
5757
| ty::PredicateKind::ClosureKind(..)
5858
| ty::PredicateKind::Subtype(..)
59+
| ty::PredicateKind::Coerce(..)
5960
| ty::PredicateKind::ConstEvaluatable(..)
6061
| ty::PredicateKind::ConstEquate(..)
6162
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),

Diff for: src/librustdoc/clean/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
332332
ty::PredicateKind::ConstEvaluatable(..) => None,
333333

334334
ty::PredicateKind::Subtype(..)
335+
| ty::PredicateKind::Coerce(..)
335336
| ty::PredicateKind::WellFormed(..)
336337
| ty::PredicateKind::ObjectSafe(..)
337338
| ty::PredicateKind::ClosureKind(..)

0 commit comments

Comments
 (0)