Skip to content

Commit e6dc882

Browse files
committed
check wf before normalization
1 parent e8cde83 commit e6dc882

File tree

1 file changed

+24
-33
lines changed

1 file changed

+24
-33
lines changed

compiler/rustc_traits/src/type_op.rs

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
101101
));
102102
}
103103

104+
fn prove_wf(&self, arg: ty::GenericArg<'tcx>) {
105+
self.prove_predicate(
106+
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx()),
107+
ObligationCause::dummy_with_span(self.span),
108+
);
109+
}
110+
104111
fn tcx(&self) -> TyCtxt<'tcx> {
105112
self.ocx.infcx.tcx
106113
}
@@ -111,16 +118,8 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
111118
mir_ty: Ty<'tcx>,
112119
user_ty: Ty<'tcx>,
113120
) -> Result<(), NoSolution> {
114-
let user_ty = self.normalize(user_ty);
115-
self.eq(mir_ty, user_ty)?;
116-
117-
// FIXME(#xxxx): We should check well-formedness before normalization.
118-
self.prove_predicate(
119-
ty::Binder::dummy(ty::PredicateKind::WellFormed(user_ty.into()))
120-
.to_predicate(self.tcx()),
121-
ObligationCause::dummy_with_span(self.span),
122-
);
123-
121+
self.prove_wf(user_ty.into());
122+
self.eq(mir_ty, self.normalize(user_ty))?;
124123
Ok(())
125124
}
126125

@@ -147,8 +146,6 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
147146
// outlives" error messages.
148147
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
149148

150-
let cause = ObligationCause::dummy_with_span(self.span);
151-
152149
debug!(?instantiated_predicates);
153150
for (instantiated_predicate, predicate_span) in
154151
zip(instantiated_predicates.predicates, instantiated_predicates.spans)
@@ -164,35 +161,29 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
164161
self.prove_predicate(instantiated_predicate, cause);
165162
}
166163

164+
// Now prove the well-formedness of `def_id` with `substs`.
165+
// Note for some items, proving the WF of `ty` is not sufficient because the
166+
// well-formedness of an item may depend on the WF of gneneric args not present in the
167+
// item's type. Currently this is true for associated consts, e.g.:
168+
// ```rust
169+
// impl<T> MyTy<T> {
170+
// const CONST: () = { /* arbitrary code that depends on T being WF */ };
171+
// }
172+
// ```
173+
for arg in substs {
174+
self.prove_wf(arg);
175+
}
176+
167177
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
178+
self.prove_wf(self_ty.into());
179+
168180
let self_ty = self.normalize(self_ty);
169181
let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs);
170182
let impl_self_ty = self.normalize(impl_self_ty);
171183

172184
self.eq(self_ty, impl_self_ty)?;
173-
174-
self.prove_predicate(
175-
ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into()))
176-
.to_predicate(tcx),
177-
cause.clone(),
178-
);
179185
}
180186

181-
// In addition to proving the predicates, we have to
182-
// prove that `ty` is well-formed -- this is because
183-
// the WF of `ty` is predicated on the substs being
184-
// well-formed, and we haven't proven *that*. We don't
185-
// want to prove the WF of types from `substs` directly because they
186-
// haven't been normalized.
187-
//
188-
// FIXME(nmatsakis): Well, perhaps we should normalize
189-
// them? This would only be relevant if some input
190-
// type were ill-formed but did not appear in `ty`,
191-
// which...could happen with normalization...
192-
self.prove_predicate(
193-
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(tcx),
194-
cause,
195-
);
196187
Ok(())
197188
}
198189
}

0 commit comments

Comments
 (0)