Distinguish RPIT from other impl trait

This commit is contained in:
Matthew Jasper 2019-12-28 15:39:52 +00:00
parent 4af0952961
commit 60970be1fd
4 changed files with 39 additions and 20 deletions

View File

@ -502,6 +502,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// Otherwise, generate the label we'll use in the error message.
hir::OpaqueTyOrigin::TypeAlias => "impl Trait",
hir::OpaqueTyOrigin::FnReturn => "impl Trait",
hir::OpaqueTyOrigin::Misc => "impl Trait",
};
let msg = format!("ambiguous lifetime bound in `{}`", context_name);
let mut err = self.tcx.sess.struct_span_err(span, &msg);

View File

@ -272,7 +272,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ty = self.lower_ty(
t,
if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::OpaqueTy(None)
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
} else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
},
@ -283,7 +283,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ty = self.lower_ty(
t,
if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::OpaqueTy(None)
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
} else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
},
@ -327,8 +327,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
Some(bounds) => {
let ty = hir::OpaqueTy {
generics: self.lower_generics(generics, ImplTraitContext::OpaqueTy(None)),
bounds: self.lower_param_bounds(bounds, ImplTraitContext::OpaqueTy(None)),
generics: self.lower_generics(
generics,
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
),
bounds: self.lower_param_bounds(
bounds,
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
),
impl_trait_fn: None,
origin: hir::OpaqueTyOrigin::TypeAlias,
};

View File

@ -222,7 +222,7 @@ enum ImplTraitContext<'b, 'a> {
/// We optionally store a `DefId` for the parent item here so we can look up necessary
/// information later. It is `None` when no information about the context should be stored
/// (e.g., for consts and statics).
OpaqueTy(Option<DefId> /* fn def-ID */),
OpaqueTy(Option<DefId> /* fn def-ID */, hir::OpaqueTyOrigin),
/// `impl Trait` is not accepted in this position.
Disallowed(ImplTraitPosition),
@ -248,7 +248,7 @@ impl<'a> ImplTraitContext<'_, 'a> {
use self::ImplTraitContext::*;
match self {
Universal(params) => Universal(params),
OpaqueTy(fn_def_id) => OpaqueTy(*fn_def_id),
OpaqueTy(fn_def_id, origin) => OpaqueTy(*fn_def_id, *origin),
Disallowed(pos) => Disallowed(*pos),
}
}
@ -1010,7 +1010,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// so desugar to
//
// fn foo() -> impl Iterator<Item = impl Debug>
ImplTraitContext::OpaqueTy(_) => (true, itctx),
ImplTraitContext::OpaqueTy(..) => (true, itctx),
// We are in the argument position, but within a dyn type:
//
@ -1019,7 +1019,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// so desugar to
//
// fn foo(x: dyn Iterator<Item = impl Debug>)
ImplTraitContext::Universal(_) if self.is_in_dyn_type => (true, itctx),
ImplTraitContext::Universal(..) if self.is_in_dyn_type => (true, itctx),
// In `type Foo = dyn Iterator<Item: Debug>` we desugar to
// `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
@ -1028,7 +1028,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
//
// FIXME: this is only needed until `impl Trait` is allowed in type aliases.
ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => {
(true, ImplTraitContext::OpaqueTy(None))
(true, ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc))
}
// We are in the parameter position, but not within a dyn type:
@ -1269,8 +1269,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TyKind::ImplTrait(def_node_id, ref bounds) => {
let span = t.span;
match itctx {
ImplTraitContext::OpaqueTy(fn_def_id) => {
self.lower_opaque_impl_trait(span, fn_def_id, def_node_id, |this| {
ImplTraitContext::OpaqueTy(fn_def_id, origin) => {
self.lower_opaque_impl_trait(span, fn_def_id, origin, def_node_id, |this| {
this.lower_param_bounds(bounds, itctx)
})
}
@ -1349,6 +1349,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
span: Span,
fn_def_id: Option<DefId>,
origin: hir::OpaqueTyOrigin,
opaque_ty_node_id: NodeId,
lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
) -> hir::TyKind<'hir> {
@ -1390,7 +1391,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
},
bounds: hir_bounds,
impl_trait_fn: fn_def_id,
origin: hir::OpaqueTyOrigin::FnReturn,
origin,
};
trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_index);
@ -1622,7 +1623,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_ty(
t,
if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::OpaqueTy(Some(parent_def_id))
ImplTraitContext::OpaqueTy(Some(parent_def_id), hir::OpaqueTyOrigin::Misc)
} else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
},
@ -1723,9 +1724,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else {
match decl.output {
FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
Some((def_id, _)) if impl_trait_return_allow => hir::FunctionRetTy::Return(
self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(def_id))),
),
Some((def_id, _)) if impl_trait_return_allow => {
hir::FunctionRetTy::Return(self.lower_ty(
ty,
ImplTraitContext::OpaqueTy(Some(def_id), hir::OpaqueTyOrigin::FnReturn),
))
}
_ => hir::FunctionRetTy::Return(
self.lower_ty(ty, ImplTraitContext::disallowed()),
),
@ -1957,7 +1961,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::GenericBound<'hir> {
// Compute the `T` in `Future<Output = T>` from the return type.
let output_ty = match output {
FunctionRetTy::Ty(ty) => self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(fn_def_id))),
FunctionRetTy::Ty(ty) => self.lower_ty(
ty,
ImplTraitContext::OpaqueTy(Some(fn_def_id), hir::OpaqueTyOrigin::FnReturn),
),
FunctionRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
};
@ -2102,9 +2109,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
let kind = hir::GenericParamKind::Type {
default: default
.as_ref()
.map(|x| self.lower_ty(x, ImplTraitContext::OpaqueTy(None))),
default: default.as_ref().map(|x| {
self.lower_ty(
x,
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
)
}),
synthetic: param
.attrs
.iter()

View File

@ -1990,6 +1990,8 @@ pub enum OpaqueTyOrigin {
FnReturn,
/// `async fn`
AsyncFn,
/// Impl trait in bindings, consts, statics, bounds.
Misc,
}
/// The various kinds of types recognized by the compiler.