Prepare for using wfcheck on existential types
This commit is contained in:
parent
feb139f53f
commit
fdd719aa3d
6 changed files with 54 additions and 36 deletions
|
|
@ -2856,22 +2856,26 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
|
|||
})
|
||||
}
|
||||
|
||||
/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition
|
||||
pub fn is_impl_trait_defn(tcx: TyCtxt, def_id: DefId) -> Option<DefId> {
|
||||
if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
|
||||
if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
|
||||
if let hir::ItemKind::Existential(ref exist_ty) = item.node {
|
||||
return exist_ty.impl_trait_fn;
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// See `ParamEnv` struct def'n for details.
|
||||
fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId)
|
||||
-> ParamEnv<'tcx> {
|
||||
|
||||
// The param_env of an impl Trait type is its defining function's param_env
|
||||
if let Some(Def::Existential(_)) = tcx.describe_def(def_id) {
|
||||
if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
|
||||
if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
|
||||
if let hir::ItemKind::Existential(ref exist_ty) = item.node {
|
||||
if let Some(parent) = exist_ty.impl_trait_fn {
|
||||
return param_env(tcx, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(parent) = is_impl_trait_defn(tcx, def_id) {
|
||||
return param_env(tcx, parent);
|
||||
}
|
||||
// Compute the bounds on Self and the type parameters.
|
||||
|
||||
|
|
|
|||
|
|
@ -360,10 +360,16 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||
// types appearing in the fn signature
|
||||
}
|
||||
|
||||
ty::TyAnon(..) => {
|
||||
ty::TyAnon(did, substs) => {
|
||||
// all of the requirements on type parameters
|
||||
// should've been checked by the instantiation
|
||||
// of whatever returned this exact `impl Trait`.
|
||||
|
||||
// for named existential types we still need to check them
|
||||
if super::is_impl_trait_defn(self.infcx.tcx, did).is_none() {
|
||||
let obligations = self.nominal_obligations(did, substs);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
}
|
||||
|
||||
ty::TyDynamic(data, r) => {
|
||||
|
|
|
|||
|
|
@ -1037,15 +1037,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
|||
match path.def {
|
||||
Def::Existential(did) => {
|
||||
// check for desugared impl trait
|
||||
if let Some(node_id) = tcx.hir.as_local_node_id(did) {
|
||||
if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
|
||||
if let hir::ItemKind::Existential(ref exist_ty) = item.node {
|
||||
if exist_ty.impl_trait_fn.is_some() {
|
||||
let lifetimes = &path.segments[0].args.as_ref().unwrap().args;
|
||||
return self.impl_trait_ty_to_ty(did, lifetimes);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ty::is_impl_trait_defn(tcx, did).is_some() {
|
||||
let lifetimes = &path.segments[0].args.as_ref().unwrap().args;
|
||||
return self.impl_trait_ty_to_ty(did, lifetimes);
|
||||
}
|
||||
let item_segment = path.segments.split_last().unwrap();
|
||||
self.prohibit_generics(item_segment.1);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:16:18
|
||||
|
|
||||
LL | let z: i32 = x; //~ ERROR mismatched types
|
||||
| ^ expected i32, found anonymized type
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `WrongGeneric::<&{integer}>`
|
||||
|
||||
warning: not reporting region error due to nll
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:16:1
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:19:1
|
||||
|
|
||||
LL | existential type WrongGeneric<T>: 'static;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:20:5
|
||||
|
|
||||
LL | t
|
||||
| ^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `T: 'static`...
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0310`.
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
|
|
@ -8,10 +8,13 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
#![feature(existential_type)]
|
||||
|
||||
fn main() {}
|
||||
fn main() {
|
||||
let y = 42;
|
||||
let x = wrong_generic(&y);
|
||||
let z: i32 = x; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
existential type WrongGeneric<T>: 'static;
|
||||
//~^ ERROR the parameter type `T` may not live long enough
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:16:18
|
||||
|
|
||||
LL | let z: i32 = x; //~ ERROR mismatched types
|
||||
| ^ expected i32, found anonymized type
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `WrongGeneric::<&{integer}>`
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:16:1
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:19:1
|
||||
|
|
||||
LL | existential type WrongGeneric<T>: 'static;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -8,11 +17,12 @@ LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
|
|||
| - help: consider adding an explicit lifetime bound `T: 'static`...
|
||||
|
|
||||
note: ...so that the type `T` will meet its required lifetime bounds
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:16:1
|
||||
--> $DIR/generic_type_does_not_live_long_enough.rs:19:1
|
||||
|
|
||||
LL | existential type WrongGeneric<T>: 'static;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0310`.
|
||||
Some errors occurred: E0308, E0310.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue