]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #49771 - tamird:incremental-no-stage-1, r=Mark-Simulacrum
authorbors <bors@rust-lang.org>
Sun, 8 Apr 2018 19:11:47 +0000 (19:11 +0000)
committerbors <bors@rust-lang.org>
Sun, 8 Apr 2018 19:11:47 +0000 (19:11 +0000)
Don't default to stage 1 with incremental

Closes #43177.

r? @Mark-Simulacrum

14 files changed:
src/bootstrap/config.rs
src/librustc/ich/impls_ty.rs
src/librustc/middle/mem_categorization.rs
src/librustc/traits/select.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_typeck/check/wfcheck.rs
src/test/incremental/issue-49595/auxiliary/lit_a.rs [new file with mode: 0644]
src/test/incremental/issue-49595/auxiliary/lit_b.rs [new file with mode: 0644]
src/test/incremental/issue-49595/issue_49595.rs [new file with mode: 0644]
src/test/run-pass/defaults-well-formedness.rs
src/test/ui/issue-48728.rs [new file with mode: 0644]
src/test/ui/issue-48728.stderr [new file with mode: 0644]
src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs [new file with mode: 0644]
src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.stderr [new file with mode: 0644]

index 863abd14935a8f3493b0994ac4314e8bce5cb804..95baf4f8cca45d61e0c9db8b28f73acfd4867d47 100644 (file)
@@ -563,7 +563,7 @@ pub fn parse(args: &[String]) -> Config {
         // default values for all options that we haven't otherwise stored yet.
 
         set(&mut config.initial_rustc, build.rustc.map(PathBuf::from));
-        set(&mut config.initial_rustc, build.cargo.map(PathBuf::from));
+        set(&mut config.initial_cargo, build.cargo.map(PathBuf::from));
 
         let default = false;
         config.llvm_assertions = llvm_assertions.unwrap_or(default);
index f86913490258e51c11d72f1fba3fe1b08836fd68..af4d3429bb1d57699210dd13645a0f07598a0e5c 100644 (file)
@@ -417,7 +417,7 @@ fn hash_stable<W: StableHasherResult>(
             let tcx = tcx.expect("can't hash AllocIds during hir lowering");
             if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) {
                 AllocDiscriminant::Alloc.hash_stable(hcx, hasher);
-                if !hcx.alloc_id_recursion_tracker.insert(*self) {
+                if hcx.alloc_id_recursion_tracker.insert(*self) {
                     tcx
                         .interpret_interner
                         .get_corresponding_static_def_id(*self)
index 6bf0c5d1ba3e39478389c9fa1d60b95fec599f37..5875e5e4097af496036aaa5b221866ffa5fc6e1a 100644 (file)
@@ -503,8 +503,37 @@ pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr))
     }
 
+    /// Returns the type of value that this pattern matches against.
+    /// Some non-obvious cases:
+    ///
+    /// - a `ref x` binding matches against a value of type `T` and gives
+    ///   `x` the type `&T`; we return `T`.
+    /// - a pattern with implicit derefs (thanks to default binding
+    ///   modes #42640) may look like `Some(x)` but in fact have
+    ///   implicit deref patterns attached (e.g., it is really
+    ///   `&Some(x)`). In that case, we return the "outermost" type
+    ///   (e.g., `&Option<T>).
     fn pat_ty(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
+        // Check for implicit `&` types wrapping the pattern; note
+        // that these are never attached to binding patterns, so
+        // actually this is somewhat "disjoint" from the code below
+        // that aims to account for `ref x`.
+        if let Some(vec) = self.tables.pat_adjustments().get(pat.hir_id) {
+            if let Some(first_ty) = vec.first() {
+                debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty);
+                return Ok(first_ty);
+            }
+        }
+
+        self.pat_ty_unadjusted(pat)
+    }
+
+
+    /// Like `pat_ty`, but ignores implicit `&` patterns.
+    fn pat_ty_unadjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
         let base_ty = self.node_ty(pat.hir_id)?;
+        debug!("pat_ty(pat={:?}) base_ty={:?}", pat, base_ty);
+
         // This code detects whether we are looking at a `ref x`,
         // and if so, figures out what the type *being borrowed* is.
         let ret_ty = match pat.node {
@@ -531,8 +560,8 @@ fn pat_ty(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
             }
             _ => base_ty,
         };
-        debug!("pat_ty(pat={:?}) base_ty={:?} ret_ty={:?}",
-               pat, base_ty, ret_ty);
+        debug!("pat_ty(pat={:?}) ret_ty={:?}", pat, ret_ty);
+
         Ok(ret_ty)
     }
 
@@ -1246,7 +1275,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
                      self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len())
                 }
                 Def::StructCtor(_, CtorKind::Fn) => {
-                    match self.pat_ty(&pat)?.sty {
+                    match self.pat_ty_unadjusted(&pat)?.sty {
                         ty::TyAdt(adt_def, _) => {
                             (cmt, adt_def.non_enum_variant().fields.len())
                         }
@@ -1297,7 +1326,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
 
           PatKind::Tuple(ref subpats, ddpos) => {
             // (p1, ..., pN)
-            let expected_len = match self.pat_ty(&pat)?.sty {
+            let expected_len = match self.pat_ty_unadjusted(&pat)?.sty {
                 ty::TyTuple(ref tys) => tys.len(),
                 ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
             };
index b1649686323f8750e09e47f33be76fdf28a7f839..58c591bf9351258885ce10111369a488f963ecb1 100644 (file)
@@ -961,11 +961,21 @@ fn insert_evaluation_cache(&mut self,
         if self.can_use_global_caches(param_env) {
             let mut cache = self.tcx().evaluation_cache.hashmap.borrow_mut();
             if let Some(trait_ref) = self.tcx().lift_to_global(&trait_ref) {
+                debug!(
+                    "insert_evaluation_cache(trait_ref={:?}, candidate={:?}) global",
+                    trait_ref,
+                    result,
+                );
                 cache.insert(trait_ref, WithDepNode::new(dep_node, result));
                 return;
             }
         }
 
+        debug!(
+            "insert_evaluation_cache(trait_ref={:?}, candidate={:?})",
+            trait_ref,
+            result,
+        );
         self.infcx.evaluation_cache.hashmap
                                    .borrow_mut()
                                    .insert(trait_ref, WithDepNode::new(dep_node, result));
@@ -1069,25 +1079,29 @@ fn candidate_from_obligation_no_cache<'o>(&mut self,
                 if self.intercrate_ambiguity_causes.is_some() {
                     debug!("evaluate_stack: intercrate_ambiguity_causes is some");
                     // Heuristics: show the diagnostics when there are no candidates in crate.
-                    let candidate_set = self.assemble_candidates(stack)?;
-                    if !candidate_set.ambiguous && candidate_set.vec.iter().all(|c| {
-                        !self.evaluate_candidate(stack, &c).may_apply()
-                    }) {
-                        let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
-                        let self_ty = trait_ref.self_ty();
-                        let trait_desc = trait_ref.to_string();
-                        let self_desc = if self_ty.has_concrete_skeleton() {
-                            Some(self_ty.to_string())
-                        } else {
-                            None
-                        };
-                        let cause = if let Conflict::Upstream = conflict {
-                            IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc }
-                        } else {
-                            IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
-                        };
-                        debug!("evaluate_stack: pushing cause = {:?}", cause);
-                        self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
+                    if let Ok(candidate_set) = self.assemble_candidates(stack) {
+                        if !candidate_set.ambiguous && candidate_set.vec.iter().all(|c| {
+                            !self.evaluate_candidate(stack, &c).may_apply()
+                        }) {
+                            let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
+                            let self_ty = trait_ref.self_ty();
+                            let trait_desc = trait_ref.to_string();
+                            let self_desc = if self_ty.has_concrete_skeleton() {
+                                Some(self_ty.to_string())
+                            } else {
+                                None
+                            };
+                            let cause = if let Conflict::Upstream = conflict {
+                                IntercrateAmbiguityCause::UpstreamCrateUpdate {
+                                    trait_desc,
+                                    self_desc,
+                                }
+                            } else {
+                                IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
+                            };
+                            debug!("evaluate_stack: pushing cause = {:?}", cause);
+                            self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
+                        }
                     }
                 }
                 return Ok(None);
@@ -1285,12 +1299,22 @@ fn insert_candidate_cache(&mut self,
             let mut cache = tcx.selection_cache.hashmap.borrow_mut();
             if let Some(trait_ref) = tcx.lift_to_global(&trait_ref) {
                 if let Some(candidate) = tcx.lift_to_global(&candidate) {
+                    debug!(
+                        "insert_candidate_cache(trait_ref={:?}, candidate={:?}) global",
+                        trait_ref,
+                        candidate,
+                    );
                     cache.insert(trait_ref, WithDepNode::new(dep_node, candidate));
                     return;
                 }
             }
         }
 
+        debug!(
+            "insert_candidate_cache(trait_ref={:?}, candidate={:?}) local",
+            trait_ref,
+            candidate,
+        );
         self.infcx.selection_cache.hashmap
                                   .borrow_mut()
                                   .insert(trait_ref, WithDepNode::new(dep_node, candidate));
index cf3241fe9be662d6938e7d551020cbee98db5a4d..3220d4d96b36bd1ed7db3a01745156842101d14f 100644 (file)
@@ -893,7 +893,7 @@ pub fn read_discriminant_value(
     }
 
 
-    pub(crate) fn write_discriminant_value(
+    pub fn write_discriminant_value(
         &mut self,
         dest_ty: Ty<'tcx>,
         dest: Place,
index 406ff9463a03c314f4da185ca068dd0ae2c24a37..7dc73a1d5f01977a45aa07581030c55753b5414c 100644 (file)
@@ -423,12 +423,18 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
                     _ => t.super_visit_with(self)
                 }
             }
+
+            fn visit_region(&mut self, _: ty::Region<'tcx>) -> bool {
+                true
+            }
         }
         let mut param_count = CountParams { params: FxHashSet() };
-        pred.visit_with(&mut param_count);
+        let has_region = pred.visit_with(&mut param_count);
         let substituted_pred = pred.subst(fcx.tcx, substs);
-        // Don't check non-defaulted params, dependent defaults or preds with multiple params.
-        if substituted_pred.references_error() || param_count.params.len() > 1 {
+        // Don't check non-defaulted params, dependent defaults (including lifetimes)
+        // or preds with multiple params.
+        if substituted_pred.references_error() || param_count.params.len() > 1
+            || has_region {
             continue;
         }
         // Avoid duplication of predicates that contain no parameters, for example.
diff --git a/src/test/incremental/issue-49595/auxiliary/lit_a.rs b/src/test/incremental/issue-49595/auxiliary/lit_a.rs
new file mode 100644 (file)
index 0000000..f36baa0
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2018 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 const A: &str = "hello";
diff --git a/src/test/incremental/issue-49595/auxiliary/lit_b.rs b/src/test/incremental/issue-49595/auxiliary/lit_b.rs
new file mode 100644 (file)
index 0000000..2252437
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2018 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 const A: &str = "xxxxx";
diff --git a/src/test/incremental/issue-49595/issue_49595.rs b/src/test/incremental/issue-49595/issue_49595.rs
new file mode 100644 (file)
index 0000000..b899e02
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2018 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.
+
+// revisions:cfail1 cfail2 cfail3
+// compile-flags: -Z query-dep-graph --test
+// must-compile-successfully
+
+#![feature(rustc_attrs)]
+#![crate_type = "rlib"]
+
+#![rustc_partition_translated(module="issue_49595-tests", cfg="cfail2")]
+#![rustc_partition_translated(module="issue_49595-lit_test", cfg="cfail3")]
+
+mod tests {
+    #[cfg_attr(not(cfail1), ignore)]
+    #[test]
+    fn test() {
+    }
+}
+
+
+// Checks that changing a string literal without changing its span
+// takes effect.
+
+// replacing a module to have a stable span
+#[cfg_attr(not(cfail3), path = "auxiliary/lit_a.rs")]
+#[cfg_attr(cfail3, path = "auxiliary/lit_b.rs")]
+mod lit;
+
+pub mod lit_test {
+    #[test]
+    fn lit_test() {
+        println!("{}", ::lit::A);
+    }
+}
index f35946790955360be57bf8f2e09c009ef82c6670..9b06bf837ae0ccf266e24f63ce341dfb7cf1afc1 100644 (file)
@@ -27,4 +27,8 @@ trait SelfBound<T: Copy=Self> {}
 // Not even for well-formedness.
 struct WellFormedProjection<A, T=<A as Iterator>::Item>(A, T);
 
+// Issue #49344, predicates with lifetimes should not be checked.
+trait Scope<'a> {}
+struct Request<'a, S: Scope<'a> = i32>(S, &'a ());
+
 fn main() {}
diff --git a/src/test/ui/issue-48728.rs b/src/test/ui/issue-48728.rs
new file mode 100644 (file)
index 0000000..251ebf5
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+// Regression test for #48728, an ICE that occurred computing
+// coherence "help" information.
+
+#[derive(Clone)] //~ ERROR conflicting implementations of trait `std::clone::Clone`
+struct Node<T: ?Sized>(Box<T>);
+
+impl<T: Clone + ?Sized> Clone for Node<[T]> {
+    fn clone(&self) -> Self {
+        Node(Box::clone(&self.0))
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/issue-48728.stderr b/src/test/ui/issue-48728.stderr
new file mode 100644 (file)
index 0000000..05c87fe
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Node<[_]>`:
+  --> $DIR/issue-48728.rs:14:10
+   |
+LL | #[derive(Clone)] //~ ERROR conflicting implementations of trait `std::clone::Clone`
+   |          ^^^^^ conflicting implementation for `Node<[_]>`
+...
+LL | impl<T: Clone + ?Sized> Clone for Node<[T]> {
+   | ------------------------------------------- first implementation here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs b/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs
new file mode 100644 (file)
index 0000000..8dc1627
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct Foo {
+}
+
+impl Foo {
+    fn get(&self) -> Option<&Result<String, String>> {
+        None
+    }
+
+    fn mutate(&mut self) { }
+}
+
+fn main() {
+    let mut foo = Foo { };
+
+    // foo.get() returns type Option<&Result<String, String>>, so
+    // using `string` keeps borrow of `foo` alive. Hence calling
+    // `foo.mutate()` should be an error.
+    while let Some(Ok(string)) = foo.get() {
+        foo.mutate();
+        //~^ ERROR cannot borrow `foo` as mutable
+        println!("foo={:?}", *string);
+    }
+}
diff --git a/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.stderr b/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.stderr
new file mode 100644 (file)
index 0000000..2da5ac8
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-issue-49631.rs:30:9
+   |
+LL |     while let Some(Ok(string)) = foo.get() {
+   |                                  ---     - immutable borrow ends here
+   |                                  |
+   |                                  immutable borrow occurs here
+LL |         foo.mutate();
+   |         ^^^ mutable borrow occurs here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.