Auto merge of #89037 - JohnTitor:rollup-rd9btbs, r=JohnTitor
Rollup of 10 pull requests Successful merges: - #86382 (Make diagnostics clearer for `?` operators) - #87529 (Fix ICE in `improper_ctypes_definitions` lint with all-ZST transparent types) - #88339 (Add TcpListener::into_incoming and IntoIncoming) - #88735 (Don't lint about missing code examples in derived traits) - #88751 (Couple of changes to FileSearch and SearchPath) - #88883 (Move some tests to more reasonable directories - 7) - #88887 (Const Deref) - #88911 (Improve error message for type mismatch in generator arguments) - #89014 (PassWrapper: handle separate Module*SanitizerPass) - #89033 (Set the library path in sysroot-crates-are-unstable) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
1c03f0d0ba
81 changed files with 283 additions and 111 deletions
|
@ -637,7 +637,7 @@ fn link_dwarf_object<'a>(sess: &'a Session, executable_out_filename: &Path) {
|
|||
cmd.arg("-o");
|
||||
cmd.arg(&dwp_out_filename);
|
||||
|
||||
let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
|
||||
let mut new_path = sess.get_tools_search_paths(false);
|
||||
if let Some(path) = env::var_os("PATH") {
|
||||
new_path.extend(env::split_paths(&path));
|
||||
}
|
||||
|
@ -2555,8 +2555,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
|
|||
match ld_impl {
|
||||
LdImpl::Lld => {
|
||||
if sess.target.lld_flavor == LldFlavor::Ld64 {
|
||||
let tools_path =
|
||||
sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
|
||||
let tools_path = sess.get_tools_search_paths(false);
|
||||
let ld64_exe = tools_path
|
||||
.into_iter()
|
||||
.map(|p| p.join("gcc-ld"))
|
||||
|
@ -2571,8 +2570,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
|
|||
arg
|
||||
});
|
||||
} else {
|
||||
let tools_path =
|
||||
sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
|
||||
let tools_path = sess.get_tools_search_paths(false);
|
||||
let lld_path = tools_path
|
||||
.into_iter()
|
||||
.map(|p| p.join("gcc-ld"))
|
||||
|
|
|
@ -15,7 +15,6 @@ use rustc_middle::middle::dependency_format::Linkage;
|
|||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_serialize::{json, Encoder};
|
||||
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
|
||||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor};
|
||||
|
@ -101,7 +100,7 @@ pub fn get_linker<'a>(
|
|||
|
||||
// The compiler's sysroot often has some bundled tools, so add it to the
|
||||
// PATH for the child.
|
||||
let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained);
|
||||
let mut new_path = sess.get_tools_search_paths(self_contained);
|
||||
let mut msvc_changed_path = false;
|
||||
if sess.target.is_like_msvc {
|
||||
if let Some(ref tool) = msvc_tool {
|
||||
|
|
|
@ -677,10 +677,7 @@ impl RustcDefaultCalls {
|
|||
println!("{}", targets.join("\n"));
|
||||
}
|
||||
Sysroot => println!("{}", sess.sysroot.display()),
|
||||
TargetLibdir => println!(
|
||||
"{}",
|
||||
sess.target_tlib_path.as_ref().unwrap_or(&sess.host_tlib_path).dir.display()
|
||||
),
|
||||
TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()),
|
||||
TargetSpec => println!("{}", sess.target.to_json().pretty()),
|
||||
FileNames | CrateName => {
|
||||
let input = input.unwrap_or_else(|| {
|
||||
|
|
|
@ -74,6 +74,10 @@ impl DiagnosticStyledString {
|
|||
pub fn highlighted<S: Into<String>>(t: S) -> DiagnosticStyledString {
|
||||
DiagnosticStyledString(vec![StringPart::Highlighted(t.into())])
|
||||
}
|
||||
|
||||
pub fn content(&self) -> String {
|
||||
self.0.iter().map(|x| x.content()).collect::<String>()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -82,6 +86,14 @@ pub enum StringPart {
|
|||
Highlighted(String),
|
||||
}
|
||||
|
||||
impl StringPart {
|
||||
pub fn content(&self) -> &str {
|
||||
match self {
|
||||
&StringPart::Normal(ref s) | &StringPart::Highlighted(ref s) => s,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Diagnostic {
|
||||
pub fn new(level: Level, message: &str) -> Self {
|
||||
Diagnostic::new_with_code(level, None, message)
|
||||
|
|
|
@ -1971,6 +1971,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
trace: TypeTrace<'tcx>,
|
||||
terr: &TypeError<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
use crate::traits::ObligationCauseCode::MatchExpressionArm;
|
||||
|
||||
debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
|
||||
|
||||
let span = trace.cause.span(self.tcx);
|
||||
|
@ -2013,6 +2015,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
if let MatchExpressionArm(box MatchExpressionArmCause { source, .. }) =
|
||||
trace.cause.code
|
||||
{
|
||||
if let hir::MatchSource::TryDesugar = source {
|
||||
if let Some((expected_ty, found_ty)) = self.values_str(trace.values) {
|
||||
err.note(&format!(
|
||||
"`?` operator cannot convert from `{}` to `{}`",
|
||||
found_ty.content(),
|
||||
expected_ty.content(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
err
|
||||
}
|
||||
FailureCode::Error0644(failure_str) => {
|
||||
|
@ -2585,9 +2600,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
|||
CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"),
|
||||
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => {
|
||||
Error0308(match source {
|
||||
hir::MatchSource::TryDesugar => {
|
||||
"try expression alternatives have incompatible types"
|
||||
}
|
||||
hir::MatchSource::TryDesugar => "`?` operator has incompatible types",
|
||||
_ => "`match` arms have incompatible types",
|
||||
})
|
||||
}
|
||||
|
|
|
@ -851,12 +851,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
use FfiResult::*;
|
||||
|
||||
if def.repr.transparent() {
|
||||
// Can assume that only one field is not a ZST, so only check
|
||||
// Can assume that at most one field is not a ZST, so only check
|
||||
// that field's type for FFI-safety.
|
||||
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
|
||||
self.check_field_type_for_ffi(cache, field, substs)
|
||||
} else {
|
||||
bug!("malformed transparent type");
|
||||
// All fields are ZSTs; this means that the type should behave
|
||||
// like (), which is FFI-unsafe
|
||||
FfiUnsafe {
|
||||
ty,
|
||||
reason: "this struct contains only zero-sized fields".into(),
|
||||
help: None,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We can't completely trust repr(C) markings; make sure the fields are
|
||||
|
|
|
@ -875,7 +875,11 @@ LLVMRustOptimizeWithNewPassManager(
|
|||
#if LLVM_VERSION_GE(11, 0)
|
||||
OptimizerLastEPCallbacks.push_back(
|
||||
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
|
||||
#if LLVM_VERSION_GE(14, 0)
|
||||
MPM.addPass(ModuleMemorySanitizerPass(Options));
|
||||
#else
|
||||
MPM.addPass(MemorySanitizerPass(Options));
|
||||
#endif
|
||||
MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass(Options)));
|
||||
}
|
||||
);
|
||||
|
@ -897,7 +901,11 @@ LLVMRustOptimizeWithNewPassManager(
|
|||
#if LLVM_VERSION_GE(11, 0)
|
||||
OptimizerLastEPCallbacks.push_back(
|
||||
[](ModulePassManager &MPM, OptimizationLevel Level) {
|
||||
#if LLVM_VERSION_GE(14, 0)
|
||||
MPM.addPass(ModuleThreadSanitizerPass());
|
||||
#else
|
||||
MPM.addPass(ThreadSanitizerPass());
|
||||
#endif
|
||||
MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
|
||||
}
|
||||
);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! A module for searching for libraries
|
||||
|
||||
pub use self::FileMatch::*;
|
||||
|
||||
use std::env;
|
||||
|
@ -14,8 +16,6 @@ pub enum FileMatch {
|
|||
FileDoesntMatch,
|
||||
}
|
||||
|
||||
// A module for searching for libraries
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FileSearch<'a> {
|
||||
sysroot: &'a Path,
|
||||
|
@ -83,22 +83,10 @@ impl<'a> FileSearch<'a> {
|
|||
FileSearch { sysroot, triple, search_paths, tlib_path, kind }
|
||||
}
|
||||
|
||||
// Returns just the directories within the search paths.
|
||||
/// Returns just the directories within the search paths.
|
||||
pub fn search_path_dirs(&self) -> Vec<PathBuf> {
|
||||
self.search_paths().map(|sp| sp.dir.to_path_buf()).collect()
|
||||
}
|
||||
|
||||
// Returns a list of directories where target-specific tool binaries are located.
|
||||
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
|
||||
let rustlib_path = rustc_target::target_rustlib_path(self.sysroot, &self.triple);
|
||||
let p = std::array::IntoIter::new([
|
||||
Path::new(&self.sysroot),
|
||||
Path::new(&rustlib_path),
|
||||
Path::new("bin"),
|
||||
])
|
||||
.collect::<PathBuf>();
|
||||
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
||||
|
@ -107,8 +95,8 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
|||
.collect::<PathBuf>()
|
||||
}
|
||||
|
||||
// This function checks if sysroot is found using env::args().next(), and if it
|
||||
// is not found, uses env::current_exe() to imply sysroot.
|
||||
/// This function checks if sysroot is found using env::args().next(), and if it
|
||||
/// is not found, uses env::current_exe() to imply sysroot.
|
||||
pub fn get_or_default_sysroot() -> PathBuf {
|
||||
// Follow symlinks. If the resolved path is relative, make it absolute.
|
||||
fn canonicalize(path: PathBuf) -> PathBuf {
|
||||
|
|
|
@ -9,17 +9,17 @@ pub struct SearchPath {
|
|||
pub files: Vec<SearchPathFile>,
|
||||
}
|
||||
|
||||
// The obvious implementation of `SearchPath::files` is a `Vec<PathBuf>`. But
|
||||
// it is searched repeatedly by `find_library_crate`, and the searches involve
|
||||
// checking the prefix and suffix of the filename of each `PathBuf`. This is
|
||||
// doable, but very slow, because it involves calls to `file_name` and
|
||||
// `extension` that are themselves slow.
|
||||
//
|
||||
// This type augments the `PathBuf` with an `Option<String>` containing the
|
||||
// `PathBuf`'s filename. The prefix and suffix checking is much faster on the
|
||||
// `Option<String>` than the `PathBuf`. (It's an `Option` because
|
||||
// `Path::file_name` can fail; if that happens then all subsequent checking
|
||||
// will also fail, which is fine.)
|
||||
/// The obvious implementation of `SearchPath::files` is a `Vec<PathBuf>`. But
|
||||
/// it is searched repeatedly by `find_library_crate`, and the searches involve
|
||||
/// checking the prefix and suffix of the filename of each `PathBuf`. This is
|
||||
/// doable, but very slow, because it involves calls to `file_name` and
|
||||
/// `extension` that are themselves slow.
|
||||
///
|
||||
/// This type augments the `PathBuf` with an `Option<String>` containing the
|
||||
/// `PathBuf`'s filename. The prefix and suffix checking is much faster on the
|
||||
/// `Option<String>` than the `PathBuf`. (It's an `Option` because
|
||||
/// `Path::file_name` can fail; if that happens then all subsequent checking
|
||||
/// will also fail, which is fine.)
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SearchPathFile {
|
||||
pub path: PathBuf,
|
||||
|
|
|
@ -36,7 +36,7 @@ use std::fmt;
|
|||
use std::io::Write;
|
||||
use std::num::NonZeroU32;
|
||||
use std::ops::{Div, Mul};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
@ -131,9 +131,8 @@ pub struct Session {
|
|||
pub target: Target,
|
||||
pub host: Target,
|
||||
pub opts: config::Options,
|
||||
pub host_tlib_path: SearchPath,
|
||||
/// `None` if the host and target are the same.
|
||||
pub target_tlib_path: Option<SearchPath>,
|
||||
pub host_tlib_path: Lrc<SearchPath>,
|
||||
pub target_tlib_path: Lrc<SearchPath>,
|
||||
pub parse_sess: ParseSess,
|
||||
pub sysroot: PathBuf,
|
||||
/// The name of the root source file of the crate, in the local file system.
|
||||
|
@ -787,8 +786,7 @@ impl Session {
|
|||
&self.sysroot,
|
||||
self.opts.target_triple.triple(),
|
||||
&self.opts.search_paths,
|
||||
// `target_tlib_path == None` means it's the same as `host_tlib_path`.
|
||||
self.target_tlib_path.as_ref().unwrap_or(&self.host_tlib_path),
|
||||
&self.target_tlib_path,
|
||||
kind,
|
||||
)
|
||||
}
|
||||
|
@ -802,6 +800,18 @@ impl Session {
|
|||
)
|
||||
}
|
||||
|
||||
/// Returns a list of directories where target-specific tool binaries are located.
|
||||
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
|
||||
let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, &config::host_triple());
|
||||
let p = std::array::IntoIter::new([
|
||||
Path::new(&self.sysroot),
|
||||
Path::new(&rustlib_path),
|
||||
Path::new("bin"),
|
||||
])
|
||||
.collect::<PathBuf>();
|
||||
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
|
||||
}
|
||||
|
||||
pub fn init_incr_comp_session(
|
||||
&self,
|
||||
session_dir: PathBuf,
|
||||
|
@ -1245,11 +1255,13 @@ pub fn build_session(
|
|||
|
||||
let host_triple = config::host_triple();
|
||||
let target_triple = sopts.target_triple.triple();
|
||||
let host_tlib_path = SearchPath::from_sysroot_and_triple(&sysroot, host_triple);
|
||||
let host_tlib_path = Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, host_triple));
|
||||
let target_tlib_path = if host_triple == target_triple {
|
||||
None
|
||||
// Use the same `SearchPath` if host and target triple are identical to avoid unnecessary
|
||||
// rescanning of the target lib path and an unnecessary allocation.
|
||||
host_tlib_path.clone()
|
||||
} else {
|
||||
Some(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
|
||||
Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
|
||||
};
|
||||
|
||||
let file_path_mapping = sopts.file_path_mapping();
|
||||
|
|
|
@ -722,7 +722,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
let found_did = match *found_trait_ty.kind() {
|
||||
ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
|
||||
ty::Closure(did, _)
|
||||
| ty::Foreign(did)
|
||||
| ty::FnDef(did, _)
|
||||
| ty::Generator(did, ..) => Some(did),
|
||||
ty::Adt(def, _) => Some(def.did),
|
||||
_ => None,
|
||||
};
|
||||
|
|
|
@ -1256,33 +1256,40 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
) -> String {
|
||||
let inputs = trait_ref.skip_binder().substs.type_at(1);
|
||||
let sig = if let ty::Tuple(inputs) = inputs.kind() {
|
||||
tcx.mk_fn_sig(
|
||||
inputs.iter().map(|k| k.expect_ty()),
|
||||
tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
abi::Abi::Rust,
|
||||
)
|
||||
} else {
|
||||
tcx.mk_fn_sig(
|
||||
let sig = match inputs.kind() {
|
||||
ty::Tuple(inputs)
|
||||
if tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some() =>
|
||||
{
|
||||
tcx.mk_fn_sig(
|
||||
inputs.iter().map(|k| k.expect_ty()),
|
||||
tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
abi::Abi::Rust,
|
||||
)
|
||||
}
|
||||
_ => tcx.mk_fn_sig(
|
||||
std::iter::once(inputs),
|
||||
tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
abi::Abi::Rust,
|
||||
)
|
||||
),
|
||||
};
|
||||
trait_ref.rebind(sig).to_string()
|
||||
}
|
||||
|
||||
let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
|
||||
let argument_kind = match expected_ref.skip_binder().substs.type_at(0) {
|
||||
t if t.is_closure() => "closure",
|
||||
t if t.is_generator() => "generator",
|
||||
_ => "function",
|
||||
};
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0631,
|
||||
"type mismatch in {} arguments",
|
||||
if argument_is_closure { "closure" } else { "function" }
|
||||
argument_kind
|
||||
);
|
||||
|
||||
let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found));
|
||||
|
|
|
@ -330,7 +330,11 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<B: ?Sized + ToOwned> Deref for Cow<'_, B> {
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
|
||||
where
|
||||
B::Owned: ~const Borrow<B>,
|
||||
{
|
||||
type Target = B;
|
||||
|
||||
fn deref(&self) -> &B {
|
||||
|
|
|
@ -145,7 +145,8 @@ impl<T: ?Sized> ManuallyDrop<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "manually_drop", since = "1.20.0")]
|
||||
impl<T: ?Sized> Deref for ManuallyDrop<T> {
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
impl<T: ?Sized> const Deref for ManuallyDrop<T> {
|
||||
type Target = T;
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &T {
|
||||
|
@ -154,7 +155,8 @@ impl<T: ?Sized> Deref for ManuallyDrop<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "manually_drop", since = "1.20.0")]
|
||||
impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
impl<T: ?Sized> const DerefMut for ManuallyDrop<T> {
|
||||
#[inline(always)]
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
&mut self.value
|
||||
|
|
|
@ -76,7 +76,8 @@ pub trait Deref {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Deref for &T {
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
impl<T: ?Sized> const Deref for &T {
|
||||
type Target = T;
|
||||
|
||||
#[rustc_diagnostic_item = "noop_method_deref"]
|
||||
|
@ -89,7 +90,8 @@ impl<T: ?Sized> Deref for &T {
|
|||
impl<T: ?Sized> !DerefMut for &T {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Deref for &mut T {
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
impl<T: ?Sized> const Deref for &mut T {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
|
|
|
@ -96,6 +96,18 @@ pub struct Incoming<'a> {
|
|||
listener: &'a TcpListener,
|
||||
}
|
||||
|
||||
/// An iterator that infinitely [`accept`]s connections on a [`TcpListener`].
|
||||
///
|
||||
/// This `struct` is created by the [`TcpListener::into_incoming`] method.
|
||||
/// See its documentation for more.
|
||||
///
|
||||
/// [`accept`]: TcpListener::accept
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
pub struct IntoIncoming {
|
||||
listener: TcpListener,
|
||||
}
|
||||
|
||||
impl TcpStream {
|
||||
/// Opens a TCP connection to a remote host.
|
||||
///
|
||||
|
@ -845,6 +857,37 @@ impl TcpListener {
|
|||
Incoming { listener: self }
|
||||
}
|
||||
|
||||
/// Turn this into an iterator over the connections being received on this
|
||||
/// listener.
|
||||
///
|
||||
/// The returned iterator will never return [`None`] and will also not yield
|
||||
/// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to
|
||||
/// calling [`TcpListener::accept`] in a loop.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(tcplistener_into_incoming)]
|
||||
/// use std::net::{TcpListener, TcpStream};
|
||||
///
|
||||
/// fn listen_on(port: u16) -> impl Iterator<Item = TcpStream> {
|
||||
/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
|
||||
/// listener.into_incoming()
|
||||
/// .filter_map(Result::ok) /* Ignore failed connections */
|
||||
/// }
|
||||
///
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
/// for stream in listen_on(80) {
|
||||
/// /* handle the connection here */
|
||||
/// }
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
pub fn into_incoming(self) -> IntoIncoming {
|
||||
IntoIncoming { listener: self }
|
||||
}
|
||||
|
||||
/// Sets the value for the `IP_TTL` option on this socket.
|
||||
///
|
||||
/// This value sets the time-to-live field that is used in every packet sent
|
||||
|
@ -982,6 +1025,14 @@ impl<'a> Iterator for Incoming<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
impl Iterator for IntoIncoming {
|
||||
type Item = io::Result<TcpStream>;
|
||||
fn next(&mut self) -> Option<io::Result<TcpStream>> {
|
||||
Some(self.listener.accept().map(|p| p.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<net_imp::TcpListener> for TcpListener {
|
||||
fn as_inner(&self) -> &net_imp::TcpListener {
|
||||
&self.0
|
||||
|
|
|
@ -96,6 +96,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo
|
|||
|
||||
if cx.tcx.hir().attrs(hir_id).lists(sym::doc).has_word(sym::hidden)
|
||||
|| inherits_doc_hidden(cx.tcx, hir_id)
|
||||
|| cx.tcx.hir().span(hir_id).in_derive_expansion()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,17 @@ def convert_to_string(s):
|
|||
return s
|
||||
|
||||
|
||||
def set_ld_lib_path():
|
||||
var = os.environ.get("LD_LIB_PATH_ENVVAR")
|
||||
rpath = os.environ.get("HOST_RPATH_DIR")
|
||||
if var and rpath:
|
||||
path = os.environ.get(var)
|
||||
if path:
|
||||
os.environ[var] = rpath + os.pathsep + path
|
||||
else:
|
||||
os.environ[var] = rpath
|
||||
|
||||
|
||||
def exec_command(command, to_input=None):
|
||||
child = None
|
||||
if to_input is None:
|
||||
|
@ -50,7 +61,9 @@ def get_all_libs(dir_path):
|
|||
if isfile(join(dir_path, f)) and f.endswith('.rlib') and f not in STABLE_CRATES]
|
||||
|
||||
|
||||
set_ld_lib_path()
|
||||
sysroot = exec_command([os.environ['RUSTC'], '--print', 'sysroot'])[0].replace('\n', '')
|
||||
assert sysroot, "Could not read the rustc sysroot!"
|
||||
libs = get_all_libs(join(sysroot, 'lib/rustlib/{}/lib'.format(os.environ['TARGET'])))
|
||||
|
||||
ret = 0
|
||||
|
|
|
@ -78,6 +78,15 @@ impl Clone for Struct {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/// doc
|
||||
///
|
||||
/// ```
|
||||
/// println!("hello");
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
pub struct NiceStruct;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod foo {
|
||||
pub fn bar() {}
|
||||
|
|
19
src/test/ui/generator/issue-88653.rs
Normal file
19
src/test/ui/generator/issue-88653.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Regression test for #88653, where a confusing warning about a
|
||||
// type mismatch in generator arguments was issued.
|
||||
|
||||
#![feature(generators, generator_trait)]
|
||||
|
||||
use std::ops::Generator;
|
||||
|
||||
fn foo(bar: bool) -> impl Generator<(bool,)> {
|
||||
//~^ ERROR: type mismatch in generator arguments [E0631]
|
||||
//~| NOTE: expected signature of `fn((bool,)) -> _`
|
||||
|bar| {
|
||||
//~^ NOTE: found signature of `fn(bool) -> _`
|
||||
if bar {
|
||||
yield bar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
12
src/test/ui/generator/issue-88653.stderr
Normal file
12
src/test/ui/generator/issue-88653.stderr
Normal file
|
@ -0,0 +1,12 @@
|
|||
error[E0631]: type mismatch in generator arguments
|
||||
--> $DIR/issue-88653.rs:8:22
|
||||
|
|
||||
LL | fn foo(bar: bool) -> impl Generator<(bool,)> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _`
|
||||
...
|
||||
LL | |bar| {
|
||||
| ----- found signature of `fn(bool) -> _`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0631`.
|
7
src/test/ui/inference/issue-71309.rs
Normal file
7
src/test/ui/inference/issue-71309.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
fn foo(x: Result<i32, ()>) -> Result<(), ()> {
|
||||
let y: u32 = x?;
|
||||
//~^ ERROR: `?` operator has incompatible types
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {}
|
15
src/test/ui/inference/issue-71309.stderr
Normal file
15
src/test/ui/inference/issue-71309.stderr
Normal file
|
@ -0,0 +1,15 @@
|
|||
error[E0308]: `?` operator has incompatible types
|
||||
--> $DIR/issue-71309.rs:2:18
|
||||
|
|
||||
LL | let y: u32 = x?;
|
||||
| ^^ expected `u32`, found `i32`
|
||||
|
|
||||
= note: `?` operator cannot convert from `i32` to `u32`
|
||||
help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
|
||||
|
|
||||
LL | let y: u32 = x?.try_into().unwrap();
|
||||
| ++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
|
@ -6,7 +6,7 @@ fn missing_discourses() -> Result<isize, ()> {
|
|||
|
||||
fn forbidden_narratives() -> Result<isize, ()> {
|
||||
missing_discourses()?
|
||||
//~^ ERROR try expression alternatives have incompatible types
|
||||
//~^ ERROR: `?` operator has incompatible types
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
error[E0308]: try expression alternatives have incompatible types
|
||||
error[E0308]: `?` operator has incompatible types
|
||||
--> $DIR/issue-51632-try-desugar-incompatible-types.rs:8:5
|
||||
|
|
||||
LL | missing_discourses()?
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `isize`
|
||||
|
|
||||
= note: `?` operator cannot convert from `isize` to `Result<isize, ()>`
|
||||
= note: expected enum `Result<isize, ()>`
|
||||
found type `isize`
|
||||
help: try removing this `?`
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![warn(clashing_extern_declarations)]
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
extern "C" {
|
||||
#[link_name = "malloc"]
|
||||
fn malloc1(len: i32) -> *const u8;
|
||||
#[link_name = "malloc"]
|
||||
//~^ WARN `malloc2` redeclares `malloc` with a different signature
|
||||
fn malloc2(len: i32, foo: i32) -> *const u8;
|
||||
}
|
||||
|
||||
pub fn main() {}
|
|
@ -1,21 +0,0 @@
|
|||
warning: `malloc2` redeclares `malloc` with a different signature
|
||||
--> $DIR/issue-5791.rs:9:5
|
||||
|
|
||||
LL | / #[link_name = "malloc"]
|
||||
LL | | fn malloc1(len: i32) -> *const u8;
|
||||
| |______________________________________- `malloc` previously declared here
|
||||
LL | / #[link_name = "malloc"]
|
||||
LL | |
|
||||
LL | | fn malloc2(len: i32, foo: i32) -> *const u8;
|
||||
| |________________________________________________^ this signature doesn't match the previous declaration
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-5791.rs:3:9
|
||||
|
|
||||
LL | #![warn(clashing_extern_declarations)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: expected `unsafe extern "C" fn(i32) -> *const u8`
|
||||
found `unsafe extern "C" fn(i32, i32) -> *const u8`
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
12
src/test/ui/repr/repr-transparent-issue-87496.rs
Normal file
12
src/test/ui/repr/repr-transparent-issue-87496.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Regression test for the ICE described in #87496.
|
||||
|
||||
// check-pass
|
||||
|
||||
#[repr(transparent)]
|
||||
struct TransparentCustomZst(());
|
||||
extern "C" {
|
||||
fn good17(p: TransparentCustomZst);
|
||||
//~^ WARNING: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe
|
||||
}
|
||||
|
||||
fn main() {}
|
16
src/test/ui/repr/repr-transparent-issue-87496.stderr
Normal file
16
src/test/ui/repr/repr-transparent-issue-87496.stderr
Normal file
|
@ -0,0 +1,16 @@
|
|||
warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe
|
||||
--> $DIR/repr-transparent-issue-87496.rs:8:18
|
||||
|
|
||||
LL | fn good17(p: TransparentCustomZst);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: `#[warn(improper_ctypes)]` on by default
|
||||
= note: this struct contains only zero-sized fields
|
||||
note: the type is defined here
|
||||
--> $DIR/repr-transparent-issue-87496.rs:6:1
|
||||
|
|
||||
LL | struct TransparentCustomZst(());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -7,8 +7,8 @@ use std::path::Path;
|
|||
|
||||
const ENTRY_LIMIT: usize = 1000;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ROOT_ENTRY_LIMIT: usize = 1345;
|
||||
const ISSUES_ENTRY_LIMIT: usize = 2525;
|
||||
const ROOT_ENTRY_LIMIT: usize = 1330;
|
||||
const ISSUES_ENTRY_LIMIT: usize = 2488;
|
||||
|
||||
fn check_entries(path: &Path, bad: &mut bool) {
|
||||
let dirs = walkdir::WalkDir::new(&path.join("test/ui"))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue