From ce32daa6b7f14084cb29466b985128c8938f942a Mon Sep 17 00:00:00 2001
From: Jeffrey Seyfried <jeffrey.seyfried@gmail.com>
Date: Thu, 16 Mar 2017 20:39:41 +0000
Subject: [PATCH 1/6] Fix regression when `include!()`ing a `macro_rules!`
 containing a `$crate::` path.

---
 src/librustc_resolve/build_reduced_graph.rs |  5 ++++-
 src/test/run-pass/auxiliary/issue_40469.rs  | 11 +++++++++++
 src/test/run-pass/issue-40469.rs            | 18 ++++++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 src/test/run-pass/auxiliary/issue_40469.rs
 create mode 100644 src/test/run-pass/issue-40469.rs

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 03c61067d64c2..be905a9d0f94a 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -23,7 +23,7 @@ use {resolve_error, resolve_struct_error, ResolutionError};
 
 use rustc::middle::cstore::LoadedMacro;
 use rustc::hir::def::*;
-use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
+use rustc::hir::def_id::{CrateNum, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefId};
 use rustc::ty;
 
 use std::cell::Cell;
@@ -496,6 +496,9 @@ impl<'a> Resolver<'a> {
         let def_id = self.macro_defs[&expansion];
         if let Some(id) = self.definitions.as_local_node_id(def_id) {
             self.local_macro_def_scopes[&id]
+        } else if def_id.krate == BUILTIN_MACROS_CRATE {
+            // FIXME(jseyfried): This happens when `include!()`ing a `$crate::` path, c.f, #40469.
+            self.graph_root
         } else {
             let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
             self.get_extern_crate_root(module_def_id.krate)
diff --git a/src/test/run-pass/auxiliary/issue_40469.rs b/src/test/run-pass/auxiliary/issue_40469.rs
new file mode 100644
index 0000000000000..4970bba431a84
--- /dev/null
+++ b/src/test/run-pass/auxiliary/issue_40469.rs
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! m { () => { $crate::main(); } }
diff --git a/src/test/run-pass/issue-40469.rs b/src/test/run-pass/issue-40469.rs
new file mode 100644
index 0000000000000..30055e532cd45
--- /dev/null
+++ b/src/test/run-pass/issue-40469.rs
@@ -0,0 +1,18 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty issue #37195
+
+#![allow(dead_code)]
+
+include!("auxiliary/issue_40469.rs");
+fn f() { m!(); }
+
+fn main() {}

From 41f6bad85562abe2200c9918ff807b6bbdacc78d Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Thu, 9 Mar 2017 21:05:56 +0200
Subject: [PATCH 2/6] Rename expected_types_for_fn_args to
 expected_inputs_for_expected_output.

---
 src/librustc_typeck/check/callee.rs |  4 ++--
 src/librustc_typeck/check/mod.rs    | 20 ++++++++++----------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 4b88f5acf42da..529ee107c46ce 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -254,7 +254,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         // Call the generic checker.
         let expected_arg_tys =
-            self.expected_types_for_fn_args(call_expr.span,
+            self.expected_inputs_for_expected_output(call_expr.span,
                                             expected,
                                             fn_sig.output(),
                                             fn_sig.inputs());
@@ -280,7 +280,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // do know the types expected for each argument and the return
         // type.
 
-        let expected_arg_tys = self.expected_types_for_fn_args(call_expr.span,
+        let expected_arg_tys = self.expected_inputs_for_expected_output(call_expr.span,
                                                                expected,
                                                                fn_sig.output().clone(),
                                                                fn_sig.inputs());
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 5a582a523ea1c..95d0ee51d3443 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2292,7 +2292,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             match method_fn_ty.sty {
                 ty::TyFnDef(def_id, .., ref fty) => {
                     // HACK(eddyb) ignore self in the definition (see above).
-                    let expected_arg_tys = self.expected_types_for_fn_args(
+                    let expected_arg_tys = self.expected_inputs_for_expected_output(
                         sp,
                         expected,
                         fty.0.output(),
@@ -2645,14 +2645,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         TypeAndSubsts { substs: substs, ty: substd_ty }
     }
 
-    /// Unifies the return type with the expected type early, for more coercions
-    /// and forward type information on the argument expressions.
-    fn expected_types_for_fn_args(&self,
-                                  call_span: Span,
-                                  expected_ret: Expectation<'tcx>,
-                                  formal_ret: Ty<'tcx>,
-                                  formal_args: &[Ty<'tcx>])
-                                  -> Vec<Ty<'tcx>> {
+    /// Unifies the output type with the expected type early, for more coercions
+    /// and forward type information on the input expressions.
+    fn expected_inputs_for_expected_output(&self,
+                                           call_span: Span,
+                                           expected_ret: Expectation<'tcx>,
+                                           formal_ret: Ty<'tcx>,
+                                           formal_args: &[Ty<'tcx>])
+                                           -> Vec<Ty<'tcx>> {
         let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
             self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
                 // Attempt to apply a subtyping relationship between the formal
@@ -2675,7 +2675,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }).collect())
             }).ok()
         }).unwrap_or(vec![]);
-        debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
+        debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
                formal_args, formal_ret,
                expected_args, expected_ret);
         expected_args

From 52e7c9c29e029cf53ea92234121101cb3baabdb7 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Thu, 9 Mar 2017 21:06:18 +0200
Subject: [PATCH 3/6] Propagate expected type hints through struct literals.

---
 src/librustc_typeck/check/mod.rs | 29 +++++++++++++++++++++--------
 src/test/run-pass/issue-31260.rs | 20 ++++++++++++++++++++
 2 files changed, 41 insertions(+), 8 deletions(-)
 create mode 100644 src/test/run-pass/issue-31260.rs

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 95d0ee51d3443..f36254a8a10ea 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3032,14 +3032,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
     fn check_expr_struct_fields(&self,
                                 adt_ty: Ty<'tcx>,
+                                expected: Expectation<'tcx>,
                                 expr_id: ast::NodeId,
                                 span: Span,
                                 variant: &'tcx ty::VariantDef,
                                 ast_fields: &'gcx [hir::Field],
                                 check_completeness: bool) {
         let tcx = self.tcx;
-        let (substs, adt_kind, kind_name) = match adt_ty.sty {
-            ty::TyAdt(adt, substs) => (substs, adt.adt_kind(), adt.variant_descr()),
+
+        let adt_ty_hint =
+            self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
+                .get(0).cloned().unwrap_or(adt_ty);
+
+        let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
+            (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
+                (substs, hint_substs, adt.adt_kind(), adt.variant_descr())
+            }
             _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
         };
 
@@ -3054,10 +3062,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         // Typecheck each field.
         for field in ast_fields {
-            let expected_field_type;
+            let final_field_type;
+            let field_type_hint;
 
             if let Some(v_field) = remaining_fields.remove(&field.name.node) {
-                expected_field_type = self.field_ty(field.span, v_field, substs);
+                final_field_type = self.field_ty(field.span, v_field, substs);
+                field_type_hint = self.field_ty(field.span, v_field, hint_substs);
 
                 seen_fields.insert(field.name.node, field.span);
 
@@ -3069,7 +3079,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }
             } else {
                 error_happened = true;
-                expected_field_type = tcx.types.err;
+                final_field_type = tcx.types.err;
+                field_type_hint = tcx.types.err;
                 if let Some(_) = variant.find_field_named(field.name.node) {
                     let mut err = struct_span_err!(self.tcx.sess,
                                                 field.name.span,
@@ -3091,7 +3102,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
             // Make sure to give a type to the field even if there's
             // an error, so we can continue typechecking
-            self.check_expr_coercable_to_type(&field.expr, expected_field_type);
+            let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
+            self.demand_coerce(&field.expr, ty, final_field_type);
         }
 
         // Make sure the programmer specified correct number of fields.
@@ -3201,6 +3213,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
     fn check_expr_struct(&self,
                          expr: &hir::Expr,
+                         expected: Expectation<'tcx>,
                          qpath: &hir::QPath,
                          fields: &'gcx [hir::Field],
                          base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
@@ -3219,7 +3232,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             hir::QPath::TypeRelative(ref qself, _) => qself.span
         };
 
-        self.check_expr_struct_fields(struct_ty, expr.id, path_span, variant, fields,
+        self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
                                       base_expr.is_none());
         if let &Some(ref base_expr) = base_expr {
             self.check_expr_has_type(base_expr, struct_ty);
@@ -3764,7 +3777,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             }
           }
           hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
-            self.check_expr_struct(expr, qpath, fields, base_expr)
+            self.check_expr_struct(expr, expected, qpath, fields, base_expr)
           }
           hir::ExprField(ref base, ref field) => {
             self.check_field(expr, lvalue_pref, &base, field)
diff --git a/src/test/run-pass/issue-31260.rs b/src/test/run-pass/issue-31260.rs
new file mode 100644
index 0000000000000..e771fc7464d00
--- /dev/null
+++ b/src/test/run-pass/issue-31260.rs
@@ -0,0 +1,20 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Struct<K: 'static> {
+    pub field: K,
+}
+
+// Partial fix for #31260, doesn't work without {...}.
+static STRUCT: Struct<&'static [u8]> = Struct {
+    field: {&[1]}
+};
+
+fn main() {}

From 4d605c0c013b443e8d6254bee8abc5659e63cc1f Mon Sep 17 00:00:00 2001
From: Austin Bonander <austin.bonander@gmail.com>
Date: Wed, 15 Mar 2017 01:27:43 -0700
Subject: [PATCH 4/6] Correctly get source for metadata crate type; replace
 `unwrap()` with `expect()`

---
 src/librustc_metadata/creader.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 49dcffb4830a1..e9b97e63399ed 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -236,7 +236,8 @@ impl<'a> CrateLoader<'a> {
             // path (this is a top-level dependency) as we don't want to
             // implicitly load anything inside the dependency lookup path.
             let prev_kind = source.dylib.as_ref().or(source.rlib.as_ref())
-                                  .unwrap().1;
+                                  .or(source.rmeta.as_ref())
+                                  .expect("No sources for crate").1;
             if ret.is_none() && (prev_kind == kind || prev_kind == PathKind::All) {
                 ret = Some(cnum);
             }

From 1dc25bdb8bb925e8f18ec865b9aafce82993227c Mon Sep 17 00:00:00 2001
From: Austin Bonander <austin.bonander@gmail.com>
Date: Thu, 16 Mar 2017 14:41:08 -0700
Subject: [PATCH 5/6] Regression test for rust-lang/rust#40535

---
 src/test/run-make/issue-40535/Makefile | 11 +++++++++++
 src/test/run-make/issue-40535/bar.rs   | 13 +++++++++++++
 src/test/run-make/issue-40535/baz.rs   | 11 +++++++++++
 src/test/run-make/issue-40535/foo.rs   | 14 ++++++++++++++
 4 files changed, 49 insertions(+)
 create mode 100644 src/test/run-make/issue-40535/Makefile
 create mode 100644 src/test/run-make/issue-40535/bar.rs
 create mode 100644 src/test/run-make/issue-40535/baz.rs
 create mode 100644 src/test/run-make/issue-40535/foo.rs

diff --git a/src/test/run-make/issue-40535/Makefile b/src/test/run-make/issue-40535/Makefile
new file mode 100644
index 0000000000000..7d513a86a7fa5
--- /dev/null
+++ b/src/test/run-make/issue-40535/Makefile
@@ -0,0 +1,11 @@
+# The ICE occurred in the following situation:
+# * `foo` declares `extern crate bar, baz`, depends only on `bar` (forgetting `baz` in `Cargo.toml`)
+# * `bar` declares and depends on `extern crate baz`
+# * All crates built in metadata-only mode (`cargo check`)
+all:
+	# cc https://github.com/rust-lang/rust/issues/40623
+	$(RUSTC) baz.rs --emit=metadata --out-dir=$(TMPDIR)
+	$(RUSTC) bar.rs --emit=metadata --extern baz=$(TMPDIR)/libbaz.rmeta --out-dir=$(TMPDIR)
+	$(RUSTC) foo.rs --emit=metadata --extern bar=$(TMPDIR)/libbar.rmeta --out-dir=$(TMPDIR) 2>&1 | \
+	grep -vq "unexpectedly panicked"
+	# ^ Succeeds if it doesn't find the ICE message
diff --git a/src/test/run-make/issue-40535/bar.rs b/src/test/run-make/issue-40535/bar.rs
new file mode 100644
index 0000000000000..4c22f181975b8
--- /dev/null
+++ b/src/test/run-make/issue-40535/bar.rs
@@ -0,0 +1,13 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+
+extern crate baz;
diff --git a/src/test/run-make/issue-40535/baz.rs b/src/test/run-make/issue-40535/baz.rs
new file mode 100644
index 0000000000000..737a918a0398d
--- /dev/null
+++ b/src/test/run-make/issue-40535/baz.rs
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
diff --git a/src/test/run-make/issue-40535/foo.rs b/src/test/run-make/issue-40535/foo.rs
new file mode 100644
index 0000000000000..53a8c8636b148
--- /dev/null
+++ b/src/test/run-make/issue-40535/foo.rs
@@ -0,0 +1,14 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+
+extern crate bar;
+extern crate baz;

From 3808ae855b9a55d88e3f23f5a63e807c4df3a373 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Mon, 20 Mar 2017 07:53:15 -0700
Subject: [PATCH 6/6] Bump beta to .2

---
 src/bootstrap/channel.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs
index 2607ce412f108..cb6e1c2b57e7e 100644
--- a/src/bootstrap/channel.rs
+++ b/src/bootstrap/channel.rs
@@ -28,7 +28,7 @@ pub const CFG_RELEASE_NUM: &'static str = "1.17.0";
 // An optional number to put after the label, e.g. '.2' -> '-beta.2'
 // Be sure to make this starts with a dot to conform to semver pre-release
 // versions (section 9)
-pub const CFG_PRERELEASE_VERSION: &'static str = ".1";
+pub const CFG_PRERELEASE_VERSION: &'static str = ".2";
 
 pub struct GitInfo {
     inner: Option<Info>,