|
21 | 21 | //! in the *unconstrained* substs for `impl2`. A parameter is constrained if
|
22 | 22 | //! its value is completely determined by an associated type projection
|
23 | 23 | //! predicate.
|
24 |
| -//! 4. Check that all predicates on `impl1` also exist on `impl2` (after |
25 |
| -//! matching substs). |
| 24 | +//! 4. Check that all predicates on `impl1` either exist on `impl2` (after |
| 25 | +//! matching substs), or are well-formed predicates for the trait's type |
| 26 | +//! arguments. |
26 | 27 | //!
|
27 | 28 | //! ## Example
|
28 | 29 | //!
|
@@ -129,7 +130,7 @@ fn check_always_applicable(
|
129 | 130 | check_static_lifetimes(tcx, &parent_substs, span);
|
130 | 131 | check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
|
131 | 132 |
|
132 |
| - check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span); |
| 133 | + check_predicates(infcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span); |
133 | 134 | }
|
134 | 135 | }
|
135 | 136 |
|
@@ -282,14 +283,17 @@ fn check_static_lifetimes<'tcx>(
|
282 | 283 | /// * on the base `impl impl2`
|
283 | 284 | /// * Currently this check is done using syntactic equality, which is
|
284 | 285 | /// conservative but generally sufficient.
|
| 286 | +/// * a well-formed predicate of a type argument of the trait being implemented, |
| 287 | +/// including the `Self`-type. |
285 | 288 | fn check_predicates<'tcx>(
|
286 |
| - tcx: TyCtxt<'tcx>, |
| 289 | + infcx: &InferCtxt<'_, 'tcx>, |
287 | 290 | impl1_def_id: DefId,
|
288 | 291 | impl1_substs: SubstsRef<'tcx>,
|
289 | 292 | impl2_node: Node,
|
290 | 293 | impl2_substs: SubstsRef<'tcx>,
|
291 | 294 | span: Span,
|
292 | 295 | ) {
|
| 296 | + let tcx = infcx.tcx; |
293 | 297 | let impl1_predicates = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);
|
294 | 298 | let mut impl2_predicates = if impl2_node.is_from_trait() {
|
295 | 299 | // Always applicable traits have to be always applicable without any
|
@@ -329,6 +333,21 @@ fn check_predicates<'tcx>(
|
329 | 333 | })
|
330 | 334 | .copied()
|
331 | 335 | .collect();
|
| 336 | + |
| 337 | + // Include the well-formed predicates of the type parameters of the impl. |
| 338 | + for ty in tcx.impl_trait_ref(impl1_def_id).unwrap().substs.types() { |
| 339 | + if let Some(obligations) = wf::obligations( |
| 340 | + infcx, |
| 341 | + tcx.param_env(impl1_def_id), |
| 342 | + tcx.hir().as_local_hir_id(impl1_def_id).unwrap(), |
| 343 | + ty, |
| 344 | + span, |
| 345 | + ) { |
| 346 | + impl2_predicates |
| 347 | + .predicates |
| 348 | + .extend(obligations.into_iter().map(|obligation| obligation.predicate)) |
| 349 | + } |
| 350 | + } |
332 | 351 | impl2_predicates.predicates.extend(traits::elaborate_predicates(tcx, always_applicable_traits));
|
333 | 352 |
|
334 | 353 | for predicate in impl1_predicates.predicates {
|
|
0 commit comments