mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 06:22:00 +00:00
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
This commit is contained in:
commit
0d8b3346a3
@ -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()
|
||||
})
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
@ -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")]
|
||||
|
@ -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
|
||||
///
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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 };
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
14
tests/rustdoc-ui/redundant-explicit-links-123677.rs
Normal file
14
tests/rustdoc-ui/redundant-explicit-links-123677.rs
Normal file
@ -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() {}
|
14
tests/ui/traits/overflow-computing-ambiguity.rs
Normal file
14
tests/ui/traits/overflow-computing-ambiguity.rs
Normal file
@ -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
|
||||
}
|
23
tests/ui/traits/overflow-computing-ambiguity.stderr
Normal file
23
tests/ui/traits/overflow-computing-ambiguity.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user