about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-14 21:47:39 +0000
committerbors <bors@rust-lang.org>2024-04-14 21:47:39 +0000
commit0d8b3346a3992ab11ea35ff0fb95a6864b91f797 (patch)
treea3535a775490a9bad07dc1b37abe8e65fc772300
parent29b120740b55aaf2f75e659ba34c4e30977e5fed (diff)
parent32be7b712989cd3da0f056ca04b3020e2c7276e9 (diff)
downloadrust-0d8b3346a3992ab11ea35ff0fb95a6864b91f797.tar.gz
rust-0d8b3346a3992ab11ea35ff0fb95a6864b91f797.zip
Auto merge of #123945 - GuillaumeGomez:rollup-14x3enh, r=GuillaumeGomez
Rollup of 5 pull requests

Successful merges:

 - #120900 (std: use `stream_position` where applicable)
 - #123373 (skip Codegen{GCC,Cranelift} when using CI rustc)
 - #123618 (Discard overflow obligations in `impl_may_apply`)
 - #123905 (rustdoc: check redundant explicit links with correct itemid)
 - #123915 (improve documentation slightly regarding some pointer methods)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs4
-rw-r--r--library/core/src/ptr/mut_ptr.rs12
-rw-r--r--library/std/src/fs.rs5
-rw-r--r--library/std/src/fs/tests.rs48
-rw-r--r--library/std/src/io/buffered/tests.rs7
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs10
-rw-r--r--src/librustdoc/passes/lint/redundant_explicit_links.rs19
-rw-r--r--tests/rustdoc-ui/redundant-explicit-links-123677.rs14
-rw-r--r--tests/ui/traits/overflow-computing-ambiguity.rs14
-rw-r--r--tests/ui/traits/overflow-computing-ambiguity.stderr23
11 files changed, 124 insertions, 52 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
index ddb582ffab0..e6cb28df593 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
@@ -5,6 +5,7 @@ use rustc_infer::traits::{Obligation, ObligationCause, PolyTraitObligation};
 use rustc_middle::ty;
 use rustc_span::{Span, DUMMY_SP};
 
+use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::ObligationCtxt;
 
 #[derive(Debug)]
@@ -52,10 +53,21 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>(
                 _ => return false,
             }
 
-            let impl_predicates = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_args);
-            ocx.register_obligations(impl_predicates.predicates.iter().map(|&predicate| {
-                Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
-            }));
+            let obligations = tcx
+                .predicates_of(impl_def_id)
+                .instantiate(tcx, impl_args)
+                .into_iter()
+                .map(|(predicate, _)| {
+                    Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
+                })
+                // Kinda hacky, but let's just throw away obligations that overflow.
+                // This may reduce the accuracy of this check (if the obligation guides
+                // inference or it actually resulted in error after others are processed)
+                // ... but this is diagnostics code.
+                .filter(|obligation| {
+                    infcx.next_trait_solver() || infcx.evaluate_obligation(obligation).is_ok()
+                });
+            ocx.register_obligations(obligations);
 
             ocx.select_where_possible().is_empty()
         })
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 1b8b09ddda1..3819ea68e96 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -2399,12 +2399,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 if ambiguities.len() > 5 {
                     let infcx = self.infcx;
                     if !ambiguities.iter().all(|option| match option {
-                        DefId(did) => infcx.fresh_args_for_item(DUMMY_SP, *did).is_empty(),
+                        DefId(did) => infcx.tcx.generics_of(*did).count() == 0,
                         ParamEnv(_) => true,
                     }) {
                         // If not all are blanket impls, we filter blanked impls out.
                         ambiguities.retain(|option| match option {
-                            DefId(did) => infcx.fresh_args_for_item(DUMMY_SP, *did).is_empty(),
+                            DefId(did) => infcx.tcx.generics_of(*did).count() == 0,
                             ParamEnv(_) => true,
                         });
                     }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 08f03af355d..d8f91f1996b 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -464,8 +464,8 @@ impl<T: ?Sized> *mut T {
     /// let ptr: *mut u32 = s.as_mut_ptr();
     ///
     /// unsafe {
-    ///     println!("{}", *ptr.offset(1));
-    ///     println!("{}", *ptr.offset(2));
+    ///     assert_eq!(2, *ptr.offset(1));
+    ///     assert_eq!(3, *ptr.offset(2));
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1027,8 +1027,8 @@ impl<T: ?Sized> *mut T {
     /// let ptr: *const u8 = s.as_ptr();
     ///
     /// unsafe {
-    ///     println!("{}", *ptr.add(1) as char);
-    ///     println!("{}", *ptr.add(2) as char);
+    ///     assert_eq!('2', *ptr.add(1) as char);
+    ///     assert_eq!('3', *ptr.add(2) as char);
     /// }
     /// ```
     #[stable(feature = "pointer_methods", since = "1.26.0")]
@@ -1111,8 +1111,8 @@ impl<T: ?Sized> *mut T {
     ///
     /// unsafe {
     ///     let end: *const u8 = s.as_ptr().add(3);
-    ///     println!("{}", *end.sub(1) as char);
-    ///     println!("{}", *end.sub(2) as char);
+    ///     assert_eq!('3', *end.sub(1) as char);
+    ///     assert_eq!('2', *end.sub(2) as char);
     /// }
     /// ```
     #[stable(feature = "pointer_methods", since = "1.26.0")]
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 1b8fafd0089..8a24949631c 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -993,7 +993,7 @@ impl OpenOptions {
     /// If a file is opened with both read and append access, beware that after
     /// opening, and after every write, the position for reading may be set at the
     /// end of the file. So, before writing, save the current position (using
-    /// <code>[seek]\([SeekFrom]::[Current]\(0))</code>), and restore it before the next read.
+    /// <code>[Seek]::[stream_position]</code>), and restore it before the next read.
     ///
     /// ## Note
     ///
@@ -1002,8 +1002,7 @@ impl OpenOptions {
     ///
     /// [`write()`]: Write::write "io::Write::write"
     /// [`flush()`]: Write::flush "io::Write::flush"
-    /// [seek]: Seek::seek "io::Seek::seek"
-    /// [Current]: SeekFrom::Current "io::SeekFrom::Current"
+    /// [stream_position]: Seek::stream_position "io::Seek::stream_position"
     ///
     /// # Examples
     ///
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 6a92832fcdb..ff399a0acd5 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -187,9 +187,9 @@ fn file_test_io_seek_and_tell_smoke_test() {
     {
         let mut read_stream = check!(File::open(filename));
         check!(read_stream.seek(SeekFrom::Start(set_cursor)));
-        tell_pos_pre_read = check!(read_stream.seek(SeekFrom::Current(0)));
+        tell_pos_pre_read = check!(read_stream.stream_position());
         check!(read_stream.read(&mut read_mem));
-        tell_pos_post_read = check!(read_stream.seek(SeekFrom::Current(0)));
+        tell_pos_post_read = check!(read_stream.stream_position());
     }
     check!(fs::remove_file(filename));
     let read_str = str::from_utf8(&read_mem).unwrap();
@@ -284,42 +284,42 @@ fn file_test_io_read_write_at() {
         let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
         let mut rw = check!(oo.open(&filename));
         assert_eq!(check!(rw.write_at(write1.as_bytes(), 5)), write1.len());
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
+        assert_eq!(check!(rw.stream_position()), 0);
         assert_eq!(check!(rw.read_at(&mut buf, 5)), write1.len());
         assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
+        assert_eq!(check!(rw.stream_position()), 0);
         assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len());
         assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok("\0\0\0\0\0"));
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0);
+        assert_eq!(check!(rw.stream_position()), 0);
         assert_eq!(check!(rw.write(write2.as_bytes())), write2.len());
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
+        assert_eq!(check!(rw.stream_position()), 5);
         assert_eq!(check!(rw.read(&mut buf)), write1.len());
         assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.stream_position()), 9);
         assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len());
         assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2));
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.stream_position()), 9);
         assert_eq!(check!(rw.write_at(write3.as_bytes(), 9)), write3.len());
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.stream_position()), 9);
     }
     {
         let mut read = check!(File::open(&filename));
         assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
         assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 0);
+        assert_eq!(check!(read.stream_position()), 0);
         assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
         assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
         assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(read.stream_position()), 9);
         assert_eq!(check!(read.read(&mut buf)), write3.len());
         assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3));
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.stream_position()), 14);
         assert_eq!(check!(read.read_at(&mut buf, 0)), content.len());
         assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.stream_position()), 14);
         assert_eq!(check!(read.read_at(&mut buf, 14)), 0);
         assert_eq!(check!(read.read_at(&mut buf, 15)), 0);
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.stream_position()), 14);
     }
     check!(fs::remove_file(&filename));
 }
@@ -362,38 +362,38 @@ fn file_test_io_seek_read_write() {
         let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
         let mut rw = check!(oo.open(&filename));
         assert_eq!(check!(rw.seek_write(write1.as_bytes(), 5)), write1.len());
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.stream_position()), 9);
         assert_eq!(check!(rw.seek_read(&mut buf, 5)), write1.len());
         assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.stream_position()), 9);
         assert_eq!(check!(rw.seek(SeekFrom::Start(0))), 0);
         assert_eq!(check!(rw.write(write2.as_bytes())), write2.len());
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
+        assert_eq!(check!(rw.stream_position()), 5);
         assert_eq!(check!(rw.read(&mut buf)), write1.len());
         assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1));
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9);
+        assert_eq!(check!(rw.stream_position()), 9);
         assert_eq!(check!(rw.seek_read(&mut buf[..write2.len()], 0)), write2.len());
         assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2));
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5);
+        assert_eq!(check!(rw.stream_position()), 5);
         assert_eq!(check!(rw.seek_write(write3.as_bytes(), 9)), write3.len());
-        assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(rw.stream_position()), 14);
     }
     {
         let mut read = check!(File::open(&filename));
         assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
         assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.stream_position()), 14);
         assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
         assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
         assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.stream_position()), 14);
         assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9);
         assert_eq!(check!(read.read(&mut buf)), write3.len());
         assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3));
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.stream_position()), 14);
         assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len());
         assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content));
-        assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14);
+        assert_eq!(check!(read.stream_position()), 14);
         assert_eq!(check!(read.seek_read(&mut buf, 14)), 0);
         assert_eq!(check!(read.seek_read(&mut buf, 15)), 0);
     }
diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs
index 35a5291a347..ee0db30e22c 100644
--- a/library/std/src/io/buffered/tests.rs
+++ b/library/std/src/io/buffered/tests.rs
@@ -114,7 +114,7 @@ fn test_buffered_reader_seek() {
 
     assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
-    assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3));
+    assert_eq!(reader.stream_position().ok(), Some(3));
     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
     assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4));
     assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..]));
@@ -230,6 +230,9 @@ fn test_buffered_reader_seek_underflow() {
             Ok(len)
         }
     }
+    // note: this implementation of `Seek` is "broken" due to position
+    // wrapping, so calling `reader.seek(Current(0))` is semantically different
+    // than `reader.stream_position()`
     impl Seek for PositionReader {
         fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
             match pos {
@@ -374,7 +377,7 @@ fn test_buffered_writer_seek() {
     let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
     w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap();
     w.write_all(&[6, 7]).unwrap();
-    assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8));
+    assert_eq!(w.stream_position().ok(), Some(8));
     assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
     assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2));
     w.write_all(&[8, 9]).unwrap();
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 09763e6bf01..e3dde89aefc 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -3300,6 +3300,11 @@ impl Step for CodegenCranelift {
             return;
         }
 
+        if builder.download_rustc() {
+            builder.info("CI rustc uses the default codegen backend. skipping");
+            return;
+        }
+
         if !target_supports_cranelift_backend(run.target) {
             builder.info("target not supported by rustc_codegen_cranelift. skipping");
             return;
@@ -3421,6 +3426,11 @@ impl Step for CodegenGCC {
             return;
         }
 
+        if builder.download_rustc() {
+            builder.info("CI rustc uses the default codegen backend. skipping");
+            return;
+        }
+
         let triple = run.target.triple;
         let target_supported =
             if triple.contains("linux") { triple.contains("x86_64") } else { false };
diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs
index 569c17ee36e..09886024595 100644
--- a/src/librustdoc/passes/lint/redundant_explicit_links.rs
+++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs
@@ -6,7 +6,7 @@ use rustc_errors::SuggestionStyle;
 use rustc_hir::def::{DefKind, DocLinkResMap, Namespace, Res};
 use rustc_hir::HirId;
 use rustc_lint_defs::Applicability;
-use rustc_resolve::rustdoc::source_span_for_markdown_range;
+use rustc_resolve::rustdoc::{prepare_to_doc_link_resolution, source_span_for_markdown_range};
 use rustc_span::def_id::DefId;
 use rustc_span::Symbol;
 
@@ -29,16 +29,13 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
         return;
     };
 
-    let doc = item.doc_value();
-    if doc.is_empty() {
-        return;
-    }
-
-    if let Some(item_id) = item.def_id() {
-        check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
-    }
-    if let Some(item_id) = item.inline_stmt_id {
-        check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
+    let hunks = prepare_to_doc_link_resolution(&item.attrs.doc_strings);
+    for (item_id, doc) in hunks {
+        if let Some(item_id) = item_id.or(item.def_id())
+            && !doc.is_empty()
+        {
+            check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
+        }
     }
 }
 
diff --git a/tests/rustdoc-ui/redundant-explicit-links-123677.rs b/tests/rustdoc-ui/redundant-explicit-links-123677.rs
new file mode 100644
index 00000000000..f3a5e81f89d
--- /dev/null
+++ b/tests/rustdoc-ui/redundant-explicit-links-123677.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+#![deny(rustdoc::redundant_explicit_links)]
+
+mod bar {
+    /// [`Rc`](std::rc::Rc)
+    pub enum Baz {}
+}
+
+pub use bar::*;
+
+use std::rc::Rc;
+
+/// [`Rc::allocator`] [foo](std::rc::Rc)
+pub fn winit_runner() {}
diff --git a/tests/ui/traits/overflow-computing-ambiguity.rs b/tests/ui/traits/overflow-computing-ambiguity.rs
new file mode 100644
index 00000000000..b8f11efeda2
--- /dev/null
+++ b/tests/ui/traits/overflow-computing-ambiguity.rs
@@ -0,0 +1,14 @@
+trait Hello {}
+
+struct Foo<'a, T: ?Sized>(&'a T);
+
+impl<'a, T: ?Sized> Hello for Foo<'a, &'a T> where Foo<'a, T>: Hello {}
+
+impl Hello for Foo<'static, i32> {}
+
+fn hello<T: ?Sized + Hello>() {}
+
+fn main() {
+    hello();
+    //~^ ERROR type annotations needed
+}
diff --git a/tests/ui/traits/overflow-computing-ambiguity.stderr b/tests/ui/traits/overflow-computing-ambiguity.stderr
new file mode 100644
index 00000000000..a2e255865bf
--- /dev/null
+++ b/tests/ui/traits/overflow-computing-ambiguity.stderr
@@ -0,0 +1,23 @@
+error[E0283]: type annotations needed
+  --> $DIR/overflow-computing-ambiguity.rs:12:5
+   |
+LL |     hello();
+   |     ^^^^^ cannot infer type of the type parameter `T` declared on the function `hello`
+   |
+   = note: cannot satisfy `_: Hello`
+   = help: the following types implement trait `Hello`:
+             Foo<'a, &'a T>
+             Foo<'static, i32>
+note: required by a bound in `hello`
+  --> $DIR/overflow-computing-ambiguity.rs:9:22
+   |
+LL | fn hello<T: ?Sized + Hello>() {}
+   |                      ^^^^^ required by this bound in `hello`
+help: consider specifying the generic argument
+   |
+LL |     hello::<T>();
+   |          +++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0283`.