Make RPIT and TAIT work exactly the same
This commit is contained in:
parent
493c960a3e
commit
524d2b3178
57 changed files with 359 additions and 221 deletions
|
@ -38,6 +38,15 @@ pub struct OpaqueTypeDecl<'tcx> {
|
|||
pub origin: hir::OpaqueTyOrigin,
|
||||
}
|
||||
|
||||
pub enum ReplaceOpaqueTypes {
|
||||
/// Closures can't create hidden types for opaque types of their parent, as they
|
||||
/// do not have all the outlives information available. Also `type_of` looks for
|
||||
/// hidden types in the owner (so the closure's parent), so it would not find these
|
||||
/// definitions.
|
||||
OnlyForRPIT,
|
||||
All,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn replace_opaque_types_with_inference_vars(
|
||||
&self,
|
||||
|
@ -46,27 +55,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
span: Span,
|
||||
code: ObligationCauseCode<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
replace: ReplaceOpaqueTypes,
|
||||
) -> InferOk<'tcx, Ty<'tcx>> {
|
||||
if !ty.has_opaque_types() {
|
||||
return InferOk { value: ty, obligations: vec![] };
|
||||
}
|
||||
let mut obligations = vec![];
|
||||
let replace_opaque_type = |def_id| match self.opaque_type_origin(def_id, span) {
|
||||
None => false,
|
||||
Some(OpaqueTyOrigin::FnReturn(..)) => true,
|
||||
// Not using `==` or `matches!` here to make sure we exhaustively match variants.
|
||||
Some(_) => match replace {
|
||||
ReplaceOpaqueTypes::OnlyForRPIT => false,
|
||||
ReplaceOpaqueTypes::All => true,
|
||||
},
|
||||
};
|
||||
let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
|
||||
tcx: self.tcx,
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
ty_op: |ty| match *ty.kind() {
|
||||
// Closures can't create hidden types for opaque types of their parent, as they
|
||||
// do not have all the outlives information available. Also `type_of` looks for
|
||||
// hidden types in the owner (so the closure's parent), so it would not find these
|
||||
// definitions.
|
||||
ty::Opaque(def_id, _substs)
|
||||
if matches!(
|
||||
self.opaque_type_origin(def_id, span),
|
||||
Some(OpaqueTyOrigin::FnReturn(..))
|
||||
) =>
|
||||
{
|
||||
let span = if span.is_dummy() { self.tcx.def_span(def_id) } else { span };
|
||||
ty::Opaque(def_id, _substs) if replace_opaque_type(def_id) => {
|
||||
let def_span = self.tcx.def_span(def_id);
|
||||
let span = if span.contains(def_span) { def_span } else { span };
|
||||
let cause = ObligationCause::new(span, body_id, code.clone());
|
||||
// FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind
|
||||
// for opaque types, and then use that kind to fix the spans for type errors
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue