about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-19 11:54:40 +0000
committerbors <bors@rust-lang.org>2020-05-19 11:54:40 +0000
commit42acd9086f93fdc68a61cd79152abca77c6cd369 (patch)
tree66bd44168250f99b548ae126d68a1f3f05c748ea
parent914adf04af1c1a984707f778da3d04590c03d144 (diff)
parent745ca2afae768b5228bee15eeb37531313a5a435 (diff)
downloadrust-42acd9086f93fdc68a61cd79152abca77c6cd369.tar.gz
rust-42acd9086f93fdc68a61cd79152abca77c6cd369.zip
Auto merge of #72346 - Dylan-DPC:rollup-vp418xs, r=Dylan-DPC
Rollup of 5 pull requests

Successful merges:

 - #71886 (Stabilize saturating_abs and saturating_neg)
 - #72066 (correctly handle uninferred consts)
 - #72068 (Ignore arguments when looking for `IndexMut` for subsequent `mut` obligation)
 - #72338 (Fix ICE in -Zsave-analysis)
 - #72344 (Assert doc wording)

Failed merges:

r? @ghost
-rw-r--r--src/libcore/macros/mod.rs2
-rw-r--r--src/libcore/num/mod.rs10
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/librustc_infer/infer/error_reporting/need_type_info.rs43
-rw-r--r--src/librustc_save_analysis/lib.rs6
-rw-r--r--src/librustc_typeck/check/method/confirm.rs4
-rw-r--r--src/librustc_typeck/check/writeback.rs20
-rw-r--r--src/test/ui/const-generics/uninferred-consts.rs12
-rw-r--r--src/test/ui/const-generics/uninferred-consts.stderr20
-rw-r--r--src/test/ui/consts/const-int-arithmetic.rs1
-rw-r--r--src/test/ui/issues/issue-72002.rs29
-rw-r--r--src/test/ui/save-analysis/issue-72267.rs7
-rw-r--r--src/test/ui/save-analysis/issue-72267.stderr15
13 files changed, 154 insertions, 16 deletions
diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs
index 14bfa8bab89..13a569e81d0 100644
--- a/src/libcore/macros/mod.rs
+++ b/src/libcore/macros/mod.rs
@@ -1243,7 +1243,7 @@ pub(crate) mod builtin {
     /// be disabled. See [`debug_assert!`] for assertions that are not enabled in
     /// release builds by default.
     ///
-    /// Unsafe code relies on `assert!` to enforce run-time invariants that, if
+    /// Unsafe code may rely on `assert!` to enforce run-time invariants that, if
     /// violated could lead to unsafety.
     ///
     /// Other use-cases of `assert!` include testing and enforcing run-time
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 9e1971c9a94..c164e893b4f 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1165,8 +1165,7 @@ instead of overflowing.
 Basic usage:
 
 ```
-", $Feature, "#![feature(saturating_neg)]
-assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);
 assert_eq!((-100", stringify!($SelfT), ").saturating_neg(), 100);
 assert_eq!(", stringify!($SelfT), "::MIN.saturating_neg(), ", stringify!($SelfT),
 "::MAX);
@@ -1175,7 +1174,7 @@ assert_eq!(", stringify!($SelfT), "::MAX.saturating_neg(), ", stringify!($SelfT)
 $EndFeature, "
 ```"),
 
-            #[unstable(feature = "saturating_neg", issue = "59983")]
+            #[stable(feature = "saturating_neg", since = "1.45.0")]
             #[rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718")]
             #[inline]
             pub const fn saturating_neg(self) -> Self {
@@ -1192,8 +1191,7 @@ MIN` instead of overflowing.
 Basic usage:
 
 ```
-", $Feature, "#![feature(saturating_neg)]
-assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);
+", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);
 assert_eq!((-100", stringify!($SelfT), ").saturating_abs(), 100);
 assert_eq!(", stringify!($SelfT), "::MIN.saturating_abs(), ", stringify!($SelfT),
 "::MAX);
@@ -1202,7 +1200,7 @@ assert_eq!((", stringify!($SelfT), "::MIN + 1).saturating_abs(), ", stringify!($
 $EndFeature, "
 ```"),
 
-            #[unstable(feature = "saturating_neg", issue = "59983")]
+            #[stable(feature = "saturating_neg", since = "1.45.0")]
             #[rustc_const_unstable(feature = "const_saturating_int_methods", issue = "53718")]
             #[inline]
             pub const fn saturating_abs(self) -> Self {
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index d636542d699..6a8e908b9c6 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -17,7 +17,6 @@
 #![feature(pattern)]
 #![feature(range_is_empty)]
 #![feature(raw)]
-#![feature(saturating_neg)]
 #![feature(sort_internals)]
 #![feature(slice_partition_at_index)]
 #![feature(specialization)]
diff --git a/src/librustc_infer/infer/error_reporting/need_type_info.rs b/src/librustc_infer/infer/error_reporting/need_type_info.rs
index 0141ba82737..dfc7177921d 100644
--- a/src/librustc_infer/infer/error_reporting/need_type_info.rs
+++ b/src/librustc_infer/infer/error_reporting/need_type_info.rs
@@ -172,8 +172,19 @@ fn closure_args(fn_sig: &ty::PolyFnSig<'_>) -> String {
 }
 
 pub enum TypeAnnotationNeeded {
+    /// ```compile_fail,E0282
+    /// let x = "hello".chars().rev().collect();
+    /// ```
     E0282,
+    /// An implementation cannot be chosen unambiguously because of lack of information.
+    /// ```compile_fail,E0283
+    /// let _ = Default::default();
+    /// ```
     E0283,
+    /// ```compile_fail,E0284
+    /// let mut d: u64 = 2;
+    /// d = d % 1u32.into();
+    /// ```
     E0284,
 }
 
@@ -261,7 +272,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             printer.name_resolver = Some(Box::new(&getter));
             let _ = if let ty::FnDef(..) = ty.kind {
                 // We don't want the regular output for `fn`s because it includes its path in
-                // invalid pseduo-syntax, we want the `fn`-pointer output instead.
+                // invalid pseudo-syntax, we want the `fn`-pointer output instead.
                 ty.fn_sig(self.tcx).print(printer)
             } else {
                 ty.print(printer)
@@ -518,6 +529,36 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         err
     }
 
+    // FIXME(const_generics): We should either try and merge this with `need_type_info_err`
+    // or improve the errors created here.
+    //
+    // Unlike for type inference variables, we don't yet store the origin of const inference variables.
+    // This is needed for to get a more relevant error span.
+    pub fn need_type_info_err_const(
+        &self,
+        body_id: Option<hir::BodyId>,
+        span: Span,
+        ct: &'tcx ty::Const<'tcx>,
+        error_code: TypeAnnotationNeeded,
+    ) -> DiagnosticBuilder<'tcx> {
+        let mut local_visitor = FindHirNodeVisitor::new(&self, ct.into(), span);
+        if let Some(body_id) = body_id {
+            let expr = self.tcx.hir().expect_expr(body_id.hir_id);
+            local_visitor.visit_expr(expr);
+        }
+
+        let error_code = error_code.into();
+        let mut err = self.tcx.sess.struct_span_err_with_code(
+            local_visitor.target_span,
+            &format!("type annotations needed"),
+            error_code,
+        );
+
+        err.note("unable to infer the value of a const parameter");
+
+        err
+    }
+
     /// If the `FnSig` for the method call can be found and type arguments are identified as
     /// needed, suggest annotating the call, otherwise point out the resulting type of the call.
     fn annotate_method_call(
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 8ae6853210f..43fd2b18530 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -620,7 +620,11 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
     }
 
     pub fn get_path_res(&self, id: NodeId) -> Res {
-        let hir_id = self.tcx.hir().node_id_to_hir_id(id);
+        // FIXME(#71104)
+        let hir_id = match self.tcx.hir().opt_node_id_to_hir_id(id) {
+            Some(id) => id,
+            None => return Res::Err,
+        };
         match self.tcx.hir().get(hir_id) {
             Node::TraitRef(tr) => tr.path.res,
 
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 64dc34ab3b0..c4805c54a7d 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -468,7 +468,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
             match expr.kind {
                 hir::ExprKind::Index(ref base_expr, ref index_expr) => {
-                    let index_expr_ty = self.node_ty(index_expr.hir_id);
+                    // We need to get the final type in case dereferences were needed for the trait
+                    // to apply (#72002).
+                    let index_expr_ty = self.tables.borrow().expr_ty_adjusted(index_expr);
                     self.convert_place_op_to_mutable(
                         PlaceOp::Index,
                         expr,
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index c5bf151bc1e..154ca391aa5 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -647,13 +647,26 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
         Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false }
     }
 
-    fn report_error(&self, t: Ty<'tcx>) {
+    fn report_type_error(&self, t: Ty<'tcx>) {
         if !self.tcx.sess.has_errors() {
             self.infcx
                 .need_type_info_err(Some(self.body.id()), self.span.to_span(self.tcx), t, E0282)
                 .emit();
         }
     }
+
+    fn report_const_error(&self, c: &'tcx ty::Const<'tcx>) {
+        if !self.tcx.sess.has_errors() {
+            self.infcx
+                .need_type_info_err_const(
+                    Some(self.body.id()),
+                    self.span.to_span(self.tcx),
+                    c,
+                    E0282,
+                )
+                .emit();
+        }
+    }
 }
 
 impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
@@ -666,7 +679,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
             Ok(t) => self.infcx.tcx.erase_regions(&t),
             Err(_) => {
                 debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
-                self.report_error(t);
+                self.report_type_error(t);
                 self.replaced_with_error = true;
                 self.tcx().types.err
             }
@@ -683,8 +696,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
             Ok(ct) => self.infcx.tcx.erase_regions(&ct),
             Err(_) => {
                 debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
-                // FIXME: we'd like to use `self.report_error`, but it doesn't yet
-                // accept a &'tcx ty::Const.
+                self.report_const_error(ct);
                 self.replaced_with_error = true;
                 self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty })
             }
diff --git a/src/test/ui/const-generics/uninferred-consts.rs b/src/test/ui/const-generics/uninferred-consts.rs
new file mode 100644
index 00000000000..3b2bb49197d
--- /dev/null
+++ b/src/test/ui/const-generics/uninferred-consts.rs
@@ -0,0 +1,12 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete
+
+// taken from https://github.com/rust-lang/rust/issues/70507#issuecomment-615268893
+struct Foo;
+impl Foo {
+    fn foo<const N: usize>(self) {}
+}
+fn main() {
+    Foo.foo();
+    //~^ ERROR type annotations needed
+}
diff --git a/src/test/ui/const-generics/uninferred-consts.stderr b/src/test/ui/const-generics/uninferred-consts.stderr
new file mode 100644
index 00000000000..a3620084a42
--- /dev/null
+++ b/src/test/ui/const-generics/uninferred-consts.stderr
@@ -0,0 +1,20 @@
+warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/uninferred-consts.rs:1:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
+
+error[E0282]: type annotations needed
+  --> $DIR/uninferred-consts.rs:10:5
+   |
+LL |     Foo.foo();
+   |     ^^^^^^^^^
+   |
+   = note: unable to infer the value of a const parameter
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/consts/const-int-arithmetic.rs b/src/test/ui/consts/const-int-arithmetic.rs
index 2c3421b7a8d..ab24abeba32 100644
--- a/src/test/ui/consts/const-int-arithmetic.rs
+++ b/src/test/ui/consts/const-int-arithmetic.rs
@@ -1,6 +1,5 @@
 // run-pass
 
-#![feature(saturating_neg)]
 #![feature(const_checked_int_methods)]
 #![feature(const_euclidean_int_methods)]
 #![feature(const_overflowing_int_methods)]
diff --git a/src/test/ui/issues/issue-72002.rs b/src/test/ui/issues/issue-72002.rs
new file mode 100644
index 00000000000..54ff89355ff
--- /dev/null
+++ b/src/test/ui/issues/issue-72002.rs
@@ -0,0 +1,29 @@
+// check-pass
+struct Indexable;
+
+impl Indexable {
+    fn boo(&mut self) {}
+}
+
+impl std::ops::Index<&str> for Indexable {
+    type Output = Indexable;
+
+    fn index(&self, field: &str) -> &Indexable {
+        self
+    }
+}
+
+impl std::ops::IndexMut<&str> for Indexable {
+    fn index_mut(&mut self, field: &str) -> &mut Indexable {
+        self
+    }
+}
+
+fn main() {
+    let mut v = Indexable;
+    let field = "hello".to_string();
+
+    v[field.as_str()].boo();
+
+    v[&field].boo(); // < This should work
+}
diff --git a/src/test/ui/save-analysis/issue-72267.rs b/src/test/ui/save-analysis/issue-72267.rs
new file mode 100644
index 00000000000..eea0a7fea0c
--- /dev/null
+++ b/src/test/ui/save-analysis/issue-72267.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Z save-analysis
+
+fn main() {
+    let _: Box<(dyn ?Sized)>;
+    //~^ ERROR `?Trait` is not permitted in trait object types
+    //~| ERROR at least one trait is required for an object type
+}
diff --git a/src/test/ui/save-analysis/issue-72267.stderr b/src/test/ui/save-analysis/issue-72267.stderr
new file mode 100644
index 00000000000..76fc6c57cbc
--- /dev/null
+++ b/src/test/ui/save-analysis/issue-72267.stderr
@@ -0,0 +1,15 @@
+error: `?Trait` is not permitted in trait object types
+  --> $DIR/issue-72267.rs:4:21
+   |
+LL |     let _: Box<(dyn ?Sized)>;
+   |                     ^^^^^^
+
+error[E0224]: at least one trait is required for an object type
+  --> $DIR/issue-72267.rs:4:17
+   |
+LL |     let _: Box<(dyn ?Sized)>;
+   |                 ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0224`.