about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2019-06-16 17:23:41 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-06-18 17:02:26 +0300
commitdedf2eda8f6d062da91c80a8980b3b794f5c876e (patch)
tree98f3e4cce19fb170c17f0a90706472359210561e /src
parent374c63e0fc356eb61b1966cb6026a2a49fe9226d (diff)
downloadrust-dedf2eda8f6d062da91c80a8980b3b794f5c876e.tar.gz
rust-dedf2eda8f6d062da91c80a8980b3b794f5c876e.zip
rustc_typeck: correctly compute `Substs` for `Res::SelfCtor`.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/mod.rs96
-rw-r--r--src/test/ui/issues/issue-57924.rs (renamed from src/test/run-pass/issues/issue-57924.rs)1
-rw-r--r--src/test/ui/issues/issue-57924.stderr9
-rw-r--r--src/test/ui/issues/issue-61882-2.rs11
-rw-r--r--src/test/ui/issues/issue-61882-2.stderr15
-rw-r--r--src/test/ui/issues/issue-61882.rs9
-rw-r--r--src/test/ui/issues/issue-61882.stderr21
7 files changed, 109 insertions, 53 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 22f17097fcb..a5d9284a6fe 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5300,52 +5300,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Some(original_span.with_lo(original_span.hi() - BytePos(1)))
     }
 
-    // Rewrite `SelfCtor` to `Ctor`
-    pub fn rewrite_self_ctor(
-        &self,
-        res: Res,
-        span: Span,
-    ) -> Result<Res, ErrorReported> {
-        let tcx = self.tcx;
-        if let Res::SelfCtor(impl_def_id) = res {
-            let ty = self.impl_self_ty(span, impl_def_id).ty;
-            let adt_def = ty.ty_adt_def();
-
-            match adt_def {
-                Some(adt_def) if adt_def.has_ctor() => {
-                    let variant = adt_def.non_enum_variant();
-                    let ctor_def_id = variant.ctor_def_id.unwrap();
-                    Ok(Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id))
-                }
-                _ => {
-                    let mut err = tcx.sess.struct_span_err(span,
-                        "the `Self` constructor can only be used with tuple or unit structs");
-                    if let Some(adt_def) = adt_def {
-                        match adt_def.adt_kind() {
-                            AdtKind::Enum => {
-                                err.help("did you mean to use one of the enum's variants?");
-                            },
-                            AdtKind::Struct |
-                            AdtKind::Union => {
-                                err.span_suggestion(
-                                    span,
-                                    "use curly brackets",
-                                    String::from("Self { /* fields */ }"),
-                                    Applicability::HasPlaceholders,
-                                );
-                            }
-                        }
-                    }
-                    err.emit();
-
-                    Err(ErrorReported)
-                }
-            }
-        } else {
-            Ok(res)
-        }
-    }
-
     // Instantiates the given path, which must refer to an item with the given
     // number of type parameters and type.
     pub fn instantiate_value_path(&self,
@@ -5365,12 +5319,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let tcx = self.tcx;
 
-        let res = match self.rewrite_self_ctor(res, span) {
-            Ok(res) => res,
-            Err(ErrorReported) => return (tcx.types.err, res),
-        };
         let path_segs = match res {
-            Res::Local(_) => vec![],
+            Res::Local(_) | Res::SelfCtor(_) => vec![],
             Res::Def(kind, def_id) =>
                 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
             _ => bug!("instantiate_value_path on {:?}", res),
@@ -5475,13 +5425,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             tcx.generics_of(*def_id).has_self
         }).unwrap_or(false);
 
+        let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
+            let ty = self.impl_self_ty(span, impl_def_id).ty;
+            let adt_def = ty.ty_adt_def();
+
+            match ty.sty {
+                ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
+                    let variant = adt_def.non_enum_variant();
+                    let ctor_def_id = variant.ctor_def_id.unwrap();
+                    (
+                        Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
+                        Some(substs),
+                    )
+                }
+                _ => {
+                    let mut err = tcx.sess.struct_span_err(span,
+                        "the `Self` constructor can only be used with tuple or unit structs");
+                    if let Some(adt_def) = adt_def {
+                        match adt_def.adt_kind() {
+                            AdtKind::Enum => {
+                                err.help("did you mean to use one of the enum's variants?");
+                            },
+                            AdtKind::Struct |
+                            AdtKind::Union => {
+                                err.span_suggestion(
+                                    span,
+                                    "use curly brackets",
+                                    String::from("Self { /* fields */ }"),
+                                    Applicability::HasPlaceholders,
+                                );
+                            }
+                        }
+                    }
+                    err.emit();
+
+                    return (tcx.types.err, res)
+                }
+            }
+        } else {
+            (res, None)
+        };
         let def_id = res.def_id();
 
         // The things we are substituting into the type should not contain
         // escaping late-bound regions, and nor should the base type scheme.
         let ty = tcx.type_of(def_id);
 
-        let substs = AstConv::create_substs_for_generic_args(
+        let substs = self_ctor_substs.unwrap_or_else(|| AstConv::create_substs_for_generic_args(
             tcx,
             def_id,
             &[][..],
@@ -5551,7 +5541,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                 }
             },
-        );
+        ));
         assert!(!substs.has_escaping_bound_vars());
         assert!(!ty.has_escaping_bound_vars());
 
diff --git a/src/test/run-pass/issues/issue-57924.rs b/src/test/ui/issues/issue-57924.rs
index 232596334b0..dc2942225e3 100644
--- a/src/test/run-pass/issues/issue-57924.rs
+++ b/src/test/ui/issues/issue-57924.rs
@@ -3,6 +3,7 @@ pub struct Gcm<E>(E);
 impl<E> Gcm<E> {
     pub fn crash(e: E) -> Self {
         Self::<E>(e)
+        //~^ ERROR type arguments are not allowed for this type
     }
 }
 
diff --git a/src/test/ui/issues/issue-57924.stderr b/src/test/ui/issues/issue-57924.stderr
new file mode 100644
index 00000000000..2f184b1aae1
--- /dev/null
+++ b/src/test/ui/issues/issue-57924.stderr
@@ -0,0 +1,9 @@
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/issue-57924.rs:5:16
+   |
+LL |         Self::<E>(e)
+   |                ^ type argument not allowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/issues/issue-61882-2.rs b/src/test/ui/issues/issue-61882-2.rs
new file mode 100644
index 00000000000..1209b54bc41
--- /dev/null
+++ b/src/test/ui/issues/issue-61882-2.rs
@@ -0,0 +1,11 @@
+struct A<T>(T);
+
+impl A<&'static u8> {
+    fn f() {
+        let x = 0;
+        Self(&x);
+        //~^ ERROR `x` does not live long enough
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-61882-2.stderr b/src/test/ui/issues/issue-61882-2.stderr
new file mode 100644
index 00000000000..03a65540ced
--- /dev/null
+++ b/src/test/ui/issues/issue-61882-2.stderr
@@ -0,0 +1,15 @@
+error[E0597]: `x` does not live long enough
+  --> $DIR/issue-61882-2.rs:6:14
+   |
+LL |         Self(&x);
+   |              ^^
+   |              |
+   |              borrowed value does not live long enough
+   |              requires that `x` is borrowed for `'static`
+LL |
+LL |     }
+   |     - `x` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/issues/issue-61882.rs b/src/test/ui/issues/issue-61882.rs
new file mode 100644
index 00000000000..013398b4598
--- /dev/null
+++ b/src/test/ui/issues/issue-61882.rs
@@ -0,0 +1,9 @@
+struct A<T>(T);
+
+impl A<bool> {
+    const B: A<u8> = Self(0);
+    //~^ ERROR mismatched types
+    //~| ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-61882.stderr b/src/test/ui/issues/issue-61882.stderr
new file mode 100644
index 00000000000..a14e1a4dd4d
--- /dev/null
+++ b/src/test/ui/issues/issue-61882.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-61882.rs:4:27
+   |
+LL |     const B: A<u8> = Self(0);
+   |                           ^ expected bool, found integer
+   |
+   = note: expected type `bool`
+              found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-61882.rs:4:22
+   |
+LL |     const B: A<u8> = Self(0);
+   |                      ^^^^^^^ expected u8, found bool
+   |
+   = note: expected type `A<u8>`
+              found type `A<bool>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.