about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-18 01:11:43 +0000
committerbors <bors@rust-lang.org>2020-08-18 01:11:43 +0000
commitd7dcae03c9c014362cdefb7ec605bb35804a6a94 (patch)
tree9be507e2db101a874e421bc81a4800a0e8bcc327 /src
parent668ef72f4429059240ee361a2f0f748558a5326f (diff)
parent51154d82959f941ff334de306d9426557b9f4214 (diff)
downloadrust-d7dcae03c9c014362cdefb7ec605bb35804a6a94.tar.gz
rust-d7dcae03c9c014362cdefb7ec605bb35804a6a94.zip
Auto merge of #75653 - JohnTitor:rollup-0ejtdfo, r=JohnTitor
Rollup of 8 pull requests

Successful merges:

 - #75389 (attempt to improve span_label docs)
 - #75392 (Add `as_uninit`-like methods to pointer types and unify documentation of `as_ref` methods)
 - #75464 (Move to intra doc links for ascii.rs and panic.rs)
 - #75578 (Allowing raw ptr dereference in const fn)
 - #75613 (Add explanation for `&mut self` method call when expecting `-> Self`)
 - #75626 (Clean up E0754 explanation)
 - #75629 (Use intra-doc links in `std::env`, `std::alloc` and `std::error`)
 - #75634 (Mark x86_64-linux-kernel as *)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/librustc_error_codes/error_codes/E0754.md20
-rw-r--r--src/librustc_errors/diagnostic.rs15
-rw-r--r--src/librustc_errors/diagnostic_builder.rs14
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs2
-rw-r--r--src/librustc_typeck/check/demand.rs1
-rw-r--r--src/librustc_typeck/check/mod.rs45
-rw-r--r--src/test/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs11
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr14
-rw-r--r--src/test/ui/suggestions/chain-method-call-mutation-in-place.rs4
-rw-r--r--src/test/ui/suggestions/chain-method-call-mutation-in-place.stderr20
12 files changed, 111 insertions, 39 deletions
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 61261e82147..21874853839 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -204,7 +204,7 @@ target | std | host | notes
 `thumbv4t-none-eabi` | * |  | ARMv4T T32
 `x86_64-apple-ios-macabi` | ✓[^apple] |  | Apple Catalyst
 `x86_64-apple-tvos` | *[^apple] | | x86 64-bit tvOS
-`x86_64-linux-kernel` | ? |  | Linux kernel modules
+`x86_64-linux-kernel` | * |  | Linux kernel modules
 `x86_64-pc-solaris` | ? |  |
 `x86_64-pc-windows-msvc` | ✓ |  | 64-bit Windows XP support
 `x86_64-unknown-cloudabi` | ✓ |  | 64-bit CloudABI
diff --git a/src/librustc_error_codes/error_codes/E0754.md b/src/librustc_error_codes/error_codes/E0754.md
index abdc01ed21a..57620bcd65c 100644
--- a/src/librustc_error_codes/error_codes/E0754.md
+++ b/src/librustc_error_codes/error_codes/E0754.md
@@ -1,31 +1,25 @@
 An non-ascii identifier was used in an invalid context.
 
-Erroneous code example:
+Erroneous code examples:
 
 ```compile_fail,E0754
 # #![feature(non_ascii_idents)]
 
-mod řųśť;
-// ^ error!
-fn main() {}
-```
-
-```compile_fail,E0754
-# #![feature(non_ascii_idents)]
+mod řųśť; // error!
 
 #[no_mangle]
-fn řųśť() {}
-// ^ error!
+fn řųśť() {} // error!
+
 fn main() {}
 ```
 
-Non-ascii can be used as module names if it is inline
-or a #\[path\] attribute is specified. For example:
+Non-ascii can be used as module names if it is inlined or if a `#[path]`
+attribute is specified. For example:
 
 ```
 # #![feature(non_ascii_idents)]
 
-mod řųśť {
+mod řųśť { // ok!
     const IS_GREAT: bool = true;
 }
 
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs
index cd4b5d56f36..870f7b81e21 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/src/librustc_errors/diagnostic.rs
@@ -127,14 +127,15 @@ impl Diagnostic {
     }
 
     /// Adds a span/label to be included in the resulting snippet.
-    /// This label will be shown together with the original span/label used when creating the
-    /// diagnostic, *not* a span added by one of the `span_*` methods.
     ///
-    /// This is pushed onto the `MultiSpan` that was created when the
-    /// diagnostic was first built. If you don't call this function at
-    /// all, and you just supplied a `Span` to create the diagnostic,
-    /// then the snippet will just include that `Span`, which is
-    /// called the primary span.
+    /// This is pushed onto the [`MultiSpan`] that was created when the diagnostic
+    /// was first built. That means it will be shown together with the original
+    /// span/label, *not* a span added by one of the `span_{note,warn,help,suggestions}` methods.
+    ///
+    /// This span is *not* considered a ["primary span"][`MultiSpan`]; only
+    /// the `Span` supplied when creating the diagnostic is primary.
+    ///
+    /// [`MultiSpan`]: ../rustc_span/struct.MultiSpan.html
     pub fn span_label<T: Into<String>>(&mut self, span: Span, label: T) -> &mut Self {
         self.span.push_span_label(span, label.into());
         self
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index dc52e29fa9b..d1ff6f721c4 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -184,11 +184,15 @@ impl<'a> DiagnosticBuilder<'a> {
     }
 
     /// Adds a span/label to be included in the resulting snippet.
-    /// This is pushed onto the `MultiSpan` that was created when the
-    /// diagnostic was first built. If you don't call this function at
-    /// all, and you just supplied a `Span` to create the diagnostic,
-    /// then the snippet will just include that `Span`, which is
-    /// called the primary span.
+    ///
+    /// This is pushed onto the [`MultiSpan`] that was created when the diagnostic
+    /// was first built. That means it will be shown together with the original
+    /// span/label, *not* a span added by one of the `span_{note,warn,help,suggestions}` methods.
+    ///
+    /// This span is *not* considered a ["primary span"][`MultiSpan`]; only
+    /// the `Span` supplied when creating the diagnostic is primary.
+    ///
+    /// [`MultiSpan`]: ../rustc_span/struct.MultiSpan.html
     pub fn span_label(&mut self, span: Span, label: impl Into<String>) -> &mut Self {
         self.0.diagnostic.span_label(span, label);
         self
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index d2a5616b8ed..6aabc1941a6 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -228,7 +228,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
             let base_ty = Place::ty_from(place.local, proj_base, self.body, self.tcx).ty;
             match base_ty.kind {
                 ty::RawPtr(..) => self.require_unsafe(
-                    UnsafetyViolationKind::General,
+                    UnsafetyViolationKind::GeneralAndConstFn,
                     UnsafetyViolationDetails::DerefOfRawPointer,
                 ),
                 ty::Adt(adt, _) => {
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index ad97dbe63d8..aa92d8b8b2b 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -36,6 +36,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.suggest_missing_await(err, expr, expected, expr_ty);
         self.suggest_missing_parentheses(err, expr);
         self.note_need_for_fn_pointer(err, expected, expr_ty);
+        self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
     }
 
     // Requires that the two types unify, and prints an error message if
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 5b8c775e74d..824e81a974c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5198,6 +5198,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    fn note_internal_mutation_in_method(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expr: &hir::Expr<'_>,
+        expected: Ty<'tcx>,
+        found: Ty<'tcx>,
+    ) {
+        if found != self.tcx.types.unit {
+            return;
+        }
+        if let ExprKind::MethodCall(path_segment, _, [rcvr, ..], _) = expr.kind {
+            if self
+                .typeck_results
+                .borrow()
+                .expr_ty_adjusted_opt(rcvr)
+                .map_or(true, |ty| expected.peel_refs() != ty.peel_refs())
+            {
+                return;
+            }
+            let mut sp = MultiSpan::from_span(path_segment.ident.span);
+            sp.push_span_label(
+                path_segment.ident.span,
+                format!(
+                    "this call modifies {} in-place",
+                    match rcvr.kind {
+                        ExprKind::Path(QPath::Resolved(
+                            None,
+                            hir::Path { segments: [segment], .. },
+                        )) => format!("`{}`", segment.ident),
+                        _ => "its receiver".to_string(),
+                    }
+                ),
+            );
+            sp.push_span_label(
+                rcvr.span,
+                "you probably want to use this value after calling the method...".to_string(),
+            );
+            err.span_note(
+                sp,
+                &format!("method `{}` modifies its receiver in-place", path_segment.ident),
+            );
+            err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident));
+        }
+    }
+
     /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
     fn suggest_calling_boxed_future_when_appropriate(
         &self,
diff --git a/src/test/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs b/src/test/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs
new file mode 100644
index 00000000000..25dc457d144
--- /dev/null
+++ b/src/test/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs
@@ -0,0 +1,11 @@
+// check-pass
+#![feature(const_raw_ptr_deref)]
+#![feature(raw_ref_macros)]
+
+use std::ptr;
+
+const fn test_fn(x: *const i32) {
+    let x2 = unsafe { ptr::raw_const!(*x) };
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs
index 0b1ab1c34ff..6462d736ad1 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs
@@ -1,4 +1,4 @@
-const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
+const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } }
 //~^ dereferencing raw pointers in constant functions
 
 const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x }
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr
index 97b0a778d2c..427ecff5c6d 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr
@@ -34,15 +34,7 @@ LL |     Foo { x: () }.y
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
-  --> $DIR/min_const_fn_unsafe_bad.rs:1:77
-   |
-LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } }
-   |                                                                             ^^^ dereference of raw pointer
-   |
-   = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0133, E0658, E0723.
-For more information about an error, try `rustc --explain E0133`.
+Some errors have detailed explanations: E0658, E0723.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/suggestions/chain-method-call-mutation-in-place.rs b/src/test/ui/suggestions/chain-method-call-mutation-in-place.rs
new file mode 100644
index 00000000000..cb92ab87a8f
--- /dev/null
+++ b/src/test/ui/suggestions/chain-method-call-mutation-in-place.rs
@@ -0,0 +1,4 @@
+fn main() {}
+fn foo(mut s: String) -> String {
+    s.push_str("asdf") //~ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/chain-method-call-mutation-in-place.stderr b/src/test/ui/suggestions/chain-method-call-mutation-in-place.stderr
new file mode 100644
index 00000000000..63e3bb78954
--- /dev/null
+++ b/src/test/ui/suggestions/chain-method-call-mutation-in-place.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+  --> $DIR/chain-method-call-mutation-in-place.rs:3:5
+   |
+LL | fn foo(mut s: String) -> String {
+   |                          ------ expected `std::string::String` because of return type
+LL |     s.push_str("asdf")
+   |     ^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found `()`
+   |
+note: method `push_str` modifies its receiver in-place
+  --> $DIR/chain-method-call-mutation-in-place.rs:3:7
+   |
+LL |     s.push_str("asdf")
+   |     - ^^^^^^^^ this call modifies `s` in-place
+   |     |
+   |     you probably want to use this value after calling the method...
+   = note: ...instead of the `()` output of method `push_str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.