Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 81831e1

Browse files
committed
add WellFormedConst predicate
1 parent cb2308d commit 81831e1

File tree

32 files changed

+296
-61
lines changed

32 files changed

+296
-61
lines changed

src/librustc_infer/infer/outlives/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ pub fn explicit_outlives_bounds<'tcx>(
2020
| ty::PredicateKind::ClosureKind(..)
2121
| ty::PredicateKind::TypeOutlives(..)
2222
| ty::PredicateKind::ConstEvaluatable(..)
23-
| ty::PredicateKind::ConstEquate(..) => None,
23+
| ty::PredicateKind::ConstEquate(..)
24+
| ty::PredicateKind::WellFormedConst(..) => None,
2425
ty::PredicateKind::RegionOutlives(ref data) => data
2526
.no_bound_vars()
2627
.map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)),

src/librustc_infer/traits/util.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ pub fn anonymize_predicate<'tcx>(
4545
}
4646

4747
ty::PredicateKind::ConstEquate(c1, c2) => ty::PredicateKind::ConstEquate(c1, c2),
48+
49+
ty::PredicateKind::WellFormedConst(ct) => ty::PredicateKind::WellFormedConst(ct),
4850
};
4951

5052
if new != *kind { new.to_predicate(tcx) } else { pred }
@@ -204,6 +206,9 @@ impl Elaborator<'tcx> {
204206
// Currently, we do not elaborate const-equate
205207
// predicates.
206208
}
209+
ty::PredicateKind::WellFormedConst(..) => {
210+
// Currently, we do not elaborate WF predicates.
211+
}
207212
ty::PredicateKind::RegionOutlives(..) => {
208213
// Nothing to elaborate from `'a: 'b`.
209214
}

src/librustc_lint/builtin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
12181218
Projection(..) |
12191219
// Ignore bounds that a user can't type
12201220
WellFormed(..) |
1221+
WellFormedConst(..) |
12211222
ObjectSafe(..) |
12221223
ClosureKind(..) |
12231224
Subtype(..) |

src/librustc_middle/ty/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,9 @@ pub enum PredicateKind<'tcx> {
10791079

10801080
/// Constants must be equal. The first component is the const that is expected.
10811081
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
1082+
1083+
/// Constant must be well formed.
1084+
WellFormedConst(&'tcx Const<'tcx>),
10821085
}
10831086

10841087
/// The crate outlives map is computed during typeck and contains the
@@ -1195,6 +1198,9 @@ impl<'tcx> Predicate<'tcx> {
11951198
PredicateKind::ConstEquate(c1, c2) => {
11961199
PredicateKind::ConstEquate(c1.subst(tcx, substs), c2.subst(tcx, substs))
11971200
}
1201+
PredicateKind::WellFormedConst(c) => {
1202+
PredicateKind::WellFormedConst(c.subst(tcx, substs))
1203+
}
11981204
};
11991205

12001206
if new != *kind { new.to_predicate(tcx) } else { self }
@@ -1386,7 +1392,8 @@ impl<'tcx> Predicate<'tcx> {
13861392
| PredicateKind::ClosureKind(..)
13871393
| PredicateKind::TypeOutlives(..)
13881394
| PredicateKind::ConstEvaluatable(..)
1389-
| PredicateKind::ConstEquate(..) => None,
1395+
| PredicateKind::ConstEquate(..)
1396+
| PredicateKind::WellFormedConst(..) => None,
13901397
}
13911398
}
13921399

@@ -1401,7 +1408,8 @@ impl<'tcx> Predicate<'tcx> {
14011408
| PredicateKind::ObjectSafe(..)
14021409
| PredicateKind::ClosureKind(..)
14031410
| PredicateKind::ConstEvaluatable(..)
1404-
| PredicateKind::ConstEquate(..) => None,
1411+
| PredicateKind::ConstEquate(..)
1412+
| PredicateKind::WellFormedConst(..) => None,
14051413
}
14061414
}
14071415
}

src/librustc_middle/ty/print/pretty.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,6 +2054,9 @@ define_print_and_forward_display! {
20542054
print(c2),
20552055
write("`"))
20562056
}
2057+
ty::PredicateKind::WellFormedConst(c) => {
2058+
p!(print(c), write(" well-formed"))
2059+
}
20572060
}
20582061
}
20592062

src/librustc_middle/ty/structural_impls.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ impl fmt::Debug for ty::PredicateKind<'tcx> {
247247
write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
248248
}
249249
ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
250+
ty::PredicateKind::WellFormedConst(c) => write!(f, "WellFormedConst({:?})", c),
250251
}
251252
}
252253
}
@@ -507,6 +508,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
507508
ty::PredicateKind::ConstEquate(c1, c2) => {
508509
tcx.lift(&(c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2))
509510
}
511+
ty::PredicateKind::WellFormedConst(c) => {
512+
tcx.lift(&c).map(ty::PredicateKind::WellFormedConst)
513+
}
510514
}
511515
}
512516
}

src/librustc_mir/transform/qualify_min_const_fn.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
2929
| ty::PredicateKind::WellFormed(_)
3030
| ty::PredicateKind::Projection(_)
3131
| ty::PredicateKind::ConstEvaluatable(..)
32-
| ty::PredicateKind::ConstEquate(..) => continue,
32+
| ty::PredicateKind::ConstEquate(..)
33+
| ty::PredicateKind::WellFormedConst(..) => continue,
3334
ty::PredicateKind::ObjectSafe(_) => {
3435
bug!("object safe predicate on function: {:#?}", predicate)
3536
}

src/librustc_trait_selection/opaque_types.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,8 @@ crate fn required_region_bounds(
12771277
| ty::PredicateKind::ClosureKind(..)
12781278
| ty::PredicateKind::RegionOutlives(..)
12791279
| ty::PredicateKind::ConstEvaluatable(..)
1280-
| ty::PredicateKind::ConstEquate(..) => None,
1280+
| ty::PredicateKind::ConstEquate(..)
1281+
| ty::PredicateKind::WellFormedConst(..) => None,
12811282
ty::PredicateKind::TypeOutlives(predicate) => {
12821283
// Search for a bound of the form `erased_self_ty
12831284
// : 'a`, but be wary of something like `for<'a>

src/librustc_trait_selection/traits/error_reporting/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
610610
}
611611
}
612612

613+
ty::PredicateKind::WellFormedConst(ct) => {
614+
// Const WF predicates cannot themselves make
615+
// errors. They can only block due to
616+
// ambiguity; otherwise, they always
617+
// degenerate into other obligations
618+
// (which may fail).
619+
span_bug!(span, "const WF predicate not satisfied for {:?}", ct);
620+
}
621+
613622
ty::PredicateKind::ConstEvaluatable(..) => {
614623
// Errors for `ConstEvaluatable` predicates show up as
615624
// `SelectionError::ConstEvalFailure`,
@@ -1540,6 +1549,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
15401549
self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
15411550
}
15421551

1552+
ty::PredicateKind::WellFormedConst(ct) => {
1553+
// Same hacky approach as above to avoid deluging user
1554+
// with error messages.
1555+
if ct.references_error() || self.tcx.sess.has_errors() {
1556+
return;
1557+
}
1558+
self.need_type_info_err_const(body_id, span, ct, ErrorCode::E0282)
1559+
}
1560+
15431561
ty::PredicateKind::Subtype(ref data) => {
15441562
if data.references_error() || self.tcx.sess.has_errors() {
15451563
// no need to overload user in such cases

src/librustc_trait_selection/traits/fulfill.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,21 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
476476
}
477477
}
478478

479+
ty::PredicateKind::WellFormedConst(constant) => match wf::const_obligations(
480+
self.selcx.infcx(),
481+
obligation.param_env,
482+
obligation.cause.body_id,
483+
constant,
484+
obligation.cause.span,
485+
) {
486+
Some(predicates) => ProcessResult::Changed(mk_pending(predicates)),
487+
None => {
488+
pending_obligation.stalled_on =
489+
vec![TyOrConstInferVar::maybe_from_const(constant).unwrap()];
490+
ProcessResult::Unchanged
491+
}
492+
},
493+
479494
&ty::PredicateKind::Subtype(subtype) => {
480495
match self.selcx.infcx().subtype_predicate(
481496
&obligation.cause,

0 commit comments

Comments
 (0)