1
Fork 0

More documentation

This commit is contained in:
Oliver Schneider 2018-07-17 11:20:50 +02:00
parent 0f05b4be82
commit 41b0315f31
3 changed files with 38 additions and 1 deletions

View file

@ -808,6 +808,23 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
}
/// Whether `anon_node_id` is a sibling or a child of a sibling of `def_id`
///
/// ```rust
/// pub mod foo {
/// pub mod bar {
/// pub existential type Baz;
///
/// fn f1() -> Baz { .. }
/// }
///
/// fn f2() -> bar::Baz { .. }
/// }
/// ```
///
/// Here, `def_id` will be the `DefId` of the existential type `Baz`.
/// `anon_node_id` is the `NodeId` of the reference to Baz -- so either the return type of f1 or f2.
/// We will return true if the reference is within the same module as the existential type
/// So true for f1, false for f2.
pub fn may_define_existential_type(
tcx: TyCtxt,
def_id: DefId,

View file

@ -2861,7 +2861,7 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> ParamEnv<'tcx> {
// The param_env of an existential type is its parent's param_env
// 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) {

View file

@ -535,6 +535,26 @@ fn check_fn_or_method<'a, 'fcx, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
check_where_clauses(tcx, fcx, span, def_id, Some(sig.output()));
}
/// Checks "defining uses" of existential types to ensure that they meet the restrictions laid for
/// "higher-order pattern unification".
/// This ensures that inference is tractable.
/// In particular, definitions of existential types can only use other generics as arguments,
/// and they cannot repeat an argument. Example:
///
/// ```rust
/// existential type Foo<A, B>;
///
/// // ok -- `Foo` is applied to two distinct, generic types.
/// fn a<T, U>() -> Foo<T, U> { .. }
///
/// // not ok -- `Foo` is applied to `T` twice.
/// fn b<T>() -> Foo<T, T> { .. }
///
///
/// // not ok -- `Foo` is applied to a non-generic type.
/// fn b<T>() -> Foo<T, u32> { .. }
/// ```
///
fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'gcx>,
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,