]> git.lizzy.rs Git - rust.git/commitdiff
More documentation
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Tue, 17 Jul 2018 09:20:50 +0000 (11:20 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Wed, 18 Jul 2018 08:53:09 +0000 (10:53 +0200)
src/librustc/infer/anon_types/mod.rs
src/librustc/ty/mod.rs
src/librustc_typeck/check/wfcheck.rs

index 5e731871e2851e1497dc6c58d56355335ff52e78..8cc8abda70800ae54b48a71147ee1ffb1e318937 100644 (file)
@@ -808,6 +808,23 @@ fn fold_anon_ty(
 }
 
 /// 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,
index 2e221424e3ce08a58e00bb92938d4c702ee14c79..7ae6f81264981654fb25494531de5a3c3c3b2fa5 100644 (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) {
index d2c96221991600637b337d26bfd21afd85cc1eda..cd6a1e3fdba22f7df7616a1020db974698cac4b3 100644 (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>,