Auto merge of #104418 - matthiaskrgr:rollup-y4i6xjc, r=matthiaskrgr

Rollup of 11 pull requests

Successful merges:

 - #101967 (Move `unix_socket_abstract` feature API to `SocketAddrExt`.)
 - #102470 (Stabilize const char convert)
 - #104223 (Recover from function pointer types with generic parameter list)
 - #104229 (Don't print full paths in overlap errors)
 - #104294 (Don't ICE with inline const errors during MIR build)
 - #104332 (Fixed some `_i32` notation in `maybe_uninit`’s doc)
 - #104349 (fix some typos in comments)
 - #104350 (Fix x finding Python on Windows)
 - #104356 (interpret: make check_mplace public)
 - #104364 (rustdoc: Resolve doc links in external traits having local impls)
 - #104378 (Bump chalk to v0.87)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-15 03:37:07 +00:00
commit 101e1822c3
82 changed files with 648 additions and 420 deletions

View File

@ -502,9 +502,9 @@ dependencies = [
[[package]] [[package]]
name = "chalk-derive" name = "chalk-derive"
version = "0.80.0" version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0001adf0cf12361e08b65e1898ea138f8f77d8f5177cbf29b6b3b3532252bd6" checksum = "d552b2fa341f5fc35c6b917b1d289d3c3a34d0b74e579390ea6192d6152a8cdb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -514,9 +514,9 @@ dependencies = [
[[package]] [[package]]
name = "chalk-engine" name = "chalk-engine"
version = "0.80.0" version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c44ee96f2d67cb5193d1503f185db1abad9933a1c6e6b4169c176f90baecd393" checksum = "7e54ac43048cb31c470d7b3e3acd409090ef4a5abddfe02455187aebc3d6879f"
dependencies = [ dependencies = [
"chalk-derive", "chalk-derive",
"chalk-ir", "chalk-ir",
@ -527,9 +527,9 @@ dependencies = [
[[package]] [[package]]
name = "chalk-ir" name = "chalk-ir"
version = "0.80.0" version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d8a95548f23618fda86426e4304e563ec2bb7ba0216139f0748d63c107b5f1" checksum = "43aa55deff4e7fbdb09fa014543372f2c95a06835ac487b9ce57b5099b950838"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"chalk-derive", "chalk-derive",
@ -538,9 +538,9 @@ dependencies = [
[[package]] [[package]]
name = "chalk-solve" name = "chalk-solve"
version = "0.80.0" version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f37f492dacfafe2e21319b80827da2779932909bb392f0cc86b2bd5c07c1b4e1" checksum = "61213deefc36ba265ad01c4d997e18bcddf7922862a4594a47ca4575afb3dab4"
dependencies = [ dependencies = [
"chalk-derive", "chalk-derive",
"chalk-ir", "chalk-ir",

View File

@ -376,7 +376,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Read an immediate from a place, asserting that that is possible with the given layout. /// Read an immediate from a place, asserting that that is possible with the given layout.
/// ///
/// If this suceeds, the `ImmTy` is never `Uninit`. /// If this succeeds, the `ImmTy` is never `Uninit`.
#[inline(always)] #[inline(always)]
pub fn read_immediate( pub fn read_immediate(
&self, &self,

View File

@ -316,8 +316,7 @@ where
Ok(MPlaceTy { mplace, layout, align }) Ok(MPlaceTy { mplace, layout, align })
} }
/// Take an operand, representing a pointer, and dereference it to a place -- that /// Take an operand, representing a pointer, and dereference it to a place.
/// will always be a MemPlace. Lives in `place.rs` because it creates a place.
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
pub fn deref_operand( pub fn deref_operand(
&self, &self,
@ -331,7 +330,7 @@ where
} }
let mplace = self.ref_to_mplace(&val)?; let mplace = self.ref_to_mplace(&val)?;
self.check_mplace_access(mplace, CheckInAllocMsg::DerefTest)?; self.check_mplace(mplace)?;
Ok(mplace) Ok(mplace)
} }
@ -358,17 +357,18 @@ where
} }
/// Check if this mplace is dereferenceable and sufficiently aligned. /// Check if this mplace is dereferenceable and sufficiently aligned.
fn check_mplace_access( pub fn check_mplace(&self, mplace: MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
&self,
mplace: MPlaceTy<'tcx, M::Provenance>,
msg: CheckInAllocMsg,
) -> InterpResult<'tcx> {
let (size, align) = self let (size, align) = self
.size_and_align_of_mplace(&mplace)? .size_and_align_of_mplace(&mplace)?
.unwrap_or((mplace.layout.size, mplace.layout.align.abi)); .unwrap_or((mplace.layout.size, mplace.layout.align.abi));
assert!(mplace.align <= align, "dynamic alignment less strict than static one?"); assert!(mplace.align <= align, "dynamic alignment less strict than static one?");
let align = M::enforce_alignment(self).then_some(align); let align = M::enforce_alignment(self).then_some(align);
self.check_ptr_access_align(mplace.ptr, size, align.unwrap_or(Align::ONE), msg)?; self.check_ptr_access_align(
mplace.ptr,
size,
align.unwrap_or(Align::ONE),
CheckInAllocMsg::DerefTest,
)?;
Ok(()) Ok(())
} }

View File

@ -375,3 +375,12 @@ parser_async_move_order_incorrect = the order of `move` and `async` is incorrect
parser_double_colon_in_bound = expected `:` followed by trait or lifetime parser_double_colon_in_bound = expected `:` followed by trait or lifetime
.suggestion = use single colon .suggestion = use single colon
parser_fn_ptr_with_generics = function pointer types may not have generic parameters
.suggestion = consider moving the lifetime {$arity ->
[one] parameter
*[other] parameters
} to {$for_param_list_exists ->
[true] the
*[false] a
} `for` parameter list

View File

@ -1254,6 +1254,10 @@ impl HandlerInner {
} }
if diagnostic.has_future_breakage() { if diagnostic.has_future_breakage() {
// Future breakages aren't emitted if they're Level::Allowed,
// but they still need to be constructed and stashed below,
// so they'll trigger the good-path bug check.
self.suppressed_expected_diag = true;
self.future_breakage_diagnostics.push(diagnostic.clone()); self.future_breakage_diagnostics.push(diagnostic.clone());
} }

View File

@ -333,7 +333,7 @@ fn expand_macro<'cx>(
assert!(try_success_result.is_err(), "Macro matching returned a success on the second try"); assert!(try_success_result.is_err(), "Macro matching returned a success on the second try");
if let Some(result) = tracker.result { if let Some(result) = tracker.result {
// An irrecoverable error occured and has been emitted. // An irrecoverable error occurred and has been emitted.
return result; return result;
} }

View File

@ -147,7 +147,7 @@ pub enum AttributeDuplicates {
FutureWarnPreceding, FutureWarnPreceding,
} }
/// A conveniece macro to deal with `$($expr)?`. /// A convenience macro to deal with `$($expr)?`.
macro_rules! or_default { macro_rules! or_default {
($default:expr,) => { ($default:expr,) => {
$default $default

View File

@ -35,7 +35,7 @@ struct ClosureSignatures<'tcx> {
bound_sig: ty::PolyFnSig<'tcx>, bound_sig: ty::PolyFnSig<'tcx>,
/// The signature within the function body. /// The signature within the function body.
/// This mostly differs in the sense that lifetimes are now early bound and any /// This mostly differs in the sense that lifetimes are now early bound and any
/// opaque types from the signature expectation are overriden in case there are /// opaque types from the signature expectation are overridden in case there are
/// explicit hidden types written by the user in the closure signature. /// explicit hidden types written by the user in the closure signature.
liberated_sig: ty::FnSig<'tcx>, liberated_sig: ty::FnSig<'tcx>,
} }

View File

@ -360,7 +360,7 @@ fn lint_int_literal<'tcx>(
} }
if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) { if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
// The overflowing literal lint was emited by `lint_overflowing_range_endpoint`. // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
return; return;
} }
@ -429,7 +429,7 @@ fn lint_uint_literal<'tcx>(
} }
} }
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) { if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
// The overflowing literal lint was emited by `lint_overflowing_range_endpoint`. // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
return; return;
} }
if let Some(repr_str) = get_bin_hex_repr(cx, lit) { if let Some(repr_str) = get_bin_hex_repr(cx, lit) {

View File

@ -8,7 +8,7 @@ doctest = false
[dependencies] [dependencies]
bitflags = "1.2.1" bitflags = "1.2.1"
chalk-ir = "0.80.0" chalk-ir = "0.87.0"
either = "1.5.0" either = "1.5.0"
gsgdt = "0.1.2" gsgdt = "0.1.2"
polonius-engine = "0.13.0" polonius-engine = "0.13.0"

View File

@ -1541,7 +1541,7 @@ impl<'tcx> Place<'tcx> {
/// If MirPhase >= Derefered and if projection contains Deref, /// If MirPhase >= Derefered and if projection contains Deref,
/// It's guaranteed to be in the first place /// It's guaranteed to be in the first place
pub fn has_deref(&self) -> bool { pub fn has_deref(&self) -> bool {
// To make sure this is not accidently used in wrong mir phase // To make sure this is not accidentally used in wrong mir phase
debug_assert!( debug_assert!(
self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref) self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
); );

View File

@ -85,7 +85,7 @@ pub enum MirPhase {
/// ///
/// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part /// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part
/// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that /// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that
/// transformations which may supress such errors should not run on analysis MIR. /// transformations which may suppress such errors should not run on analysis MIR.
Runtime(RuntimePhase), Runtime(RuntimePhase),
} }

View File

@ -118,7 +118,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
else_block: Some(else_block), else_block: Some(else_block),
} => { } => {
// When lowering the statement `let <pat> = <expr> else { <else> };`, // When lowering the statement `let <pat> = <expr> else { <else> };`,
// the `<else>` block is nested in the parent scope enclosing this statment. // the `<else>` block is nested in the parent scope enclosing this statement.
// That scope is usually either the enclosing block scope, // That scope is usually either the enclosing block scope,
// or the remainder scope of the last statement. // or the remainder scope of the last statement.
// This is to make sure that temporaries instantiated in `<expr>` are dropped // This is to make sure that temporaries instantiated in `<expr>` are dropped

View File

@ -577,6 +577,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
self.errors.push(PatternError::ConstParamInPattern(span)); self.errors.push(PatternError::ConstParamInPattern(span));
return PatKind::Wild; return PatKind::Wild;
} }
ConstKind::Error(_) => {
return PatKind::Wild;
}
_ => bug!("Expected ConstKind::Param"), _ => bug!("Expected ConstKind::Param"),
}, },
mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind, mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,

View File

@ -1280,3 +1280,24 @@ pub(crate) struct DoubleColonInBound {
#[suggestion(code = ": ", applicability = "machine-applicable")] #[suggestion(code = ": ", applicability = "machine-applicable")]
pub between: Span, pub between: Span,
} }
#[derive(Diagnostic)]
#[diag(parser_fn_ptr_with_generics)]
pub(crate) struct FnPtrWithGenerics {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub sugg: Option<FnPtrWithGenericsSugg>,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
pub(crate) struct FnPtrWithGenericsSugg {
#[suggestion_part(code = "{snippet}")]
pub left: Span,
pub snippet: String,
#[suggestion_part(code = "")]
pub right: Span,
pub arity: usize,
pub for_param_list_exists: bool,
}

View File

@ -3,6 +3,7 @@
#![feature(array_windows)] #![feature(array_windows)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(let_chains)] #![feature(let_chains)]
#![feature(never_type)] #![feature(never_type)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]

View File

@ -1,5 +1,6 @@
use super::{Parser, PathStyle, TokenType}; use super::{Parser, PathStyle, TokenType};
use crate::errors::{FnPtrWithGenerics, FnPtrWithGenericsSugg};
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
@ -270,14 +271,19 @@ impl<'a> Parser<'a> {
TyKind::Infer TyKind::Infer
} else if self.check_fn_front_matter(false, Case::Sensitive) { } else if self.check_fn_front_matter(false, Case::Sensitive) {
// Function pointer type // Function pointer type
self.parse_ty_bare_fn(lo, Vec::new(), recover_return_sign)? self.parse_ty_bare_fn(lo, Vec::new(), None, recover_return_sign)?
} else if self.check_keyword(kw::For) { } else if self.check_keyword(kw::For) {
// Function pointer type or bound list (trait object type) starting with a poly-trait. // Function pointer type or bound list (trait object type) starting with a poly-trait.
// `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
// `for<'lt> Trait1<'lt> + Trait2 + 'a` // `for<'lt> Trait1<'lt> + Trait2 + 'a`
let lifetime_defs = self.parse_late_bound_lifetime_defs()?; let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
if self.check_fn_front_matter(false, Case::Sensitive) { if self.check_fn_front_matter(false, Case::Sensitive) {
self.parse_ty_bare_fn(lo, lifetime_defs, recover_return_sign)? self.parse_ty_bare_fn(
lo,
lifetime_defs,
Some(self.prev_token.span.shrink_to_lo()),
recover_return_sign,
)?
} else { } else {
let path = self.parse_path(PathStyle::Type)?; let path = self.parse_path(PathStyle::Type)?;
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
@ -519,7 +525,8 @@ impl<'a> Parser<'a> {
fn parse_ty_bare_fn( fn parse_ty_bare_fn(
&mut self, &mut self,
lo: Span, lo: Span,
params: Vec<GenericParam>, mut params: Vec<GenericParam>,
param_insertion_point: Option<Span>,
recover_return_sign: RecoverReturnSign, recover_return_sign: RecoverReturnSign,
) -> PResult<'a, TyKind> { ) -> PResult<'a, TyKind> {
let inherited_vis = rustc_ast::Visibility { let inherited_vis = rustc_ast::Visibility {
@ -530,6 +537,9 @@ impl<'a> Parser<'a> {
let span_start = self.token.span; let span_start = self.token.span;
let ast::FnHeader { ext, unsafety, constness, asyncness } = let ast::FnHeader { ext, unsafety, constness, asyncness } =
self.parse_fn_front_matter(&inherited_vis)?; self.parse_fn_front_matter(&inherited_vis)?;
if self.may_recover() && self.token.kind == TokenKind::Lt {
self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
}
let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?; let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
let whole_span = lo.to(self.prev_token.span); let whole_span = lo.to(self.prev_token.span);
if let ast::Const::Yes(span) = constness { if let ast::Const::Yes(span) = constness {
@ -545,6 +555,48 @@ impl<'a> Parser<'a> {
Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span }))) Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span })))
} }
/// Recover from function pointer types with a generic parameter list (e.g. `fn<'a>(&'a str)`).
fn recover_fn_ptr_with_generics(
&mut self,
lo: Span,
params: &mut Vec<GenericParam>,
param_insertion_point: Option<Span>,
) -> PResult<'a, ()> {
let generics = self.parse_generics()?;
let arity = generics.params.len();
let mut lifetimes: Vec<_> = generics
.params
.into_iter()
.filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
.collect();
let sugg = if !lifetimes.is_empty() {
let snippet =
lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
let (left, snippet) = if let Some(span) = param_insertion_point {
(span, if params.is_empty() { snippet } else { format!(", {snippet}") })
} else {
(lo.shrink_to_lo(), format!("for<{snippet}> "))
};
Some(FnPtrWithGenericsSugg {
left,
snippet,
right: generics.span,
arity,
for_param_list_exists: param_insertion_point.is_some(),
})
} else {
None
};
self.sess.emit_err(FnPtrWithGenerics { span: generics.span, sugg });
params.append(&mut lifetimes);
Ok(())
}
/// Emit an error for the given bad function pointer qualifier. /// Emit an error for the given bad function pointer qualifier.
fn error_fn_ptr_bad_qualifier(&self, span: Span, qual_span: Span, qual: &str) { fn error_fn_ptr_bad_qualifier(&self, span: Span, qual_span: Span, qual: &str) {
self.struct_span_err(span, &format!("an `fn` pointer type cannot be `{}`", qual)) self.struct_span_err(span, &format!("an `fn` pointer type cannot be `{}`", qual))

View File

@ -72,7 +72,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
update(node_id); update(node_id);
if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind { if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind {
// In theory all the single import IDs have individual visibilities and // In theory all the single import IDs have individual visibilities and
// effective visibilities, but in practice these IDs go straigth to HIR // effective visibilities, but in practice these IDs go straight to HIR
// where all their few uses assume that their (effective) visibility // where all their few uses assume that their (effective) visibility
// applies to the whole syntactic `use` item. So they all get the same // applies to the whole syntactic `use` item. So they all get the same
// value which is the maximum of all bindings. Maybe HIR for imports // value which is the maximum of all bindings. Maybe HIR for imports

View File

@ -1932,6 +1932,11 @@ impl<'a> Resolver<'a> {
} }
} }
/// For rustdoc.
pub fn get_partial_res(&self, node_id: NodeId) -> Option<PartialRes> {
self.partial_res_map.get(&node_id).copied()
}
/// Retrieves the span of the given `DefId` if `DefId` is in the local crate. /// Retrieves the span of the given `DefId` if `DefId` is in the local crate.
#[inline] #[inline]
pub fn opt_span(&self, def_id: DefId) -> Option<Span> { pub fn opt_span(&self, def_id: DefId) -> Option<Span> {

View File

@ -114,7 +114,7 @@ pub enum Lld {
/// relevant now. /// relevant now.
/// ///
/// The second goal is to keep the number of flavors to the minimum if possible. /// The second goal is to keep the number of flavors to the minimum if possible.
/// LLD somewhat forces our hand here because that linker is self-sufficent only if its executable /// LLD somewhat forces our hand here because that linker is self-sufficient only if its executable
/// (`argv[0]`) is named in specific way, otherwise it doesn't work and requires a /// (`argv[0]`) is named in specific way, otherwise it doesn't work and requires a
/// `-flavor LLD_FLAVOR` argument to choose which logic to use. Our shipped `rust-lld` in /// `-flavor LLD_FLAVOR` argument to choose which logic to use. Our shipped `rust-lld` in
/// particular is not named in such specific way, so it needs the flavor option, so we make our /// particular is not named in such specific way, so it needs the flavor option, so we make our

View File

@ -58,10 +58,10 @@ pub struct NoValueInOnUnimplemented {
pub span: Span, pub span: Span,
} }
pub struct NegativePositiveConflict<'a> { pub struct NegativePositiveConflict<'tcx> {
pub impl_span: Span, pub impl_span: Span,
pub trait_desc: &'a str, pub trait_desc: ty::TraitRef<'tcx>,
pub self_desc: &'a Option<String>, pub self_ty: Option<Ty<'tcx>>,
pub negative_impl_span: Result<Span, Symbol>, pub negative_impl_span: Result<Span, Symbol>,
pub positive_impl_span: Result<Span, Symbol>, pub positive_impl_span: Result<Span, Symbol>,
} }
@ -73,10 +73,10 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> {
handler: &Handler, handler: &Handler,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = handler.struct_err(fluent::trait_selection_negative_positive_conflict); let mut diag = handler.struct_err(fluent::trait_selection_negative_positive_conflict);
diag.set_arg("trait_desc", self.trait_desc); diag.set_arg("trait_desc", self.trait_desc.print_only_trait_path().to_string());
diag.set_arg( diag.set_arg(
"self_desc", "self_desc",
self.self_desc.clone().map_or_else(|| String::from("none"), |ty| ty), self.self_ty.map_or_else(|| "none".to_string(), |ty| ty.to_string()),
); );
diag.set_span(self.impl_span); diag.set_span(self.impl_span);
diag.code(rustc_errors::error_code!(E0751)); diag.code(rustc_errors::error_code!(E0751));

View File

@ -64,13 +64,13 @@ pub fn add_placeholder_note(err: &mut Diagnostic) {
/// with a suitably-freshened `ImplHeader` with those types /// with a suitably-freshened `ImplHeader` with those types
/// substituted. Otherwise, returns `None`. /// substituted. Otherwise, returns `None`.
#[instrument(skip(tcx, skip_leak_check), level = "debug")] #[instrument(skip(tcx, skip_leak_check), level = "debug")]
pub fn overlapping_impls( pub fn overlapping_impls<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
impl1_def_id: DefId, impl1_def_id: DefId,
impl2_def_id: DefId, impl2_def_id: DefId,
skip_leak_check: SkipLeakCheck, skip_leak_check: SkipLeakCheck,
overlap_mode: OverlapMode, overlap_mode: OverlapMode,
) -> Option<OverlapResult<'_>> { ) -> Option<OverlapResult<'tcx>> {
// Before doing expensive operations like entering an inference context, do // Before doing expensive operations like entering an inference context, do
// a quick check via fast_reject to tell if the impl headers could possibly // a quick check via fast_reject to tell if the impl headers could possibly
// unify. // unify.

View File

@ -19,9 +19,9 @@ use crate::traits::engine::TraitEngineExt as _;
use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause}; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee}; use rustc_errors::{error_code, DelayDm, Diagnostic};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::{self, ImplSubject, TyCtxt}; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt};
use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
@ -32,10 +32,10 @@ use super::SelectionContext;
/// Information pertinent to an overlapping impl error. /// Information pertinent to an overlapping impl error.
#[derive(Debug)] #[derive(Debug)]
pub struct OverlapError { pub struct OverlapError<'tcx> {
pub with_impl: DefId, pub with_impl: DefId,
pub trait_desc: String, pub trait_ref: ty::TraitRef<'tcx>,
pub self_desc: Option<String>, pub self_ty: Option<Ty<'tcx>>,
pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>, pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>,
pub involves_placeholder: bool, pub involves_placeholder: bool,
} }
@ -275,9 +275,9 @@ pub(super) fn specialization_graph_provider(
// it negatively impacts perf. // it negatively impacts perf.
#[cold] #[cold]
#[inline(never)] #[inline(never)]
fn report_overlap_conflict( fn report_overlap_conflict<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
overlap: OverlapError, overlap: OverlapError<'tcx>,
impl_def_id: LocalDefId, impl_def_id: LocalDefId,
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>, used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
sg: &mut specialization_graph::Graph, sg: &mut specialization_graph::Graph,
@ -313,9 +313,9 @@ fn report_overlap_conflict(
} }
} }
fn report_negative_positive_conflict( fn report_negative_positive_conflict<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
overlap: &OverlapError, overlap: &OverlapError<'tcx>,
local_impl_def_id: LocalDefId, local_impl_def_id: LocalDefId,
negative_impl_def_id: DefId, negative_impl_def_id: DefId,
positive_impl_def_id: DefId, positive_impl_def_id: DefId,
@ -323,17 +323,17 @@ fn report_negative_positive_conflict(
) { ) {
let mut err = tcx.sess.create_err(NegativePositiveConflict { let mut err = tcx.sess.create_err(NegativePositiveConflict {
impl_span: tcx.def_span(local_impl_def_id), impl_span: tcx.def_span(local_impl_def_id),
trait_desc: &overlap.trait_desc, trait_desc: overlap.trait_ref,
self_desc: &overlap.self_desc, self_ty: overlap.self_ty,
negative_impl_span: tcx.span_of_impl(negative_impl_def_id), negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
positive_impl_span: tcx.span_of_impl(positive_impl_def_id), positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
}); });
sg.has_errored = Some(err.emit()); sg.has_errored = Some(err.emit());
} }
fn report_conflicting_impls( fn report_conflicting_impls<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
overlap: OverlapError, overlap: OverlapError<'tcx>,
impl_def_id: LocalDefId, impl_def_id: LocalDefId,
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>, used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
sg: &mut specialization_graph::Graph, sg: &mut specialization_graph::Graph,
@ -343,12 +343,12 @@ fn report_conflicting_impls(
// Work to be done after we've built the DiagnosticBuilder. We have to define it // Work to be done after we've built the DiagnosticBuilder. We have to define it
// now because the struct_lint methods don't return back the DiagnosticBuilder // now because the struct_lint methods don't return back the DiagnosticBuilder
// that's passed in. // that's passed in.
fn decorate<'a, 'b, G: EmissionGuarantee>( fn decorate<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
overlap: OverlapError, overlap: &OverlapError<'tcx>,
impl_span: Span, impl_span: Span,
err: &'b mut DiagnosticBuilder<'a, G>, err: &mut Diagnostic,
) -> &'b mut DiagnosticBuilder<'a, G> { ) {
match tcx.span_of_impl(overlap.with_impl) { match tcx.span_of_impl(overlap.with_impl) {
Ok(span) => { Ok(span) => {
err.span_label(span, "first implementation here"); err.span_label(span, "first implementation here");
@ -357,7 +357,7 @@ fn report_conflicting_impls(
impl_span, impl_span,
format!( format!(
"conflicting implementation{}", "conflicting implementation{}",
overlap.self_desc.map_or_else(String::new, |ty| format!(" for `{}`", ty)) overlap.self_ty.map_or_else(String::new, |ty| format!(" for `{}`", ty))
), ),
); );
} }
@ -379,26 +379,28 @@ fn report_conflicting_impls(
if overlap.involves_placeholder { if overlap.involves_placeholder {
coherence::add_placeholder_note(err); coherence::add_placeholder_note(err);
} }
err
} }
let msg = format!( let msg = DelayDm(|| {
"conflicting implementations of trait `{}`{}{}", format!(
overlap.trait_desc, "conflicting implementations of trait `{}`{}{}",
overlap.self_desc.as_deref().map_or_else(String::new, |ty| format!(" for type `{ty}`")), overlap.trait_ref.print_only_trait_path(),
match used_to_be_allowed { overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")),
Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)", match used_to_be_allowed {
_ => "", Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
} _ => "",
); }
)
});
match used_to_be_allowed { match used_to_be_allowed {
None => { None => {
let reported = if overlap.with_impl.is_local() let reported = if overlap.with_impl.is_local()
|| tcx.orphan_check_impl(impl_def_id).is_ok() || tcx.orphan_check_impl(impl_def_id).is_ok()
{ {
let mut err = struct_span_err!(tcx.sess, impl_span, E0119, "{msg}",); let mut err = tcx.sess.struct_span_err(impl_span, msg);
decorate(tcx, overlap, impl_span, &mut err); err.code(error_code!(E0119));
decorate(tcx, &overlap, impl_span, &mut err);
Some(err.emit()) Some(err.emit())
} else { } else {
Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check")) Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
@ -415,7 +417,10 @@ fn report_conflicting_impls(
tcx.hir().local_def_id_to_hir_id(impl_def_id), tcx.hir().local_def_id_to_hir_id(impl_def_id),
impl_span, impl_span,
msg, msg,
|err| decorate(tcx, overlap, impl_span, err), |err| {
decorate(tcx, &overlap, impl_span, err);
err
},
); );
} }
}; };

View File

@ -3,7 +3,6 @@ use super::OverlapError;
use crate::traits; use crate::traits;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
pub use rustc_middle::traits::specialization_graph::*; pub use rustc_middle::traits::specialization_graph::*;
@ -15,15 +14,15 @@ pub enum FutureCompatOverlapErrorKind {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct FutureCompatOverlapError { pub struct FutureCompatOverlapError<'tcx> {
pub error: OverlapError, pub error: OverlapError<'tcx>,
pub kind: FutureCompatOverlapErrorKind, pub kind: FutureCompatOverlapErrorKind,
} }
/// The result of attempting to insert an impl into a group of children. /// The result of attempting to insert an impl into a group of children.
enum Inserted { enum Inserted<'tcx> {
/// The impl was inserted as a new child in this group of children. /// The impl was inserted as a new child in this group of children.
BecameNewSibling(Option<FutureCompatOverlapError>), BecameNewSibling(Option<FutureCompatOverlapError<'tcx>>),
/// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc. /// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc.
ReplaceChildren(Vec<DefId>), ReplaceChildren(Vec<DefId>),
@ -42,12 +41,12 @@ trait ChildrenExt<'tcx> {
impl_def_id: DefId, impl_def_id: DefId,
simplified_self: Option<SimplifiedType>, simplified_self: Option<SimplifiedType>,
overlap_mode: OverlapMode, overlap_mode: OverlapMode,
) -> Result<Inserted, OverlapError>; ) -> Result<Inserted<'tcx>, OverlapError<'tcx>>;
} }
impl ChildrenExt<'_> for Children { impl<'tcx> ChildrenExt<'tcx> for Children {
/// Insert an impl into this set of children without comparing to any existing impls. /// Insert an impl into this set of children without comparing to any existing impls.
fn insert_blindly(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) { fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsInfer) if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsInfer)
{ {
@ -62,7 +61,7 @@ impl ChildrenExt<'_> for Children {
/// Removes an impl from this set of children. Used when replacing /// Removes an impl from this set of children. Used when replacing
/// an impl with a parent. The impl must be present in the list of /// an impl with a parent. The impl must be present in the list of
/// children already. /// children already.
fn remove_existing(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) { fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
let vec: &mut Vec<DefId>; let vec: &mut Vec<DefId>;
if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsInfer) if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsInfer)
@ -82,11 +81,11 @@ impl ChildrenExt<'_> for Children {
/// specialization relationships. /// specialization relationships.
fn insert( fn insert(
&mut self, &mut self,
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
impl_def_id: DefId, impl_def_id: DefId,
simplified_self: Option<SimplifiedType>, simplified_self: Option<SimplifiedType>,
overlap_mode: OverlapMode, overlap_mode: OverlapMode,
) -> Result<Inserted, OverlapError> { ) -> Result<Inserted<'tcx>, OverlapError<'tcx>> {
let mut last_lint = None; let mut last_lint = None;
let mut replace_children = Vec::new(); let mut replace_children = Vec::new();
@ -103,30 +102,23 @@ impl ChildrenExt<'_> for Children {
impl_def_id, simplified_self, possible_sibling, impl_def_id, simplified_self, possible_sibling,
); );
let create_overlap_error = |overlap: traits::coherence::OverlapResult<'_>| { let create_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>| {
let trait_ref = overlap.impl_header.trait_ref.unwrap(); let trait_ref = overlap.impl_header.trait_ref.unwrap();
let self_ty = trait_ref.self_ty(); let self_ty = trait_ref.self_ty();
// FIXME: should postpone string formatting until we decide to actually emit. OverlapError {
with_no_trimmed_paths!({ with_impl: possible_sibling,
OverlapError { trait_ref,
with_impl: possible_sibling, // Only report the `Self` type if it has at least
trait_desc: trait_ref.print_only_trait_path().to_string(), // some outer concrete shell; otherwise, it's
// Only report the `Self` type if it has at least // not adding much information.
// some outer concrete shell; otherwise, it's self_ty: if self_ty.has_concrete_skeleton() { Some(self_ty) } else { None },
// not adding much information. intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
self_desc: if self_ty.has_concrete_skeleton() { involves_placeholder: overlap.involves_placeholder,
Some(self_ty.to_string()) }
} else {
None
},
intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
involves_placeholder: overlap.involves_placeholder,
}
})
}; };
let report_overlap_error = |overlap: traits::coherence::OverlapResult<'_>, let report_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>,
last_lint: &mut _| { last_lint: &mut _| {
// Found overlap, but no specialization; error out or report future-compat warning. // Found overlap, but no specialization; error out or report future-compat warning.
@ -255,31 +247,31 @@ where
} }
} }
pub trait GraphExt { pub trait GraphExt<'tcx> {
/// Insert a local impl into the specialization graph. If an existing impl /// Insert a local impl into the specialization graph. If an existing impl
/// conflicts with it (has overlap, but neither specializes the other), /// conflicts with it (has overlap, but neither specializes the other),
/// information about the area of overlap is returned in the `Err`. /// information about the area of overlap is returned in the `Err`.
fn insert( fn insert(
&mut self, &mut self,
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
impl_def_id: DefId, impl_def_id: DefId,
overlap_mode: OverlapMode, overlap_mode: OverlapMode,
) -> Result<Option<FutureCompatOverlapError>, OverlapError>; ) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>>;
/// Insert cached metadata mapping from a child impl back to its parent. /// Insert cached metadata mapping from a child impl back to its parent.
fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'_>, parent: DefId, child: DefId); fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId);
} }
impl GraphExt for Graph { impl<'tcx> GraphExt<'tcx> for Graph {
/// Insert a local impl into the specialization graph. If an existing impl /// Insert a local impl into the specialization graph. If an existing impl
/// conflicts with it (has overlap, but neither specializes the other), /// conflicts with it (has overlap, but neither specializes the other),
/// information about the area of overlap is returned in the `Err`. /// information about the area of overlap is returned in the `Err`.
fn insert( fn insert(
&mut self, &mut self,
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
impl_def_id: DefId, impl_def_id: DefId,
overlap_mode: OverlapMode, overlap_mode: OverlapMode,
) -> Result<Option<FutureCompatOverlapError>, OverlapError> { ) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>> {
assert!(impl_def_id.is_local()); assert!(impl_def_id.is_local());
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
@ -376,7 +368,7 @@ impl GraphExt for Graph {
} }
/// Insert cached metadata mapping from a child impl back to its parent. /// Insert cached metadata mapping from a child impl back to its parent.
fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'_>, parent: DefId, child: DefId) { fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId) {
if self.parent.insert(child, parent).is_some() { if self.parent.insert(child, parent).is_some() {
bug!( bug!(
"When recording an impl from the crate store, information about its parent \ "When recording an impl from the crate store, information about its parent \

View File

@ -12,9 +12,9 @@ rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" } rustc_index = { path = "../rustc_index" }
rustc_ast = { path = "../rustc_ast" } rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
chalk-ir = "0.80.0" chalk-ir = "0.87.0"
chalk-engine = "0.80.0" chalk-engine = "0.87.0"
chalk-solve = "0.80.0" chalk-solve = "0.87.0"
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
rustc_infer = { path = "../rustc_infer" } rustc_infer = { path = "../rustc_infer" }
rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_trait_selection = { path = "../rustc_trait_selection" }

View File

@ -142,6 +142,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
Some(CoerceUnsized) Some(CoerceUnsized)
} else if lang_items.dispatch_from_dyn_trait() == Some(def_id) { } else if lang_items.dispatch_from_dyn_trait() == Some(def_id) {
Some(DispatchFromDyn) Some(DispatchFromDyn)
} else if lang_items.tuple_trait() == Some(def_id) {
Some(Tuple)
} else { } else {
None None
}; };
@ -570,6 +572,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
CoerceUnsized => lang_items.coerce_unsized_trait(), CoerceUnsized => lang_items.coerce_unsized_trait(),
DiscriminantKind => lang_items.discriminant_kind_trait(), DiscriminantKind => lang_items.discriminant_kind_trait(),
DispatchFromDyn => lang_items.dispatch_from_dyn_trait(), DispatchFromDyn => lang_items.dispatch_from_dyn_trait(),
Tuple => lang_items.tuple_trait(),
}; };
def_id.map(chalk_ir::TraitId) def_id.map(chalk_ir::TraitId)
} }

View File

@ -507,9 +507,6 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
name: ty::BoundRegionKind::BrAnon(p.idx as u32, None), name: ty::BoundRegionKind::BrAnon(p.idx as u32, None),
}), }),
chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static, chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static,
chalk_ir::LifetimeData::Empty(_) => {
bug!("Chalk should not have been passed an empty lifetime.")
}
chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased, chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased,
chalk_ir::LifetimeData::Phantom(void, _) => match *void {}, chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
}; };

View File

@ -18,7 +18,6 @@ pub(super) const fn from_u32(i: u32) -> Option<char> {
} }
/// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`]. /// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`].
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
#[inline] #[inline]
#[must_use] #[must_use]
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {

View File

@ -140,7 +140,7 @@ impl char {
/// assert_eq!(None, c); /// assert_eq!(None, c);
/// ``` /// ```
#[stable(feature = "assoc_char_funcs", since = "1.52.0")] #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")] #[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
#[must_use] #[must_use]
#[inline] #[inline]
pub const fn from_u32(i: u32) -> Option<char> { pub const fn from_u32(i: u32) -> Option<char> {
@ -183,7 +183,7 @@ impl char {
/// assert_eq!('❤', c); /// assert_eq!('❤', c);
/// ``` /// ```
#[stable(feature = "assoc_char_funcs", since = "1.52.0")] #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")] #[rustc_const_unstable(feature = "const_char_from_u32_unchecked", issue = "89259")]
#[must_use] #[must_use]
#[inline] #[inline]
pub const unsafe fn from_u32_unchecked(i: u32) -> char { pub const unsafe fn from_u32_unchecked(i: u32) -> char {
@ -241,7 +241,7 @@ impl char {
/// let _c = char::from_digit(1, 37); /// let _c = char::from_digit(1, 37);
/// ``` /// ```
#[stable(feature = "assoc_char_funcs", since = "1.52.0")] #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")] #[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
#[must_use] #[must_use]
#[inline] #[inline]
pub const fn from_digit(num: u32, radix: u32) -> Option<char> { pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
@ -338,7 +338,7 @@ impl char {
/// let _ = '1'.to_digit(37); /// let _ = '1'.to_digit(37);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")] #[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline] #[inline]

View File

@ -110,7 +110,7 @@ pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::Into
/// Converts a `u32` to a `char`. Use [`char::from_u32`] instead. /// Converts a `u32` to a `char`. Use [`char::from_u32`] instead.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")] #[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
#[must_use] #[must_use]
#[inline] #[inline]
pub const fn from_u32(i: u32) -> Option<char> { pub const fn from_u32(i: u32) -> Option<char> {
@ -120,7 +120,7 @@ pub const fn from_u32(i: u32) -> Option<char> {
/// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`]. /// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`].
/// instead. /// instead.
#[stable(feature = "char_from_unchecked", since = "1.5.0")] #[stable(feature = "char_from_unchecked", since = "1.5.0")]
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")] #[rustc_const_unstable(feature = "const_char_from_u32_unchecked", issue = "89259")]
#[must_use] #[must_use]
#[inline] #[inline]
pub const unsafe fn from_u32_unchecked(i: u32) -> char { pub const unsafe fn from_u32_unchecked(i: u32) -> char {
@ -130,7 +130,7 @@ pub const unsafe fn from_u32_unchecked(i: u32) -> char {
/// Converts a digit in the given radix to a `char`. Use [`char::from_digit`] instead. /// Converts a digit in the given radix to a `char`. Use [`char::from_digit`] instead.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")] #[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
#[must_use] #[must_use]
#[inline] #[inline]
pub const fn from_digit(num: u32, radix: u32) -> Option<char> { pub const fn from_digit(num: u32, radix: u32) -> Option<char> {

View File

@ -104,7 +104,7 @@
#![feature(const_black_box)] #![feature(const_black_box)]
#![feature(const_caller_location)] #![feature(const_caller_location)]
#![feature(const_cell_into_inner)] #![feature(const_cell_into_inner)]
#![feature(const_char_convert)] #![feature(const_char_from_u32_unchecked)]
#![feature(const_clone)] #![feature(const_clone)]
#![feature(const_cmp)] #![feature(const_cmp)]
#![feature(const_discriminant)] #![feature(const_discriminant)]

View File

@ -1172,7 +1172,7 @@ impl<T> MaybeUninit<T> {
/// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)] /// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)]
/// use std::mem::MaybeUninit; /// use std::mem::MaybeUninit;
/// ///
/// let val = 0x12345678i32; /// let val = 0x12345678_i32;
/// let uninit = MaybeUninit::new(val); /// let uninit = MaybeUninit::new(val);
/// let uninit_bytes = uninit.as_bytes(); /// let uninit_bytes = uninit.as_bytes();
/// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) }; /// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) };
@ -1198,7 +1198,7 @@ impl<T> MaybeUninit<T> {
/// #![feature(maybe_uninit_as_bytes)] /// #![feature(maybe_uninit_as_bytes)]
/// use std::mem::MaybeUninit; /// use std::mem::MaybeUninit;
/// ///
/// let val = 0x12345678i32; /// let val = 0x12345678_i32;
/// let mut uninit = MaybeUninit::new(val); /// let mut uninit = MaybeUninit::new(val);
/// let uninit_bytes = uninit.as_bytes_mut(); /// let uninit_bytes = uninit.as_bytes_mut();
/// if cfg!(target_endian = "little") { /// if cfg!(target_endian = "little") {

View File

@ -1,4 +1,9 @@
//! Linux and Android-specific definitions for socket options. //! Android-specific networking functionality.
#![unstable(feature = "tcp_quickack", issue = "96256")] #![unstable(feature = "tcp_quickack", issue = "96256")]
pub use crate::os::net::tcp::TcpStreamExt;
#[unstable(feature = "unix_socket_abstract", issue = "85410")]
pub use crate::os::net::linux_ext::addr::SocketAddrExt;
#[unstable(feature = "tcp_quickack", issue = "96256")]
pub use crate::os::net::linux_ext::tcp::TcpStreamExt;

View File

@ -1,4 +1,9 @@
//! Linux and Android-specific definitions for socket options. //! Linux-specific networking functionality.
#![unstable(feature = "tcp_quickack", issue = "96256")] #![unstable(feature = "tcp_quickack", issue = "96256")]
pub use crate::os::net::tcp::TcpStreamExt;
#[unstable(feature = "unix_socket_abstract", issue = "85410")]
pub use crate::os::net::linux_ext::addr::SocketAddrExt;
#[unstable(feature = "tcp_quickack", issue = "96256")]
pub use crate::os::net::linux_ext::tcp::TcpStreamExt;

View File

@ -0,0 +1,64 @@
//! Linux and Android-specific extensions to socket addresses.
use crate::os::unix::net::SocketAddr;
use crate::sealed::Sealed;
/// Platform-specific extensions to [`SocketAddr`].
#[unstable(feature = "unix_socket_abstract", issue = "85410")]
pub trait SocketAddrExt: Sealed {
/// Creates a Unix socket address in the abstract namespace.
///
/// The abstract namespace is a Linux-specific extension that allows Unix
/// sockets to be bound without creating an entry in the filesystem.
/// Abstract sockets are unaffected by filesystem layout or permissions,
/// and no cleanup is necessary when the socket is closed.
///
/// An abstract socket address name may contain any bytes, including zero.
///
/// # Errors
///
/// Returns an error if the name is longer than `SUN_LEN - 1`.
///
/// # Examples
///
/// ```no_run
/// #![feature(unix_socket_abstract)]
/// use std::os::unix::net::{UnixListener, SocketAddr};
/// use std::os::linux::net::SocketAddrExt;
///
/// fn main() -> std::io::Result<()> {
/// let addr = SocketAddr::from_abstract_name(b"hidden")?;
/// let listener = match UnixListener::bind_addr(&addr) {
/// Ok(sock) => sock,
/// Err(err) => {
/// println!("Couldn't bind: {err:?}");
/// return Err(err);
/// }
/// };
/// Ok(())
/// }
/// ```
fn from_abstract_name<N>(name: &N) -> crate::io::Result<SocketAddr>
where
N: AsRef<[u8]>;
/// Returns the contents of this address if it is in the abstract namespace.
///
/// # Examples
///
/// ```no_run
/// #![feature(unix_socket_abstract)]
/// use std::os::unix::net::{UnixListener, SocketAddr};
/// use std::os::linux::net::SocketAddrExt;
///
/// fn main() -> std::io::Result<()> {
/// let name = b"hidden";
/// let name_addr = SocketAddr::from_abstract_name(name)?;
/// let socket = UnixListener::bind_addr(&name_addr)?;
/// let local_addr = socket.local_addr().expect("Couldn't get local address");
/// assert_eq!(local_addr.as_abstract_name(), Some(&name[..]));
/// Ok(())
/// }
/// ```
fn as_abstract_name(&self) -> Option<&[u8]>;
}

View File

@ -0,0 +1,12 @@
//! Linux and Android-specific networking functionality.
#![doc(cfg(any(target_os = "linux", target_os = "android")))]
#[unstable(feature = "unix_socket_abstract", issue = "85410")]
pub(crate) mod addr;
#[unstable(feature = "tcp_quickack", issue = "96256")]
pub(crate) mod tcp;
#[cfg(test)]
mod tests;

View File

@ -1,9 +1,8 @@
#[cfg(any(target_os = "android", target_os = "linux",))]
#[test] #[test]
fn quickack() { fn quickack() {
use crate::{ use crate::{
net::{test::next_test_ip4, TcpListener, TcpStream}, net::{test::next_test_ip4, TcpListener, TcpStream},
os::net::tcp::TcpStreamExt, os::net::linux_ext::tcp::TcpStreamExt,
}; };
macro_rules! t { macro_rules! t {

View File

@ -1,7 +1,4 @@
//! Linux and Android-specific definitions for socket options. //! OS-specific networking functionality.
#![unstable(feature = "tcp_quickack", issue = "96256")] #[cfg(any(target_os = "linux", target_os = "android", doc))]
#![doc(cfg(any(target_os = "linux", target_os = "android",)))] pub(super) mod linux_ext;
pub mod tcp;
#[cfg(test)]
mod tests;

View File

@ -1,6 +1,9 @@
use crate::ffi::OsStr; use crate::ffi::OsStr;
#[cfg(any(doc, target_os = "android", target_os = "linux"))]
use crate::os::net::linux_ext;
use crate::os::unix::ffi::OsStrExt; use crate::os::unix::ffi::OsStrExt;
use crate::path::Path; use crate::path::Path;
use crate::sealed::Sealed;
use crate::sys::cvt; use crate::sys::cvt;
use crate::{fmt, io, mem, ptr}; use crate::{fmt, io, mem, ptr};
@ -224,31 +227,6 @@ impl SocketAddr {
if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None } if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
} }
/// Returns the contents of this address if it is an abstract namespace
/// without the leading null byte.
///
/// # Examples
///
/// ```no_run
/// #![feature(unix_socket_abstract)]
/// use std::os::unix::net::{UnixListener, SocketAddr};
///
/// fn main() -> std::io::Result<()> {
/// let namespace = b"hidden";
/// let namespace_addr = SocketAddr::from_abstract_namespace(&namespace[..])?;
/// let socket = UnixListener::bind_addr(&namespace_addr)?;
/// let local_addr = socket.local_addr().expect("Couldn't get local address");
/// assert_eq!(local_addr.as_abstract_namespace(), Some(&namespace[..]));
/// Ok(())
/// }
/// ```
#[doc(cfg(any(target_os = "android", target_os = "linux")))]
#[cfg(any(doc, target_os = "android", target_os = "linux",))]
#[unstable(feature = "unix_socket_abstract", issue = "85410")]
pub fn as_abstract_namespace(&self) -> Option<&[u8]> {
if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
}
fn address(&self) -> AddressKind<'_> { fn address(&self) -> AddressKind<'_> {
let len = self.len as usize - sun_path_offset(&self.addr); let len = self.len as usize - sun_path_offset(&self.addr);
let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }; let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
@ -265,62 +243,41 @@ impl SocketAddr {
AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref()) AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
} }
} }
}
/// Creates an abstract domain socket address from a namespace #[unstable(feature = "unix_socket_abstract", issue = "85410")]
/// impl Sealed for SocketAddr {}
/// An abstract address does not create a file unlike traditional path-based
/// Unix sockets. The advantage of this is that the address will disappear when #[doc(cfg(any(target_os = "android", target_os = "linux")))]
/// the socket bound to it is closed, so no filesystem clean up is required. #[cfg(any(doc, target_os = "android", target_os = "linux"))]
/// #[unstable(feature = "unix_socket_abstract", issue = "85410")]
/// The leading null byte for the abstract namespace is automatically added. impl linux_ext::addr::SocketAddrExt for SocketAddr {
/// fn as_abstract_name(&self) -> Option<&[u8]> {
/// This is a Linux-specific extension. See more at [`unix(7)`]. if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
/// }
/// [`unix(7)`]: https://man7.org/linux/man-pages/man7/unix.7.html
/// fn from_abstract_name<N>(name: &N) -> crate::io::Result<Self>
/// # Errors where
/// N: AsRef<[u8]>,
/// This will return an error if the given namespace is too long {
/// let name = name.as_ref();
/// # Examples
///
/// ```no_run
/// #![feature(unix_socket_abstract)]
/// use std::os::unix::net::{UnixListener, SocketAddr};
///
/// fn main() -> std::io::Result<()> {
/// let addr = SocketAddr::from_abstract_namespace(b"hidden")?;
/// let listener = match UnixListener::bind_addr(&addr) {
/// Ok(sock) => sock,
/// Err(err) => {
/// println!("Couldn't bind: {err:?}");
/// return Err(err);
/// }
/// };
/// Ok(())
/// }
/// ```
#[doc(cfg(any(target_os = "android", target_os = "linux")))]
#[cfg(any(doc, target_os = "android", target_os = "linux",))]
#[unstable(feature = "unix_socket_abstract", issue = "85410")]
pub fn from_abstract_namespace(namespace: &[u8]) -> io::Result<SocketAddr> {
unsafe { unsafe {
let mut addr: libc::sockaddr_un = mem::zeroed(); let mut addr: libc::sockaddr_un = mem::zeroed();
addr.sun_family = libc::AF_UNIX as libc::sa_family_t; addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
if namespace.len() + 1 > addr.sun_path.len() { if name.len() + 1 > addr.sun_path.len() {
return Err(io::const_io_error!( return Err(io::const_io_error!(
io::ErrorKind::InvalidInput, io::ErrorKind::InvalidInput,
"namespace must be shorter than SUN_LEN", "abstract socket name must be shorter than SUN_LEN",
)); ));
} }
crate::ptr::copy_nonoverlapping( crate::ptr::copy_nonoverlapping(
namespace.as_ptr(), name.as_ptr(),
addr.sun_path.as_mut_ptr().add(1) as *mut u8, addr.sun_path.as_mut_ptr().add(1) as *mut u8,
namespace.len(), name.len(),
); );
let len = (sun_path_offset(&addr) + 1 + namespace.len()) as libc::socklen_t; let len = (sun_path_offset(&addr) + 1 + name.len()) as libc::socklen_t;
SocketAddr::from_parts(addr, len) SocketAddr::from_parts(addr, len)
} }
} }

View File

@ -7,6 +7,12 @@ use crate::sys_common::io::test::tmpdir;
use crate::thread; use crate::thread;
use crate::time::Duration; use crate::time::Duration;
#[cfg(target_os = "android")]
use crate::os::android::net::SocketAddrExt;
#[cfg(target_os = "linux")]
use crate::os::linux::net::SocketAddrExt;
macro_rules! or_panic { macro_rules! or_panic {
($e:expr) => { ($e:expr) => {
match $e { match $e {
@ -404,7 +410,7 @@ fn test_abstract_stream_connect() {
let msg1 = b"hello"; let msg1 = b"hello";
let msg2 = b"world"; let msg2 = b"world";
let socket_addr = or_panic!(SocketAddr::from_abstract_namespace(b"namespace")); let socket_addr = or_panic!(SocketAddr::from_abstract_name(b"name"));
let listener = or_panic!(UnixListener::bind_addr(&socket_addr)); let listener = or_panic!(UnixListener::bind_addr(&socket_addr));
let thread = thread::spawn(move || { let thread = thread::spawn(move || {
@ -418,7 +424,7 @@ fn test_abstract_stream_connect() {
let mut stream = or_panic!(UnixStream::connect_addr(&socket_addr)); let mut stream = or_panic!(UnixStream::connect_addr(&socket_addr));
let peer = or_panic!(stream.peer_addr()); let peer = or_panic!(stream.peer_addr());
assert_eq!(peer.as_abstract_namespace().unwrap(), b"namespace"); assert_eq!(peer.as_abstract_name().unwrap(), b"name");
or_panic!(stream.write_all(msg1)); or_panic!(stream.write_all(msg1));
let mut buf = vec![]; let mut buf = vec![];
@ -432,7 +438,7 @@ fn test_abstract_stream_connect() {
#[cfg(any(target_os = "android", target_os = "linux"))] #[cfg(any(target_os = "android", target_os = "linux"))]
#[test] #[test]
fn test_abstract_stream_iter() { fn test_abstract_stream_iter() {
let addr = or_panic!(SocketAddr::from_abstract_namespace(b"hidden")); let addr = or_panic!(SocketAddr::from_abstract_name(b"hidden"));
let listener = or_panic!(UnixListener::bind_addr(&addr)); let listener = or_panic!(UnixListener::bind_addr(&addr));
let thread = thread::spawn(move || { let thread = thread::spawn(move || {
@ -454,13 +460,13 @@ fn test_abstract_stream_iter() {
#[cfg(any(target_os = "android", target_os = "linux"))] #[cfg(any(target_os = "android", target_os = "linux"))]
#[test] #[test]
fn test_abstract_datagram_bind_send_to_addr() { fn test_abstract_datagram_bind_send_to_addr() {
let addr1 = or_panic!(SocketAddr::from_abstract_namespace(b"ns1")); let addr1 = or_panic!(SocketAddr::from_abstract_name(b"ns1"));
let sock1 = or_panic!(UnixDatagram::bind_addr(&addr1)); let sock1 = or_panic!(UnixDatagram::bind_addr(&addr1));
let local = or_panic!(sock1.local_addr()); let local = or_panic!(sock1.local_addr());
assert_eq!(local.as_abstract_namespace().unwrap(), b"ns1"); assert_eq!(local.as_abstract_name().unwrap(), b"ns1");
let addr2 = or_panic!(SocketAddr::from_abstract_namespace(b"ns2")); let addr2 = or_panic!(SocketAddr::from_abstract_name(b"ns2"));
let sock2 = or_panic!(UnixDatagram::bind_addr(&addr2)); let sock2 = or_panic!(UnixDatagram::bind_addr(&addr2));
let msg = b"hello world"; let msg = b"hello world";
@ -469,13 +475,13 @@ fn test_abstract_datagram_bind_send_to_addr() {
let (len, addr) = or_panic!(sock2.recv_from(&mut buf)); let (len, addr) = or_panic!(sock2.recv_from(&mut buf));
assert_eq!(msg, &buf[..]); assert_eq!(msg, &buf[..]);
assert_eq!(len, 11); assert_eq!(len, 11);
assert_eq!(addr.as_abstract_namespace().unwrap(), b"ns1"); assert_eq!(addr.as_abstract_name().unwrap(), b"ns1");
} }
#[cfg(any(target_os = "android", target_os = "linux"))] #[cfg(any(target_os = "android", target_os = "linux"))]
#[test] #[test]
fn test_abstract_datagram_connect_addr() { fn test_abstract_datagram_connect_addr() {
let addr1 = or_panic!(SocketAddr::from_abstract_namespace(b"ns3")); let addr1 = or_panic!(SocketAddr::from_abstract_name(b"ns3"));
let bsock1 = or_panic!(UnixDatagram::bind_addr(&addr1)); let bsock1 = or_panic!(UnixDatagram::bind_addr(&addr1));
let sock = or_panic!(UnixDatagram::unbound()); let sock = or_panic!(UnixDatagram::unbound());
@ -489,7 +495,7 @@ fn test_abstract_datagram_connect_addr() {
assert_eq!(addr.is_unnamed(), true); assert_eq!(addr.is_unnamed(), true);
assert_eq!(msg, &buf[..]); assert_eq!(msg, &buf[..]);
let addr2 = or_panic!(SocketAddr::from_abstract_namespace(b"ns4")); let addr2 = or_panic!(SocketAddr::from_abstract_name(b"ns4"));
let bsock2 = or_panic!(UnixDatagram::bind_addr(&addr2)); let bsock2 = or_panic!(UnixDatagram::bind_addr(&addr2));
or_panic!(sock.connect_addr(&addr2)); or_panic!(sock.connect_addr(&addr2));
@ -499,8 +505,8 @@ fn test_abstract_datagram_connect_addr() {
#[cfg(any(target_os = "android", target_os = "linux"))] #[cfg(any(target_os = "android", target_os = "linux"))]
#[test] #[test]
fn test_abstract_namespace_too_long() { fn test_abstract_name_too_long() {
match SocketAddr::from_abstract_namespace( match SocketAddr::from_abstract_name(
b"abcdefghijklmnopqrstuvwxyzabcdefghijklmn\ b"abcdefghijklmnopqrstuvwxyzabcdefghijklmn\
opqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi\ opqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi\
jklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", jklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
@ -513,11 +519,11 @@ fn test_abstract_namespace_too_long() {
#[cfg(any(target_os = "android", target_os = "linux"))] #[cfg(any(target_os = "android", target_os = "linux"))]
#[test] #[test]
fn test_abstract_namespace_no_pathname_and_not_unnamed() { fn test_abstract_no_pathname_and_not_unnamed() {
let namespace = b"local"; let name = b"local";
let addr = or_panic!(SocketAddr::from_abstract_namespace(&namespace[..])); let addr = or_panic!(SocketAddr::from_abstract_name(name));
assert_eq!(addr.as_pathname(), None); assert_eq!(addr.as_pathname(), None);
assert_eq!(addr.as_abstract_namespace(), Some(&namespace[..])); assert_eq!(addr.as_abstract_name(), Some(&name[..]));
assert_eq!(addr.is_unnamed(), false); assert_eq!(addr.is_unnamed(), false);
} }

View File

@ -674,7 +674,7 @@ impl FromWithTcx<clean::Variant> for Variant {
impl FromWithTcx<clean::Discriminant> for Discriminant { impl FromWithTcx<clean::Discriminant> for Discriminant {
fn from_tcx(disr: clean::Discriminant, tcx: TyCtxt<'_>) -> Self { fn from_tcx(disr: clean::Discriminant, tcx: TyCtxt<'_>) -> Self {
Discriminant { Discriminant {
// expr is only none if going throught the inlineing path, which gets // expr is only none if going through the inlineing path, which gets
// `rustc_middle` types, not `rustc_hir`, but because JSON never inlines // `rustc_middle` types, not `rustc_hir`, but because JSON never inlines
// the expr is always some. // the expr is always some.
expr: disr.expr(tcx).unwrap(), expr: disr.expr(tcx).unwrap(),

View File

@ -277,7 +277,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
let e = ExternalCrate { crate_num: LOCAL_CRATE }; let e = ExternalCrate { crate_num: LOCAL_CRATE };
// FIXME(adotinthevoid): Remove this, as it's not consistant with not // FIXME(adotinthevoid): Remove this, as it's not consistent with not
// inlining foreign items. // inlining foreign items.
let foreign_trait_items = self.get_trait_items(); let foreign_trait_items = self.get_trait_items();
let mut index = (*self.index).clone().into_inner(); let mut index = (*self.index).clone().into_inner();

View File

@ -354,7 +354,14 @@ impl Visitor<'_> for EarlyDocLinkResolver<'_, '_> {
self.parent_scope.module = old_module; self.parent_scope.module = old_module;
} else { } else {
match &item.kind { match &item.kind {
ItemKind::Impl(box ast::Impl { of_trait: Some(..), .. }) => { ItemKind::Impl(box ast::Impl { of_trait: Some(trait_ref), .. }) => {
if let Some(partial_res) = self.resolver.get_partial_res(trait_ref.ref_id)
&& let Some(res) = partial_res.full_res()
&& let Some(trait_def_id) = res.opt_def_id()
&& !trait_def_id.is_local()
&& self.visited_mods.insert(trait_def_id) {
self.resolve_doc_links_extern_impl(trait_def_id, false);
}
self.all_trait_impls.push(self.resolver.local_def_id(item.id).to_def_id()); self.all_trait_impls.push(self.resolver.local_def_id(item.id).to_def_id());
} }
ItemKind::MacroDef(macro_def) if macro_def.macro_rules => { ItemKind::MacroDef(macro_def) if macro_def.macro_rules => {

View File

@ -53,7 +53,7 @@ pub struct ItemSummary {
/// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`). /// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
/// ///
/// Note that items can appear in multiple paths, and the one chosen is implementation /// Note that items can appear in multiple paths, and the one chosen is implementation
/// defined. Currenty, this is the full path to where the item was defined. Eg /// defined. Currently, this is the full path to where the item was defined. Eg
/// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is /// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is
/// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change. /// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
pub path: Vec<String>, pub path: Vec<String>,
@ -351,7 +351,7 @@ pub enum Variant {
/// A variant with unnamed fields. /// A variant with unnamed fields.
/// ///
/// Unlike most of json, `#[doc(hidden)]` fields will be given as `None` /// Unlike most of json, `#[doc(hidden)]` fields will be given as `None`
/// instead of being ommited, because order matters. /// instead of being omitted, because order matters.
/// ///
/// ```rust /// ```rust
/// enum Demo { /// enum Demo {

View File

@ -0,0 +1,14 @@
// Doc links in `Trait`'s methods are resolved because it has a local impl.
// aux-build:issue-103463-aux.rs
extern crate issue_103463_aux;
use issue_103463_aux::Trait;
pub struct LocalType;
impl Trait for LocalType {
fn method() {}
}
fn main() {}

View File

@ -1,5 +1,3 @@
// known-bug: unknown
// FIXME(chalk): Chalk needs support for the Tuple trait
// compile-flags: -Z chalk // compile-flags: -Z chalk
fn main() -> () { fn main() -> () {
@ -26,7 +24,7 @@ fn main() -> () {
let mut c = b; let mut c = b;
c(); c();
b(); // FIXME: reenable when this is fixed ~ ERROR b(); //~ ERROR
// FIXME(chalk): this doesn't quite work // FIXME(chalk): this doesn't quite work
/* /*

View File

@ -1,80 +1,22 @@
error[E0277]: `()` is not a tuple error[E0382]: borrow of moved value: `b`
--> $DIR/closure.rs:7:5 --> $DIR/closure.rs:27:5
|
LL | t();
| ^^^ the trait `Tuple` is not implemented for `()`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() -> () where (): Tuple {
| +++++++++++++++
error[E0277]: `()` is not a tuple
--> $DIR/closure.rs:13:5
| |
LL | let mut c = b;
| - value moved here
...
LL | b(); LL | b();
| ^^^ the trait `Tuple` is not implemented for `()` | ^ value borrowed here after move
| |
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment
--> $DIR/closure.rs:20:9
| |
LL | fn main() -> () where (): Tuple { LL | a = 1;
| +++++++++++++++ | ^
help: consider mutably borrowing `b`
|
LL | let mut c = &mut b;
| ++++
error[E0277]: `()` is not a tuple error: aborting due to previous error
--> $DIR/closure.rs:17:5
|
LL | c();
| ^^^ the trait `Tuple` is not implemented for `()`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() -> () where (): Tuple {
| +++++++++++++++
error[E0277]: `()` is not a tuple For more information about this error, try `rustc --explain E0382`.
--> $DIR/closure.rs:18:5
|
LL | b();
| ^^^ the trait `Tuple` is not implemented for `()`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() -> () where (): Tuple {
| +++++++++++++++
error[E0277]: `()` is not a tuple
--> $DIR/closure.rs:24:5
|
LL | b();
| ^^^ the trait `Tuple` is not implemented for `()`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() -> () where (): Tuple {
| +++++++++++++++
error[E0277]: `()` is not a tuple
--> $DIR/closure.rs:28:5
|
LL | c();
| ^^^ the trait `Tuple` is not implemented for `()`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() -> () where (): Tuple {
| +++++++++++++++
error[E0277]: `()` is not a tuple
--> $DIR/closure.rs:29:5
|
LL | b(); // FIXME: reenable when this is fixed ~ ERROR
| ^^^ the trait `Tuple` is not implemented for `()`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() -> () where (): Tuple {
| +++++++++++++++
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,5 +1,4 @@
// known-bug: unknown // check-pass
// FIXME(chalk): Chalk needs support for the Tuple trait
// compile-flags: -Z chalk // compile-flags: -Z chalk
use std::fmt::Display; use std::fmt::Display;

View File

@ -1,32 +0,0 @@
error: the type `&dyn Fn(i32) -> _` is not well-formed (chalk)
--> $DIR/trait-objects.rs:11:12
|
LL | let f: &dyn Fn(i32) -> _ = &|x| x + x;
| ^^^^^^^^^^^^^^^^^
error[E0277]: `(i32,)` is not a tuple
--> $DIR/trait-objects.rs:12:5
|
LL | f(2);
| ^^^^ the trait `Tuple` is not implemented for `(i32,)`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() where (i32,): Tuple {
| +++++++++++++++++++
error[E0277]: expected a `Fn<(i32,)>` closure, found `dyn Fn(i32) -> i32`
--> $DIR/trait-objects.rs:12:5
|
LL | f(2);
| ^^^^ expected an `Fn<(i32,)>` closure, found `dyn Fn(i32) -> i32`
|
= help: the trait `Fn<(i32,)>` is not implemented for `dyn Fn(i32) -> i32`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() where dyn Fn(i32) -> i32: Fn<(i32,)> {
| ++++++++++++++++++++++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `go_trait::GoMut` for type `MyThingy` error[E0119]: conflicting implementations of trait `GoMut` for type `MyThingy`
--> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:15:1 --> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:15:1
| |
LL | impl GoMut for MyThingy { LL | impl GoMut for MyThingy {

View File

@ -1,4 +1,4 @@
error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
--> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1 --> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1
| |
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
@ -7,7 +7,7 @@ LL |
LL | impl<T: MyTrait> !Send for TestType<T> {} LL | impl<T: MyTrait> !Send for TestType<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>` error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
--> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1 --> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
| |
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}

View File

@ -9,7 +9,7 @@ LL | impl Copy for i32 {}
| |
= note: define and implement a trait or new type instead = note: define and implement a trait or new type instead
error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync` error[E0119]: conflicting implementations of trait `Copy` for type `&NotSync`
--> $DIR/coherence-impls-copy.rs:28:1 --> $DIR/coherence-impls-copy.rs:28:1
| |
LL | impl Copy for &'static NotSync {} LL | impl Copy for &'static NotSync {}

View File

@ -1,10 +1,10 @@
error[E0119]: conflicting implementations of trait `Sweet` for type `std::boxed::Box<_>` error[E0119]: conflicting implementations of trait `Sweet` for type `Box<_>`
--> $DIR/coherence-overlap-issue-23516.rs:8:1 --> $DIR/coherence-overlap-issue-23516.rs:8:1
| |
LL | impl<T:Sugar> Sweet for T { } LL | impl<T:Sugar> Sweet for T { }
| ------------------------- first implementation here | ------------------------- first implementation here
LL | impl<U:Sugar> Sweet for Box<U> { } LL | impl<U:Sugar> Sweet for Box<U> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::boxed::Box<_>` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
| |
= note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>` = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`

View File

@ -1,11 +1,11 @@
error[E0119]: conflicting implementations of trait `Foo<_>` for type `std::option::Option<_>` error[E0119]: conflicting implementations of trait `Foo<_>` for type `Option<_>`
--> $DIR/coherence-projection-conflict-ty-param.rs:10:1 --> $DIR/coherence-projection-conflict-ty-param.rs:10:1
| |
LL | impl <P, T: Foo<P>> Foo<P> for Option<T> {} LL | impl <P, T: Foo<P>> Foo<P> for Option<T> {}
| ---------------------------------------- first implementation here | ---------------------------------------- first implementation here
LL | LL |
LL | impl<T, U> Foo<T> for Option<U> { } LL | impl<T, U> Foo<T> for Option<U> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::option::Option<_>` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Option<_>`
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,11 +1,11 @@
error: conflicting implementations of trait `IntoWasmAbi` for type `&dyn std::ops::Fn(&_) -> _` error: conflicting implementations of trait `IntoWasmAbi` for type `&dyn Fn(&_) -> _`
--> $DIR/coherence-wasm-bindgen.rs:28:1 --> $DIR/coherence-wasm-bindgen.rs:28:1
| |
LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b) LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b)
| ------------------------------------------------------------ first implementation here | ------------------------------------------------------------ first implementation here
... ...
LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b) LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn std::ops::Fn(&_) -> _` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn Fn(&_) -> _`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>

View File

@ -1,11 +1,11 @@
error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyFundamentalStruct<(MyType,)>` error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFundamentalStruct<(MyType,)>`
--> $DIR/coherence_copy_like_err_fundamental_struct_tuple.rs:16:1 --> $DIR/coherence_copy_like_err_fundamental_struct_tuple.rs:16:1
| |
LL | impl<T: lib::MyCopy> MyTrait for T { } LL | impl<T: lib::MyCopy> MyTrait for T { }
| ---------------------------------- first implementation here | ---------------------------------- first implementation here
... ...
LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { } LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFundamentalStruct<(MyType,)>`
| |
= note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions

View File

@ -1,11 +1,11 @@
error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyStruct<MyType>` error[E0119]: conflicting implementations of trait `MyTrait` for type `MyStruct<MyType>`
--> $DIR/coherence_copy_like_err_struct.rs:19:1 --> $DIR/coherence_copy_like_err_struct.rs:19:1
| |
LL | impl<T: lib::MyCopy> MyTrait for T { } LL | impl<T: lib::MyCopy> MyTrait for T { }
| ---------------------------------- first implementation here | ---------------------------------- first implementation here
... ...
LL | impl MyTrait for lib::MyStruct<MyType> { } LL | impl MyTrait for lib::MyStruct<MyType> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyStruct<MyType>`
| |
= note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `std::convert::From<()>` for type `S` error[E0119]: conflicting implementations of trait `From<()>` for type `S`
--> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1 --> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1
| |
LL | impl From<()> for S { LL | impl From<()> for S {

View File

@ -0,0 +1,9 @@
#![allow(incomplete_features)]
#![feature(inline_const_pat)]
fn main() {
match () {
const { (|| {})() } => {}
//~^ ERROR cannot call non-const closure in constants
}
}

View File

@ -0,0 +1,12 @@
error[E0015]: cannot call non-const closure in constants
--> $DIR/invalid-inline-const-in-match-arm.rs:6:17
|
LL | const { (|| {})() } => {}
| ^^^^^^^^^
|
= note: closures need an RFC before allowed to be called in constants
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
error: aborting due to previous error
For more information about this error, try `rustc --explain E0015`.

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for type `std::boxed::Box<Q>` error[E0119]: conflicting implementations of trait `AsRef<Q>` for type `Box<Q>`
--> $DIR/conflict-with-std.rs:5:1 --> $DIR/conflict-with-std.rs:5:1
| |
LL | impl AsRef<Q> for Box<Q> { LL | impl AsRef<Q> for Box<Q> {
@ -8,7 +8,7 @@ LL | impl AsRef<Q> for Box<Q> {
- impl<T, A> AsRef<T> for Box<T, A> - impl<T, A> AsRef<T> for Box<T, A>
where A: Allocator, T: ?Sized; where A: Allocator, T: ?Sized;
error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S` error[E0119]: conflicting implementations of trait `From<S>` for type `S`
--> $DIR/conflict-with-std.rs:12:1 --> $DIR/conflict-with-std.rs:12:1
| |
LL | impl From<S> for S { LL | impl From<S> for S {
@ -17,7 +17,7 @@ LL | impl From<S> for S {
= note: conflicting implementation in crate `core`: = note: conflicting implementation in crate `core`:
- impl<T> From<T> for T; - impl<T> From<T> for T;
error[E0119]: conflicting implementations of trait `std::convert::TryFrom<X>` for type `X` error[E0119]: conflicting implementations of trait `TryFrom<X>` for type `X`
--> $DIR/conflict-with-std.rs:19:1 --> $DIR/conflict-with-std.rs:19:1
| |
LL | impl TryFrom<X> for X { LL | impl TryFrom<X> for X {

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `a::LolFrom<&[_]>` for type `LocalType<_>` error[E0119]: conflicting implementations of trait `LolFrom<&[_]>` for type `LocalType<_>`
--> $DIR/issue-23563.rs:13:1 --> $DIR/issue-23563.rs:13:1
| |
LL | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> { LL | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `std::convert::Into<_>` for type `GenX<_>` error[E0119]: conflicting implementations of trait `Into<_>` for type `GenX<_>`
--> $DIR/issue-27403.rs:5:1 --> $DIR/issue-27403.rs:5:1
| |
LL | impl<S> Into<S> for GenX<S> { LL | impl<S> Into<S> for GenX<S> {

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `std::convert::From<MyError<_>>` for type `MyError<_>` error[E0119]: conflicting implementations of trait `From<MyError<_>>` for type `MyError<_>`
--> $DIR/so-37347311.rs:11:1 --> $DIR/so-37347311.rs:11:1
| |
LL | impl<S: Storage> From<S::Error> for MyError<S> { LL | impl<S: Storage> From<S::Error> for MyError<S> {

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `MyStruct` error[E0119]: conflicting implementations of trait `Drop` for type `MyStruct`
--> $DIR/issue-28568.rs:7:1 --> $DIR/issue-28568.rs:7:1
| |
LL | impl Drop for MyStruct { LL | impl Drop for MyStruct {

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A` error[E0119]: conflicting implementations of trait `Trait1<Box<_>>` for type `A`
--> $DIR/issue-43355.rs:13:1 --> $DIR/issue-43355.rs:13:1
| |
LL | impl<X, T> Trait1<X> for T where T: Trait2<X> { LL | impl<X, T> Trait1<X> for T where T: Trait2<X> {

View File

@ -1,7 +1,7 @@
// Regression test for #48728, an ICE that occurred computing // Regression test for #48728, an ICE that occurred computing
// coherence "help" information. // coherence "help" information.
#[derive(Clone)] //~ ERROR conflicting implementations of trait `std::clone::Clone` #[derive(Clone)] //~ ERROR conflicting implementations of trait `Clone`
struct Node<T: ?Sized>(Box<T>); struct Node<T: ?Sized>(Box<T>);
impl<T: Clone + ?Sized> Clone for Node<[T]> { impl<T: Clone + ?Sized> Clone for Node<[T]> {

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Node<[_]>` error[E0119]: conflicting implementations of trait `Clone` for type `Node<[_]>`
--> $DIR/issue-48728.rs:4:10 --> $DIR/issue-48728.rs:4:10
| |
LL | #[derive(Clone)] LL | #[derive(Clone)]

View File

@ -1,36 +1,36 @@
error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + 'static)`: (E0119) error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:5:1 --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
| |
LL | impl Foo for dyn Send {} LL | impl Foo for dyn Send {}
| --------------------- first implementation here | --------------------- first implementation here
LL | LL |
LL | impl Foo for dyn Send + Send {} LL | impl Foo for dyn Send + Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
= note: `#[deny(order_dependent_trait_objects)]` on by default = note: `#[deny(order_dependent_trait_objects)]` on by default
error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:11:1 --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
| |
LL | impl Foo for dyn Send + Sync {} LL | impl Foo for dyn Send + Sync {}
| ---------------------------- first implementation here | ---------------------------- first implementation here
LL | LL |
LL | impl Foo for dyn Sync + Send {} LL | impl Foo for dyn Sync + Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:15:1 --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
| |
LL | impl Foo for dyn Sync + Send {} LL | impl Foo for dyn Sync + Send {}
| ---------------------------- first implementation here | ---------------------------- first implementation here
... ...
LL | impl Foo for dyn Send + Sync + Send {} LL | impl Foo for dyn Send + Sync + Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@ -38,42 +38,42 @@ LL | impl Foo for dyn Send + Sync + Send {}
error: aborting due to 3 previous errors error: aborting due to 3 previous errors
Future incompatibility report: Future breakage diagnostic: Future incompatibility report: Future breakage diagnostic:
error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + 'static)`: (E0119) error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:5:1 --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
| |
LL | impl Foo for dyn Send {} LL | impl Foo for dyn Send {}
| --------------------- first implementation here | --------------------- first implementation here
LL | LL |
LL | impl Foo for dyn Send + Send {} LL | impl Foo for dyn Send + Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
= note: `#[deny(order_dependent_trait_objects)]` on by default = note: `#[deny(order_dependent_trait_objects)]` on by default
Future breakage diagnostic: Future breakage diagnostic:
error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:11:1 --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
| |
LL | impl Foo for dyn Send + Sync {} LL | impl Foo for dyn Send + Sync {}
| ---------------------------- first implementation here | ---------------------------- first implementation here
LL | LL |
LL | impl Foo for dyn Sync + Send {} LL | impl Foo for dyn Sync + Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
= note: `#[deny(order_dependent_trait_objects)]` on by default = note: `#[deny(order_dependent_trait_objects)]` on by default
Future breakage diagnostic: Future breakage diagnostic:
error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:15:1 --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
| |
LL | impl Foo for dyn Sync + Send {} LL | impl Foo for dyn Sync + Send {}
| ---------------------------- first implementation here | ---------------------------- first implementation here
... ...
LL | impl Foo for dyn Send + Sync + Send {} LL | impl Foo for dyn Send + Sync + Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>

View File

@ -0,0 +1,31 @@
fn main() {
type Predicate = fn<'a>(&'a str) -> bool;
//~^ ERROR function pointer types may not have generic parameters
type Identity = fn<T>(T) -> T;
//~^ ERROR function pointer types may not have generic parameters
//~| ERROR cannot find type `T` in this scope
//~| ERROR cannot find type `T` in this scope
let _: fn<const N: usize, 'e, Q, 'f>();
//~^ ERROR function pointer types may not have generic parameters
let _: for<'outer> fn<'inner>();
//~^ ERROR function pointer types may not have generic parameters
let _: for<> fn<'r>();
//~^ ERROR function pointer types may not have generic parameters
type Hmm = fn<>();
//~^ ERROR function pointer types may not have generic parameters
let _: extern fn<'a: 'static>();
//~^ ERROR function pointer types may not have generic parameters
//~| ERROR lifetime bounds cannot be used in this context
let _: for<'any> extern "C" fn<'u>();
//~^ ERROR function pointer types may not have generic parameters
type QuiteBroken = fn<const>();
//~^ ERROR expected identifier, found `>`
}

View File

@ -0,0 +1,111 @@
error: function pointer types may not have generic parameters
--> $DIR/recover-fn-ptr-with-generics.rs:2:24
|
LL | type Predicate = fn<'a>(&'a str) -> bool;
| ^^^^
|
help: consider moving the lifetime parameter to a `for` parameter list
|
LL - type Predicate = fn<'a>(&'a str) -> bool;
LL + type Predicate = for<'a> fn(&'a str) -> bool;
|
error: function pointer types may not have generic parameters
--> $DIR/recover-fn-ptr-with-generics.rs:5:23
|
LL | type Identity = fn<T>(T) -> T;
| ^^^
error: function pointer types may not have generic parameters
--> $DIR/recover-fn-ptr-with-generics.rs:10:14
|
LL | let _: fn<const N: usize, 'e, Q, 'f>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider moving the lifetime parameters to a `for` parameter list
|
LL - let _: fn<const N: usize, 'e, Q, 'f>();
LL + let _: for<'e, 'f> fn();
|
error: function pointer types may not have generic parameters
--> $DIR/recover-fn-ptr-with-generics.rs:13:26
|
LL | let _: for<'outer> fn<'inner>();
| ^^^^^^^^
|
help: consider moving the lifetime parameter to the `for` parameter list
|
LL - let _: for<'outer> fn<'inner>();
LL + let _: for<'outer, 'inner> fn();
|
error: function pointer types may not have generic parameters
--> $DIR/recover-fn-ptr-with-generics.rs:16:20
|
LL | let _: for<> fn<'r>();
| ^^^^
|
help: consider moving the lifetime parameter to the `for` parameter list
|
LL - let _: for<> fn<'r>();
LL + let _: for<'r> fn();
|
error: function pointer types may not have generic parameters
--> $DIR/recover-fn-ptr-with-generics.rs:19:18
|
LL | type Hmm = fn<>();
| ^^
error: function pointer types may not have generic parameters
--> $DIR/recover-fn-ptr-with-generics.rs:22:21
|
LL | let _: extern fn<'a: 'static>();
| ^^^^^^^^^^^^^
|
help: consider moving the lifetime parameter to a `for` parameter list
|
LL - let _: extern fn<'a: 'static>();
LL + let _: for<'a> extern fn();
|
error: function pointer types may not have generic parameters
--> $DIR/recover-fn-ptr-with-generics.rs:26:35
|
LL | let _: for<'any> extern "C" fn<'u>();
| ^^^^
|
help: consider moving the lifetime parameter to the `for` parameter list
|
LL - let _: for<'any> extern "C" fn<'u>();
LL + let _: for<'any, 'u> extern "C" fn();
|
error: expected identifier, found `>`
--> $DIR/recover-fn-ptr-with-generics.rs:29:32
|
LL | type QuiteBroken = fn<const>();
| ^ expected identifier
error: lifetime bounds cannot be used in this context
--> $DIR/recover-fn-ptr-with-generics.rs:22:26
|
LL | let _: extern fn<'a: 'static>();
| ^^^^^^^
error[E0412]: cannot find type `T` in this scope
--> $DIR/recover-fn-ptr-with-generics.rs:5:27
|
LL | type Identity = fn<T>(T) -> T;
| ^ not found in this scope
error[E0412]: cannot find type `T` in this scope
--> $DIR/recover-fn-ptr-with-generics.rs:5:33
|
LL | type Identity = fn<T>(T) -> T;
| ^ not found in this scope
error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0412`.

View File

@ -10,7 +10,7 @@ LL | impl const std::ops::Add for i32 {
| |
= note: define and implement a trait or new type instead = note: define and implement a trait or new type instead
error[E0119]: conflicting implementations of trait `std::ops::Add` for type `Int` error[E0119]: conflicting implementations of trait `Add` for type `Int`
--> $DIR/const-and-non-const-impl.rs:22:1 --> $DIR/const-and-non-const-impl.rs:22:1
| |
LL | impl std::ops::Add for Int { LL | impl std::ops::Add for Int {

View File

@ -8,7 +8,7 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete = help: consider using `min_specialization` instead, which is more stable and complete
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
--> $DIR/specialization-overlap-negative.rs:9:1 --> $DIR/specialization-overlap-negative.rs:9:1
| |
LL | unsafe impl<T: Clone> Send for TestType<T> {} LL | unsafe impl<T: Clone> Send for TestType<T> {}

View File

@ -8,13 +8,13 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete = help: consider using `min_specialization` instead, which is more stable and complete
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error[E0119]: conflicting implementations of trait `Foo` for type `std::vec::Vec<_>` error[E0119]: conflicting implementations of trait `Foo` for type `Vec<_>`
--> $DIR/specialization-overlap.rs:5:1 --> $DIR/specialization-overlap.rs:5:1
| |
LL | impl<T: Clone> Foo for T {} LL | impl<T: Clone> Foo for T {}
| ------------------------ first implementation here | ------------------------ first implementation here
LL | impl<T> Foo for Vec<T> {} LL | impl<T> Foo for Vec<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::vec::Vec<_>` | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Vec<_>`
error[E0119]: conflicting implementations of trait `Bar` for type `(u8, u8)` error[E0119]: conflicting implementations of trait `Bar` for type `(u8, u8)`
--> $DIR/specialization-overlap.rs:9:1 --> $DIR/specialization-overlap.rs:9:1

View File

@ -1,12 +1,12 @@
error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn std::marker::Send + 'static)` error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:18:1 --> $DIR/issue-33140-hack-boundaries.rs:18:1
| |
LL | impl Trait1 for dyn Send {} LL | impl Trait1 for dyn Send {}
| ------------------------ first implementation here | ------------------------ first implementation here
LL | impl Trait1 for dyn Send {} LL | impl Trait1 for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`: error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn Send + 'static)`:
--> $DIR/issue-33140-hack-boundaries.rs:25:1 --> $DIR/issue-33140-hack-boundaries.rs:25:1
| |
LL | impl Trait2 for dyn Send {} LL | impl Trait2 for dyn Send {}
@ -14,21 +14,21 @@ LL | impl Trait2 for dyn Send {}
LL | impl !Trait2 for dyn Send {} LL | impl !Trait2 for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here | ^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
error[E0119]: conflicting implementations of trait `Trait3<(dyn std::marker::Sync + 'static)>` for type `(dyn std::marker::Send + 'static)` error[E0119]: conflicting implementations of trait `Trait3<(dyn Sync + 'static)>` for type `(dyn Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:32:1 --> $DIR/issue-33140-hack-boundaries.rs:32:1
| |
LL | impl Trait3<dyn Sync> for dyn Send {} LL | impl Trait3<dyn Sync> for dyn Send {}
| ---------------------------------- first implementation here | ---------------------------------- first implementation here
LL | impl Trait3<dyn Sync> for dyn Send {} LL | impl Trait3<dyn Sync> for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn std::marker::Send + 'static)` error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:39:1 --> $DIR/issue-33140-hack-boundaries.rs:39:1
| |
LL | impl<T: ?Sized> Trait4a for T {} LL | impl<T: ?Sized> Trait4a for T {}
| ----------------------------- first implementation here | ----------------------------- first implementation here
LL | impl Trait4a for dyn Send {} LL | impl Trait4a for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
error[E0119]: conflicting implementations of trait `Trait4b` for type `()` error[E0119]: conflicting implementations of trait `Trait4b` for type `()`
--> $DIR/issue-33140-hack-boundaries.rs:46:1 --> $DIR/issue-33140-hack-boundaries.rs:46:1
@ -38,42 +38,42 @@ LL | impl Trait4b for () {}
LL | impl Trait4b for () {} LL | impl Trait4b for () {}
| ^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` | ^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + std::marker::Send + 'static)` error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:53:1 --> $DIR/issue-33140-hack-boundaries.rs:53:1
| |
LL | impl Trait4c for dyn Trait1 + Send {} LL | impl Trait4c for dyn Trait1 + Send {}
| ---------------------------------- first implementation here | ---------------------------------- first implementation here
LL | impl Trait4c for dyn Trait1 + Send {} LL | impl Trait4c for dyn Trait1 + Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + std::marker::Send + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + Send + 'static)`
error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn std::marker::Send` error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn Send`
--> $DIR/issue-33140-hack-boundaries.rs:60:1 --> $DIR/issue-33140-hack-boundaries.rs:60:1
| |
LL | impl<'a> Trait4d for dyn Send + 'a {} LL | impl<'a> Trait4d for dyn Send + 'a {}
| ---------------------------------- first implementation here | ---------------------------------- first implementation here
LL | impl<'a> Trait4d for dyn Send + 'a {} LL | impl<'a> Trait4d for dyn Send + 'a {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn std::marker::Send` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn Send`
error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn std::marker::Send + 'static)` error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:67:1 --> $DIR/issue-33140-hack-boundaries.rs:67:1
| |
LL | impl Trait5 for dyn Send {} LL | impl Trait5 for dyn Send {}
| ------------------------ first implementation here | ------------------------ first implementation here
LL | impl Trait5 for dyn Send where u32: Copy {} LL | impl Trait5 for dyn Send where u32: Copy {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
error: aborting due to 8 previous errors error: aborting due to 8 previous errors
Some errors have detailed explanations: E0119, E0751. Some errors have detailed explanations: E0119, E0751.
For more information about an error, try `rustc --explain E0119`. For more information about an error, try `rustc --explain E0119`.
Future incompatibility report: Future breakage diagnostic: Future incompatibility report: Future breakage diagnostic:
warning: conflicting implementations of trait `Trait0` for type `(dyn std::marker::Send + 'static)`: (E0119) warning: conflicting implementations of trait `Trait0` for type `(dyn Send + 'static)`: (E0119)
--> $DIR/issue-33140-hack-boundaries.rs:10:1 --> $DIR/issue-33140-hack-boundaries.rs:10:1
| |
LL | impl Trait0 for dyn Send {} LL | impl Trait0 for dyn Send {}
| ------------------------ first implementation here | ------------------------ first implementation here
LL | impl Trait0 for dyn Send {} LL | impl Trait0 for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>

View File

@ -1,20 +1,20 @@
error[E0119]: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)` error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`
--> $DIR/issue-33140.rs:9:1 --> $DIR/issue-33140.rs:9:1
| |
LL | impl Trait for dyn Send + Sync { LL | impl Trait for dyn Send + Sync {
| ------------------------------ first implementation here | ------------------------------ first implementation here
... ...
LL | impl Trait for dyn Sync + Send { LL | impl Trait for dyn Sync + Send {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + std::marker::Sync + 'static)` error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn Send + Sync + 'static)`
--> $DIR/issue-33140.rs:22:1 --> $DIR/issue-33140.rs:22:1
| |
LL | impl Trait2 for dyn Send + Sync { LL | impl Trait2 for dyn Send + Sync {
| ------------------------------- first implementation here | ------------------------------- first implementation here
... ...
LL | impl Trait2 for dyn Sync + Send + Sync { LL | impl Trait2 for dyn Sync + Send + Sync {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
error[E0592]: duplicate definitions with name `abc` error[E0592]: duplicate definitions with name `abc`
--> $DIR/issue-33140.rs:29:5 --> $DIR/issue-33140.rs:29:5

View File

@ -1,4 +1,4 @@
error[E0751]: found both positive and negative implementation of trait `std::clone::Clone` for type `&mut MyType<'_>`: error[E0751]: found both positive and negative implementation of trait `Clone` for type `&mut MyType<'_>`:
--> $DIR/pin-unsound-issue-66544-clone.rs:7:1 --> $DIR/pin-unsound-issue-66544-clone.rs:7:1
| |
LL | impl<'a> Clone for &'a mut MyType<'a> { LL | impl<'a> Clone for &'a mut MyType<'a> {

View File

@ -1,4 +1,4 @@
error[E0751]: found both positive and negative implementation of trait `std::ops::DerefMut` for type `&MyType<'_>`: error[E0751]: found both positive and negative implementation of trait `DerefMut` for type `&MyType<'_>`:
--> $DIR/pin-unsound-issue-66544-derefmut.rs:12:1 --> $DIR/pin-unsound-issue-66544-derefmut.rs:12:1
| |
LL | impl<'a> DerefMut for &'a MyType<'a> { LL | impl<'a> DerefMut for &'a MyType<'a> {

View File

@ -1,10 +1,10 @@
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:86:1 --> $DIR/issue-33140-traitobject-crate.rs:86:1
| |
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
| ------------------------------------------------------ first implementation here | ------------------------------------------------------ first implementation here
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@ -14,26 +14,26 @@ note: the lint level is defined here
LL | #![warn(order_dependent_trait_objects)] LL | #![warn(order_dependent_trait_objects)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:89:1 --> $DIR/issue-33140-traitobject-crate.rs:89:1
| |
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
| ------------------------------------------------------------- first implementation here | ------------------------------------------------------------- first implementation here
... ...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { } LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:93:1 --> $DIR/issue-33140-traitobject-crate.rs:93:1
| |
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { } LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
| ------------------------------------------------------ first implementation here | ------------------------------------------------------ first implementation here
... ...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@ -41,13 +41,13 @@ LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
warning: 3 warnings emitted warning: 3 warnings emitted
Future incompatibility report: Future breakage diagnostic: Future incompatibility report: Future breakage diagnostic:
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:86:1 --> $DIR/issue-33140-traitobject-crate.rs:86:1
| |
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
| ------------------------------------------------------ first implementation here | ------------------------------------------------------ first implementation here
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@ -58,14 +58,14 @@ LL | #![warn(order_dependent_trait_objects)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic: Future breakage diagnostic:
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:89:1 --> $DIR/issue-33140-traitobject-crate.rs:89:1
| |
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
| ------------------------------------------------------------- first implementation here | ------------------------------------------------------------- first implementation here
... ...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { } LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@ -76,14 +76,14 @@ LL | #![warn(order_dependent_trait_objects)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic: Future breakage diagnostic:
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:93:1 --> $DIR/issue-33140-traitobject-crate.rs:93:1
| |
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { } LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
| ------------------------------------------------------ first implementation here | ------------------------------------------------------ first implementation here
... ...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>

View File

@ -1,4 +1,4 @@
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `MyStruct` error[E0119]: conflicting implementations of trait `Send` for type `MyStruct`
--> $DIR/overlap-not-permitted-for-builtin-trait.rs:7:1 --> $DIR/overlap-not-permitted-for-builtin-trait.rs:7:1
| |
LL | impl !Send for MyStruct {} LL | impl !Send for MyStruct {}

View File

@ -8,7 +8,8 @@
//! `x.py`, in that order of preference. //! `x.py`, in that order of preference.
use std::{ use std::{
env, io, env::{self, consts::EXE_EXTENSION},
io,
process::{self, Command, ExitStatus}, process::{self, Command, ExitStatus},
}; };
@ -27,12 +28,12 @@ fn python() -> &'static str {
for dir in env::split_paths(&val) { for dir in env::split_paths(&val) {
// `python` should always take precedence over python2 / python3 if it exists // `python` should always take precedence over python2 / python3 if it exists
if dir.join(PYTHON).exists() { if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() {
return PYTHON; return PYTHON;
} }
python2 |= dir.join(PYTHON2).exists(); python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists();
python3 |= dir.join(PYTHON3).exists(); python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists();
} }
// try 3 before 2 // try 3 before 2