From af6840b0a5378307b545eed1147523051cf5fdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Marcos=20P=2E=20Bezerra?= Date: Sat, 10 Feb 2024 20:53:27 -0300 Subject: [PATCH 1/5] std: use `stream_position` where applicable by replacing `seek(SeekFrom::Current(0))` calls --- library/std/src/fs.rs | 5 ++- library/std/src/fs/tests.rs | 48 ++++++++++++++-------------- library/std/src/io/buffered/tests.rs | 7 ++-- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 3383a8cfa41ef..43dfcb223639d 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -984,7 +984,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 - /// [seek]\([SeekFrom]::[Current]\(0))), and restore it before the next read. + /// [Seek]::[stream_position]), and restore it before the next read. /// /// ## Note /// @@ -993,8 +993,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 5917bf8df029e..51c9072933d9c 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -189,9 +189,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(); @@ -286,42 +286,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)); } @@ -364,38 +364,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 35a5291a34769..ee0db30e22c2e 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 { 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(); From 167e3ab8c80deb0cdec524f4445f323d93dbd3a7 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Tue, 2 Apr 2024 18:15:05 +0300 Subject: [PATCH 2/5] skip Codegen{GCC,Cranelift} when using CI rustc Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 8a79c28fc6c62..197644a1e3999 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3223,6 +3223,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; @@ -3344,6 +3349,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 }; From 87a387a7223a1b9d8cdc698df091383c9b703c31 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 7 Apr 2024 23:02:28 -0400 Subject: [PATCH 3/5] Discard overflow obligations in impl_may_apply --- .../src/traits/error_reporting/ambiguity.rs | 20 ++++++++++++---- .../error_reporting/type_err_ctxt_ext.rs | 4 ++-- .../ui/traits/overflow-computing-ambiguity.rs | 14 +++++++++++ .../overflow-computing-ambiguity.stderr | 23 +++++++++++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 tests/ui/traits/overflow-computing-ambiguity.rs create mode 100644 tests/ui/traits/overflow-computing-ambiguity.stderr 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 ddb582ffab0ba..e6cb28df593af 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 144971b63c0ad..33fc1d0d3316e 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 @@ -2398,12 +2398,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/tests/ui/traits/overflow-computing-ambiguity.rs b/tests/ui/traits/overflow-computing-ambiguity.rs new file mode 100644 index 0000000000000..b8f11efeda283 --- /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() {} + +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 0000000000000..a2e255865bf48 --- /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() {} + | ^^^^^ required by this bound in `hello` +help: consider specifying the generic argument + | +LL | hello::(); + | +++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. From 0fea38a01f4015d310230b76984068b6fe8414d4 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 13 Apr 2024 18:41:14 -0700 Subject: [PATCH 4/5] rustdoc: check redundant explicit links with correct itemid Fixes a regression caused by 0a50dba50bedd24377bd1066da3b4b7066df4d28 --- .../passes/lint/redundant_explicit_links.rs | 19 ++++++++----------- .../redundant-explicit-links-123677.rs | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 tests/rustdoc-ui/redundant-explicit-links-123677.rs diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 569c17ee36e57..098860245951a 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 0000000000000..f3a5e81f89d8d --- /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() {} From 5b8864ab80bfc4d9a4c8b41347a0ad4bf99a8681 Mon Sep 17 00:00:00 2001 From: Mohamed El-Shenawy <111167226+shenawy29@users.noreply.github.com> Date: Sun, 14 Apr 2024 09:56:33 +0200 Subject: [PATCH 5/5] improve documentation slightly regarding some pointer methods --- library/core/src/ptr/mut_ptr.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 08f03af355da8..d8f91f1996b92 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -464,8 +464,8 @@ impl *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 *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 *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")]