about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-12-20 16:48:41 -0500
committerNiko Matsakis <niko@alum.mit.edu>2017-12-20 16:48:41 -0500
commit4f549fe4fe4cef6d97982dbc891969285e436e73 (patch)
tree420ef20f8bc28af7e7ccbfb4bd59a81cd93bffa2
parent3f490ca4bdb151b7b72bf6647d0bc4de5951667c (diff)
downloadrust-4f549fe4fe4cef6d97982dbc891969285e436e73.tar.gz
rust-4f549fe4fe4cef6d97982dbc891969285e436e73.zip
improve comment about instantiating anon types
-rw-r--r--src/librustc/infer/anon_types/mod.rs40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs
index a3d236ac1b6..be5314a2c17 100644
--- a/src/librustc/infer/anon_types/mod.rs
+++ b/src/librustc/infer/anon_types/mod.rs
@@ -509,12 +509,40 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
             tcx,
             fldop: |ty| {
                 if let ty::TyAnon(def_id, substs) = ty.sty {
-                    // Check that this is `impl Trait` type is declared by
-                    // `parent_def_id`. During the first phase of type-check, this
-                    // is true, but during NLL type-check, we sometimes encounter
-                    // `impl Trait` types in e.g. inferred closure signatures that
-                    // are not 'local' to the current function and hence which
-                    // ought not to be instantiated.
+                    // Check that this is `impl Trait` type is
+                    // declared by `parent_def_id` -- i.e., one whose
+                    // value we are inferring.  At present, this is
+                    // always true during the first phase of
+                    // type-check, but not always true later on during
+                    // NLL. Once we support named abstract types more fully,
+                    // this same scenario will be able to arise during all phases.
+                    //
+                    // Here is an example using `abstract type` that indicates
+                    // the distinction we are checking for:
+                    //
+                    // ```rust
+                    // mod a {
+                    //   pub abstract type Foo: Iterator;
+                    //   pub fn make_foo() -> Foo { .. }
+                    // }
+                    //
+                    // mod b {
+                    //   fn foo() -> a::Foo { a::make_foo() }
+                    // }
+                    // ```
+                    //
+                    // Here, the return type of `foo` references a
+                    // `TyAnon` indeed, but not one whose value is
+                    // presently being inferred. You can get into a
+                    // similar situation with closure return types
+                    // today:
+                    //
+                    // ```rust
+                    // fn foo() -> impl Iterator { .. }
+                    // fn bar() {
+                    //     let x = || foo(); // returns the Anon assoc with `foo`
+                    // }
+                    // ```
                     if let Some(anon_node_id) = tcx.hir.as_local_node_id(def_id) {
                         let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
                         let anon_parent_def_id = tcx.hir.local_def_id(anon_parent_node_id);