mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
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:
commit
101e1822c3
16
Cargo.lock
16
Cargo.lock
@ -502,9 +502,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chalk-derive"
|
||||
version = "0.80.0"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0001adf0cf12361e08b65e1898ea138f8f77d8f5177cbf29b6b3b3532252bd6"
|
||||
checksum = "d552b2fa341f5fc35c6b917b1d289d3c3a34d0b74e579390ea6192d6152a8cdb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -514,9 +514,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chalk-engine"
|
||||
version = "0.80.0"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c44ee96f2d67cb5193d1503f185db1abad9933a1c6e6b4169c176f90baecd393"
|
||||
checksum = "7e54ac43048cb31c470d7b3e3acd409090ef4a5abddfe02455187aebc3d6879f"
|
||||
dependencies = [
|
||||
"chalk-derive",
|
||||
"chalk-ir",
|
||||
@ -527,9 +527,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chalk-ir"
|
||||
version = "0.80.0"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d8a95548f23618fda86426e4304e563ec2bb7ba0216139f0748d63c107b5f1"
|
||||
checksum = "43aa55deff4e7fbdb09fa014543372f2c95a06835ac487b9ce57b5099b950838"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"chalk-derive",
|
||||
@ -538,9 +538,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chalk-solve"
|
||||
version = "0.80.0"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f37f492dacfafe2e21319b80827da2779932909bb392f0cc86b2bd5c07c1b4e1"
|
||||
checksum = "61213deefc36ba265ad01c4d997e18bcddf7922862a4594a47ca4575afb3dab4"
|
||||
dependencies = [
|
||||
"chalk-derive",
|
||||
"chalk-ir",
|
||||
|
@ -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.
|
||||
///
|
||||
/// If this suceeds, the `ImmTy` is never `Uninit`.
|
||||
/// If this succeeds, the `ImmTy` is never `Uninit`.
|
||||
#[inline(always)]
|
||||
pub fn read_immediate(
|
||||
&self,
|
||||
|
@ -316,8 +316,7 @@ where
|
||||
Ok(MPlaceTy { mplace, layout, align })
|
||||
}
|
||||
|
||||
/// Take an operand, representing a pointer, and dereference it to a place -- that
|
||||
/// will always be a MemPlace. Lives in `place.rs` because it creates a place.
|
||||
/// Take an operand, representing a pointer, and dereference it to a place.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn deref_operand(
|
||||
&self,
|
||||
@ -331,7 +330,7 @@ where
|
||||
}
|
||||
|
||||
let mplace = self.ref_to_mplace(&val)?;
|
||||
self.check_mplace_access(mplace, CheckInAllocMsg::DerefTest)?;
|
||||
self.check_mplace(mplace)?;
|
||||
Ok(mplace)
|
||||
}
|
||||
|
||||
@ -358,17 +357,18 @@ where
|
||||
}
|
||||
|
||||
/// Check if this mplace is dereferenceable and sufficiently aligned.
|
||||
fn check_mplace_access(
|
||||
&self,
|
||||
mplace: MPlaceTy<'tcx, M::Provenance>,
|
||||
msg: CheckInAllocMsg,
|
||||
) -> InterpResult<'tcx> {
|
||||
pub fn check_mplace(&self, mplace: MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
|
||||
let (size, align) = self
|
||||
.size_and_align_of_mplace(&mplace)?
|
||||
.unwrap_or((mplace.layout.size, mplace.layout.align.abi));
|
||||
assert!(mplace.align <= align, "dynamic alignment less strict than static one?");
|
||||
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(())
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
.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
|
||||
|
@ -1254,6 +1254,10 @@ impl HandlerInner {
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -333,7 +333,7 @@ fn expand_macro<'cx>(
|
||||
assert!(try_success_result.is_err(), "Macro matching returned a success on the second try");
|
||||
|
||||
if let Some(result) = tracker.result {
|
||||
// An irrecoverable error occured and has been emitted.
|
||||
// An irrecoverable error occurred and has been emitted.
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ pub enum AttributeDuplicates {
|
||||
FutureWarnPreceding,
|
||||
}
|
||||
|
||||
/// A conveniece macro to deal with `$($expr)?`.
|
||||
/// A convenience macro to deal with `$($expr)?`.
|
||||
macro_rules! or_default {
|
||||
($default:expr,) => {
|
||||
$default
|
||||
|
@ -35,7 +35,7 @@ struct ClosureSignatures<'tcx> {
|
||||
bound_sig: ty::PolyFnSig<'tcx>,
|
||||
/// The signature within the function body.
|
||||
/// 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.
|
||||
liberated_sig: ty::FnSig<'tcx>,
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ fn lint_int_literal<'tcx>(
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -429,7 +429,7 @@ fn lint_uint_literal<'tcx>(
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
|
||||
|
@ -8,7 +8,7 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.2.1"
|
||||
chalk-ir = "0.80.0"
|
||||
chalk-ir = "0.87.0"
|
||||
either = "1.5.0"
|
||||
gsgdt = "0.1.2"
|
||||
polonius-engine = "0.13.0"
|
||||
|
@ -1541,7 +1541,7 @@ impl<'tcx> Place<'tcx> {
|
||||
/// If MirPhase >= Derefered and if projection contains Deref,
|
||||
/// It's guaranteed to be in the first place
|
||||
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!(
|
||||
self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
|
||||
);
|
||||
|
@ -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
|
||||
/// 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),
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
else_block: Some(else_block),
|
||||
} => {
|
||||
// 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,
|
||||
// or the remainder scope of the last statement.
|
||||
// This is to make sure that temporaries instantiated in `<expr>` are dropped
|
||||
|
@ -577,6 +577,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
self.errors.push(PatternError::ConstParamInPattern(span));
|
||||
return PatKind::Wild;
|
||||
}
|
||||
ConstKind::Error(_) => {
|
||||
return PatKind::Wild;
|
||||
}
|
||||
_ => bug!("Expected ConstKind::Param"),
|
||||
},
|
||||
mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
|
||||
|
@ -1280,3 +1280,24 @@ pub(crate) struct DoubleColonInBound {
|
||||
#[suggestion(code = ": ", applicability = "machine-applicable")]
|
||||
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,
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#![feature(array_windows)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{Parser, PathStyle, TokenType};
|
||||
|
||||
use crate::errors::{FnPtrWithGenerics, FnPtrWithGenericsSugg};
|
||||
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
@ -270,14 +271,19 @@ impl<'a> Parser<'a> {
|
||||
TyKind::Infer
|
||||
} else if self.check_fn_front_matter(false, Case::Sensitive) {
|
||||
// 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) {
|
||||
// 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> Trait1<'lt> + Trait2 + 'a`
|
||||
let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
||||
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 {
|
||||
let path = self.parse_path(PathStyle::Type)?;
|
||||
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
|
||||
@ -519,7 +525,8 @@ impl<'a> Parser<'a> {
|
||||
fn parse_ty_bare_fn(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
params: Vec<GenericParam>,
|
||||
mut params: Vec<GenericParam>,
|
||||
param_insertion_point: Option<Span>,
|
||||
recover_return_sign: RecoverReturnSign,
|
||||
) -> PResult<'a, TyKind> {
|
||||
let inherited_vis = rustc_ast::Visibility {
|
||||
@ -530,6 +537,9 @@ impl<'a> Parser<'a> {
|
||||
let span_start = self.token.span;
|
||||
let ast::FnHeader { ext, unsafety, constness, asyncness } =
|
||||
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 whole_span = lo.to(self.prev_token.span);
|
||||
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 })))
|
||||
}
|
||||
|
||||
/// 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.
|
||||
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))
|
||||
|
@ -72,7 +72,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
|
||||
update(node_id);
|
||||
if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind {
|
||||
// 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
|
||||
// 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
|
||||
|
@ -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.
|
||||
#[inline]
|
||||
pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
|
||||
|
@ -114,7 +114,7 @@ pub enum Lld {
|
||||
/// relevant now.
|
||||
///
|
||||
/// 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
|
||||
/// `-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
|
||||
|
@ -58,10 +58,10 @@ pub struct NoValueInOnUnimplemented {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
pub struct NegativePositiveConflict<'a> {
|
||||
pub struct NegativePositiveConflict<'tcx> {
|
||||
pub impl_span: Span,
|
||||
pub trait_desc: &'a str,
|
||||
pub self_desc: &'a Option<String>,
|
||||
pub trait_desc: ty::TraitRef<'tcx>,
|
||||
pub self_ty: Option<Ty<'tcx>>,
|
||||
pub negative_impl_span: Result<Span, Symbol>,
|
||||
pub positive_impl_span: Result<Span, Symbol>,
|
||||
}
|
||||
@ -73,10 +73,10 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> {
|
||||
handler: &Handler,
|
||||
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
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(
|
||||
"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.code(rustc_errors::error_code!(E0751));
|
||||
|
@ -64,13 +64,13 @@ pub fn add_placeholder_note(err: &mut Diagnostic) {
|
||||
/// with a suitably-freshened `ImplHeader` with those types
|
||||
/// substituted. Otherwise, returns `None`.
|
||||
#[instrument(skip(tcx, skip_leak_check), level = "debug")]
|
||||
pub fn overlapping_impls(
|
||||
tcx: TyCtxt<'_>,
|
||||
pub fn overlapping_impls<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl1_def_id: DefId,
|
||||
impl2_def_id: DefId,
|
||||
skip_leak_check: SkipLeakCheck,
|
||||
overlap_mode: OverlapMode,
|
||||
) -> Option<OverlapResult<'_>> {
|
||||
) -> Option<OverlapResult<'tcx>> {
|
||||
// Before doing expensive operations like entering an inference context, do
|
||||
// a quick check via fast_reject to tell if the impl headers could possibly
|
||||
// unify.
|
||||
|
@ -19,9 +19,9 @@ use crate::traits::engine::TraitEngineExt as _;
|
||||
use crate::traits::select::IntercrateAmbiguityCause;
|
||||
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
|
||||
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_middle::ty::{self, ImplSubject, TyCtxt};
|
||||
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{InternalSubsts, SubstsRef};
|
||||
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
|
||||
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
|
||||
@ -32,10 +32,10 @@ use super::SelectionContext;
|
||||
|
||||
/// Information pertinent to an overlapping impl error.
|
||||
#[derive(Debug)]
|
||||
pub struct OverlapError {
|
||||
pub struct OverlapError<'tcx> {
|
||||
pub with_impl: DefId,
|
||||
pub trait_desc: String,
|
||||
pub self_desc: Option<String>,
|
||||
pub trait_ref: ty::TraitRef<'tcx>,
|
||||
pub self_ty: Option<Ty<'tcx>>,
|
||||
pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>,
|
||||
pub involves_placeholder: bool,
|
||||
}
|
||||
@ -275,9 +275,9 @@ pub(super) fn specialization_graph_provider(
|
||||
// it negatively impacts perf.
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
fn report_overlap_conflict(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: OverlapError,
|
||||
fn report_overlap_conflict<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
overlap: OverlapError<'tcx>,
|
||||
impl_def_id: LocalDefId,
|
||||
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
@ -313,9 +313,9 @@ fn report_overlap_conflict(
|
||||
}
|
||||
}
|
||||
|
||||
fn report_negative_positive_conflict(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: &OverlapError,
|
||||
fn report_negative_positive_conflict<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
overlap: &OverlapError<'tcx>,
|
||||
local_impl_def_id: LocalDefId,
|
||||
negative_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 {
|
||||
impl_span: tcx.def_span(local_impl_def_id),
|
||||
trait_desc: &overlap.trait_desc,
|
||||
self_desc: &overlap.self_desc,
|
||||
trait_desc: overlap.trait_ref,
|
||||
self_ty: overlap.self_ty,
|
||||
negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
|
||||
positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
|
||||
});
|
||||
sg.has_errored = Some(err.emit());
|
||||
}
|
||||
|
||||
fn report_conflicting_impls(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: OverlapError,
|
||||
fn report_conflicting_impls<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
overlap: OverlapError<'tcx>,
|
||||
impl_def_id: LocalDefId,
|
||||
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
|
||||
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
|
||||
// now because the struct_lint methods don't return back the DiagnosticBuilder
|
||||
// that's passed in.
|
||||
fn decorate<'a, 'b, G: EmissionGuarantee>(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: OverlapError,
|
||||
fn decorate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
overlap: &OverlapError<'tcx>,
|
||||
impl_span: Span,
|
||||
err: &'b mut DiagnosticBuilder<'a, G>,
|
||||
) -> &'b mut DiagnosticBuilder<'a, G> {
|
||||
err: &mut Diagnostic,
|
||||
) {
|
||||
match tcx.span_of_impl(overlap.with_impl) {
|
||||
Ok(span) => {
|
||||
err.span_label(span, "first implementation here");
|
||||
@ -357,7 +357,7 @@ fn report_conflicting_impls(
|
||||
impl_span,
|
||||
format!(
|
||||
"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 {
|
||||
coherence::add_placeholder_note(err);
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
let msg = format!(
|
||||
"conflicting implementations of trait `{}`{}{}",
|
||||
overlap.trait_desc,
|
||||
overlap.self_desc.as_deref().map_or_else(String::new, |ty| format!(" for type `{ty}`")),
|
||||
match used_to_be_allowed {
|
||||
Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
|
||||
_ => "",
|
||||
}
|
||||
);
|
||||
let msg = DelayDm(|| {
|
||||
format!(
|
||||
"conflicting implementations of trait `{}`{}{}",
|
||||
overlap.trait_ref.print_only_trait_path(),
|
||||
overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")),
|
||||
match used_to_be_allowed {
|
||||
Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
|
||||
_ => "",
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
match used_to_be_allowed {
|
||||
None => {
|
||||
let reported = if overlap.with_impl.is_local()
|
||||
|| tcx.orphan_check_impl(impl_def_id).is_ok()
|
||||
{
|
||||
let mut err = struct_span_err!(tcx.sess, impl_span, E0119, "{msg}",);
|
||||
decorate(tcx, overlap, impl_span, &mut err);
|
||||
let mut err = tcx.sess.struct_span_err(impl_span, msg);
|
||||
err.code(error_code!(E0119));
|
||||
decorate(tcx, &overlap, impl_span, &mut err);
|
||||
Some(err.emit())
|
||||
} else {
|
||||
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),
|
||||
impl_span,
|
||||
msg,
|
||||
|err| decorate(tcx, overlap, impl_span, err),
|
||||
|err| {
|
||||
decorate(tcx, &overlap, impl_span, err);
|
||||
err
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -3,7 +3,6 @@ use super::OverlapError;
|
||||
use crate::traits;
|
||||
use rustc_hir::def_id::DefId;
|
||||
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};
|
||||
|
||||
pub use rustc_middle::traits::specialization_graph::*;
|
||||
@ -15,15 +14,15 @@ pub enum FutureCompatOverlapErrorKind {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FutureCompatOverlapError {
|
||||
pub error: OverlapError,
|
||||
pub struct FutureCompatOverlapError<'tcx> {
|
||||
pub error: OverlapError<'tcx>,
|
||||
pub kind: FutureCompatOverlapErrorKind,
|
||||
}
|
||||
|
||||
/// 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.
|
||||
BecameNewSibling(Option<FutureCompatOverlapError>),
|
||||
BecameNewSibling(Option<FutureCompatOverlapError<'tcx>>),
|
||||
|
||||
/// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc.
|
||||
ReplaceChildren(Vec<DefId>),
|
||||
@ -42,12 +41,12 @@ trait ChildrenExt<'tcx> {
|
||||
impl_def_id: DefId,
|
||||
simplified_self: Option<SimplifiedType>,
|
||||
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.
|
||||
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();
|
||||
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
|
||||
/// an impl with a parent. The impl must be present in the list of
|
||||
/// 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 vec: &mut Vec<DefId>;
|
||||
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.
|
||||
fn insert(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'_>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_def_id: DefId,
|
||||
simplified_self: Option<SimplifiedType>,
|
||||
overlap_mode: OverlapMode,
|
||||
) -> Result<Inserted, OverlapError> {
|
||||
) -> Result<Inserted<'tcx>, OverlapError<'tcx>> {
|
||||
let mut last_lint = None;
|
||||
let mut replace_children = Vec::new();
|
||||
|
||||
@ -103,30 +102,23 @@ impl ChildrenExt<'_> for Children {
|
||||
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 self_ty = trait_ref.self_ty();
|
||||
|
||||
// FIXME: should postpone string formatting until we decide to actually emit.
|
||||
with_no_trimmed_paths!({
|
||||
OverlapError {
|
||||
with_impl: possible_sibling,
|
||||
trait_desc: trait_ref.print_only_trait_path().to_string(),
|
||||
// Only report the `Self` type if it has at least
|
||||
// some outer concrete shell; otherwise, it's
|
||||
// not adding much information.
|
||||
self_desc: if self_ty.has_concrete_skeleton() {
|
||||
Some(self_ty.to_string())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
|
||||
involves_placeholder: overlap.involves_placeholder,
|
||||
}
|
||||
})
|
||||
OverlapError {
|
||||
with_impl: possible_sibling,
|
||||
trait_ref,
|
||||
// Only report the `Self` type if it has at least
|
||||
// some outer concrete shell; otherwise, it's
|
||||
// not adding much information.
|
||||
self_ty: if self_ty.has_concrete_skeleton() { Some(self_ty) } 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 _| {
|
||||
// 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
|
||||
/// conflicts with it (has overlap, but neither specializes the other),
|
||||
/// information about the area of overlap is returned in the `Err`.
|
||||
fn insert(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'_>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_def_id: DefId,
|
||||
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.
|
||||
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
|
||||
/// conflicts with it (has overlap, but neither specializes the other),
|
||||
/// information about the area of overlap is returned in the `Err`.
|
||||
fn insert(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'_>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_def_id: DefId,
|
||||
overlap_mode: OverlapMode,
|
||||
) -> Result<Option<FutureCompatOverlapError>, OverlapError> {
|
||||
) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>> {
|
||||
assert!(impl_def_id.is_local());
|
||||
|
||||
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.
|
||||
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() {
|
||||
bug!(
|
||||
"When recording an impl from the crate store, information about its parent \
|
||||
|
@ -12,9 +12,9 @@ rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
chalk-ir = "0.80.0"
|
||||
chalk-engine = "0.80.0"
|
||||
chalk-solve = "0.80.0"
|
||||
chalk-ir = "0.87.0"
|
||||
chalk-engine = "0.87.0"
|
||||
chalk-solve = "0.87.0"
|
||||
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
|
||||
rustc_infer = { path = "../rustc_infer" }
|
||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||
|
@ -142,6 +142,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||
Some(CoerceUnsized)
|
||||
} else if lang_items.dispatch_from_dyn_trait() == Some(def_id) {
|
||||
Some(DispatchFromDyn)
|
||||
} else if lang_items.tuple_trait() == Some(def_id) {
|
||||
Some(Tuple)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -570,6 +572,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||
CoerceUnsized => lang_items.coerce_unsized_trait(),
|
||||
DiscriminantKind => lang_items.discriminant_kind_trait(),
|
||||
DispatchFromDyn => lang_items.dispatch_from_dyn_trait(),
|
||||
Tuple => lang_items.tuple_trait(),
|
||||
};
|
||||
def_id.map(chalk_ir::TraitId)
|
||||
}
|
||||
|
@ -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),
|
||||
}),
|
||||
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::Phantom(void, _) => match *void {},
|
||||
};
|
||||
|
@ -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`].
|
||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||
|
@ -140,7 +140,7 @@ impl char {
|
||||
/// assert_eq!(None, c);
|
||||
/// ```
|
||||
#[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]
|
||||
#[inline]
|
||||
pub const fn from_u32(i: u32) -> Option<char> {
|
||||
@ -183,7 +183,7 @@ impl char {
|
||||
/// assert_eq!('❤', c);
|
||||
/// ```
|
||||
#[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]
|
||||
#[inline]
|
||||
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||
@ -241,7 +241,7 @@ impl char {
|
||||
/// let _c = char::from_digit(1, 37);
|
||||
/// ```
|
||||
#[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]
|
||||
#[inline]
|
||||
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||
@ -338,7 +338,7 @@ impl char {
|
||||
/// let _ = '1'.to_digit(37);
|
||||
/// ```
|
||||
#[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, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
|
@ -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.
|
||||
#[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]
|
||||
#[inline]
|
||||
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`].
|
||||
/// instead.
|
||||
#[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]
|
||||
#[inline]
|
||||
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.
|
||||
#[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]
|
||||
#[inline]
|
||||
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||
|
@ -104,7 +104,7 @@
|
||||
#![feature(const_black_box)]
|
||||
#![feature(const_caller_location)]
|
||||
#![feature(const_cell_into_inner)]
|
||||
#![feature(const_char_convert)]
|
||||
#![feature(const_char_from_u32_unchecked)]
|
||||
#![feature(const_clone)]
|
||||
#![feature(const_cmp)]
|
||||
#![feature(const_discriminant)]
|
||||
|
@ -1172,7 +1172,7 @@ impl<T> MaybeUninit<T> {
|
||||
/// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let val = 0x12345678i32;
|
||||
/// let val = 0x12345678_i32;
|
||||
/// let uninit = MaybeUninit::new(val);
|
||||
/// let uninit_bytes = uninit.as_bytes();
|
||||
/// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) };
|
||||
@ -1198,7 +1198,7 @@ impl<T> MaybeUninit<T> {
|
||||
/// #![feature(maybe_uninit_as_bytes)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let val = 0x12345678i32;
|
||||
/// let val = 0x12345678_i32;
|
||||
/// let mut uninit = MaybeUninit::new(val);
|
||||
/// let uninit_bytes = uninit.as_bytes_mut();
|
||||
/// if cfg!(target_endian = "little") {
|
||||
|
@ -1,4 +1,9 @@
|
||||
//! Linux and Android-specific definitions for socket options.
|
||||
//! Android-specific networking functionality.
|
||||
|
||||
#![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;
|
||||
|
@ -1,4 +1,9 @@
|
||||
//! Linux and Android-specific definitions for socket options.
|
||||
//! Linux-specific networking functionality.
|
||||
|
||||
#![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;
|
||||
|
64
library/std/src/os/net/linux_ext/addr.rs
Normal file
64
library/std/src/os/net/linux_ext/addr.rs
Normal 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]>;
|
||||
}
|
12
library/std/src/os/net/linux_ext/mod.rs
Normal file
12
library/std/src/os/net/linux_ext/mod.rs
Normal 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;
|
@ -1,9 +1,8 @@
|
||||
#[cfg(any(target_os = "android", target_os = "linux",))]
|
||||
#[test]
|
||||
fn quickack() {
|
||||
use crate::{
|
||||
net::{test::next_test_ip4, TcpListener, TcpStream},
|
||||
os::net::tcp::TcpStreamExt,
|
||||
os::net::linux_ext::tcp::TcpStreamExt,
|
||||
};
|
||||
|
||||
macro_rules! t {
|
@ -1,7 +1,4 @@
|
||||
//! Linux and Android-specific definitions for socket options.
|
||||
//! OS-specific networking functionality.
|
||||
|
||||
#![unstable(feature = "tcp_quickack", issue = "96256")]
|
||||
#![doc(cfg(any(target_os = "linux", target_os = "android",)))]
|
||||
pub mod tcp;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
#[cfg(any(target_os = "linux", target_os = "android", doc))]
|
||||
pub(super) mod linux_ext;
|
||||
|
@ -1,6 +1,9 @@
|
||||
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::path::Path;
|
||||
use crate::sealed::Sealed;
|
||||
use crate::sys::cvt;
|
||||
use crate::{fmt, io, mem, ptr};
|
||||
|
||||
@ -224,31 +227,6 @@ impl SocketAddr {
|
||||
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<'_> {
|
||||
let len = self.len as usize - sun_path_offset(&self.addr);
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an abstract domain socket address from a namespace
|
||||
///
|
||||
/// 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
|
||||
/// the socket bound to it is closed, so no filesystem clean up is required.
|
||||
///
|
||||
/// The leading null byte for the abstract namespace is automatically added.
|
||||
///
|
||||
/// This is a Linux-specific extension. See more at [`unix(7)`].
|
||||
///
|
||||
/// [`unix(7)`]: https://man7.org/linux/man-pages/man7/unix.7.html
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This will return an error if the given namespace is too long
|
||||
///
|
||||
/// # 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> {
|
||||
#[unstable(feature = "unix_socket_abstract", issue = "85410")]
|
||||
impl Sealed for SocketAddr {}
|
||||
|
||||
#[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")]
|
||||
impl linux_ext::addr::SocketAddrExt for SocketAddr {
|
||||
fn as_abstract_name(&self) -> Option<&[u8]> {
|
||||
if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
|
||||
}
|
||||
|
||||
fn from_abstract_name<N>(name: &N) -> crate::io::Result<Self>
|
||||
where
|
||||
N: AsRef<[u8]>,
|
||||
{
|
||||
let name = name.as_ref();
|
||||
unsafe {
|
||||
let mut addr: libc::sockaddr_un = mem::zeroed();
|
||||
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!(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"namespace must be shorter than SUN_LEN",
|
||||
"abstract socket name must be shorter than SUN_LEN",
|
||||
));
|
||||
}
|
||||
|
||||
crate::ptr::copy_nonoverlapping(
|
||||
namespace.as_ptr(),
|
||||
name.as_ptr(),
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,12 @@ use crate::sys_common::io::test::tmpdir;
|
||||
use crate::thread;
|
||||
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 {
|
||||
($e:expr) => {
|
||||
match $e {
|
||||
@ -404,7 +410,7 @@ fn test_abstract_stream_connect() {
|
||||
let msg1 = b"hello";
|
||||
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 thread = thread::spawn(move || {
|
||||
@ -418,7 +424,7 @@ fn test_abstract_stream_connect() {
|
||||
let mut stream = or_panic!(UnixStream::connect_addr(&socket_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));
|
||||
let mut buf = vec![];
|
||||
@ -432,7 +438,7 @@ fn test_abstract_stream_connect() {
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[test]
|
||||
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 thread = thread::spawn(move || {
|
||||
@ -454,13 +460,13 @@ fn test_abstract_stream_iter() {
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[test]
|
||||
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 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 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));
|
||||
assert_eq!(msg, &buf[..]);
|
||||
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"))]
|
||||
#[test]
|
||||
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 sock = or_panic!(UnixDatagram::unbound());
|
||||
@ -489,7 +495,7 @@ fn test_abstract_datagram_connect_addr() {
|
||||
assert_eq!(addr.is_unnamed(), true);
|
||||
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));
|
||||
|
||||
or_panic!(sock.connect_addr(&addr2));
|
||||
@ -499,8 +505,8 @@ fn test_abstract_datagram_connect_addr() {
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_abstract_namespace_too_long() {
|
||||
match SocketAddr::from_abstract_namespace(
|
||||
fn test_abstract_name_too_long() {
|
||||
match SocketAddr::from_abstract_name(
|
||||
b"abcdefghijklmnopqrstuvwxyzabcdefghijklmn\
|
||||
opqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi\
|
||||
jklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
|
||||
@ -513,11 +519,11 @@ fn test_abstract_namespace_too_long() {
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_abstract_namespace_no_pathname_and_not_unnamed() {
|
||||
let namespace = b"local";
|
||||
let addr = or_panic!(SocketAddr::from_abstract_namespace(&namespace[..]));
|
||||
fn test_abstract_no_pathname_and_not_unnamed() {
|
||||
let name = b"local";
|
||||
let addr = or_panic!(SocketAddr::from_abstract_name(name));
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -674,7 +674,7 @@ impl FromWithTcx<clean::Variant> for Variant {
|
||||
impl FromWithTcx<clean::Discriminant> for Discriminant {
|
||||
fn from_tcx(disr: clean::Discriminant, tcx: TyCtxt<'_>) -> Self {
|
||||
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
|
||||
// the expr is always some.
|
||||
expr: disr.expr(tcx).unwrap(),
|
||||
|
@ -277,7 +277,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
|
||||
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.
|
||||
let foreign_trait_items = self.get_trait_items();
|
||||
let mut index = (*self.index).clone().into_inner();
|
||||
|
@ -354,7 +354,14 @@ impl Visitor<'_> for EarlyDocLinkResolver<'_, '_> {
|
||||
self.parent_scope.module = old_module;
|
||||
} else {
|
||||
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());
|
||||
}
|
||||
ItemKind::MacroDef(macro_def) if macro_def.macro_rules => {
|
||||
|
@ -53,7 +53,7 @@ pub struct ItemSummary {
|
||||
/// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
|
||||
///
|
||||
/// 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
|
||||
/// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
|
||||
pub path: Vec<String>,
|
||||
@ -351,7 +351,7 @@ pub enum Variant {
|
||||
/// A variant with unnamed fields.
|
||||
///
|
||||
/// 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
|
||||
/// enum Demo {
|
||||
|
14
src/test/rustdoc/intra-doc/issue-104145.rs
Normal file
14
src/test/rustdoc/intra-doc/issue-104145.rs
Normal 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() {}
|
@ -1,5 +1,3 @@
|
||||
// known-bug: unknown
|
||||
// FIXME(chalk): Chalk needs support for the Tuple trait
|
||||
// compile-flags: -Z chalk
|
||||
|
||||
fn main() -> () {
|
||||
@ -26,7 +24,7 @@ fn main() -> () {
|
||||
let mut c = b;
|
||||
|
||||
c();
|
||||
b(); // FIXME: reenable when this is fixed ~ ERROR
|
||||
b(); //~ ERROR
|
||||
|
||||
// FIXME(chalk): this doesn't quite work
|
||||
/*
|
||||
|
@ -1,80 +1,22 @@
|
||||
error[E0277]: `()` is not a tuple
|
||||
--> $DIR/closure.rs:7: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
|
||||
error[E0382]: borrow of moved value: `b`
|
||||
--> $DIR/closure.rs:27:5
|
||||
|
|
||||
LL | let mut c = b;
|
||||
| - value moved here
|
||||
...
|
||||
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
|
||||
--> $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: aborting due to previous error
|
||||
|
||||
error[E0277]: `()` is not a tuple
|
||||
--> $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`.
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
|
@ -1,5 +1,4 @@
|
||||
// known-bug: unknown
|
||||
// FIXME(chalk): Chalk needs support for the Tuple trait
|
||||
// check-pass
|
||||
// compile-flags: -Z chalk
|
||||
|
||||
use std::fmt::Display;
|
||||
|
@ -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`.
|
@ -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
|
||||
|
|
||||
LL | impl GoMut for MyThingy {
|
||||
|
@ -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
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
@ -7,7 +7,7 @@ LL |
|
||||
LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
|
@ -9,7 +9,7 @@ LL | impl Copy for i32 {}
|
||||
|
|
||||
= 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
|
||||
|
|
||||
LL | impl Copy for &'static NotSync {}
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<T:Sugar> Sweet for T { }
|
||||
| ------------------------- first implementation here
|
||||
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<_>`
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl <P, T: Foo<P>> Foo<P> for Option<T> {}
|
||||
| ---------------------------------------- first implementation here
|
||||
LL |
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b)
|
||||
| ------------------------------------------------------------ first implementation here
|
||||
...
|
||||
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!
|
||||
= note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<T: lib::MyCopy> MyTrait for T { }
|
||||
| ---------------------------------- first implementation here
|
||||
...
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<T: lib::MyCopy> MyTrait for T { }
|
||||
| ---------------------------------- first implementation here
|
||||
...
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl From<()> for S {
|
||||
|
9
src/test/ui/consts/invalid-inline-const-in-match-arm.rs
Normal file
9
src/test/ui/consts/invalid-inline-const-in-match-arm.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(inline_const_pat)]
|
||||
|
||||
fn main() {
|
||||
match () {
|
||||
const { (|| {})() } => {}
|
||||
//~^ ERROR cannot call non-const closure in constants
|
||||
}
|
||||
}
|
12
src/test/ui/consts/invalid-inline-const-in-match-arm.stderr
Normal file
12
src/test/ui/consts/invalid-inline-const-in-match-arm.stderr
Normal 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`.
|
@ -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
|
||||
|
|
||||
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>
|
||||
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
|
||||
|
|
||||
LL | impl From<S> for S {
|
||||
@ -17,7 +17,7 @@ LL | impl From<S> for S {
|
||||
= note: conflicting implementation in crate `core`:
|
||||
- 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
|
||||
|
|
||||
LL | impl TryFrom<X> for X {
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<S> Into<S> for GenX<S> {
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<S: Storage> From<S::Error> for MyError<S> {
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl Drop for MyStruct {
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<X, T> Trait1<X> for T where T: Trait2<X> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Regression test for #48728, an ICE that occurred computing
|
||||
// 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>);
|
||||
|
||||
impl<T: Clone + ?Sized> Clone for Node<[T]> {
|
||||
|
@ -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
|
||||
|
|
||||
LL | #[derive(Clone)]
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl Foo for dyn Send {}
|
||||
| --------------------- first implementation here
|
||||
LL |
|
||||
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!
|
||||
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
||||
= 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
|
||||
|
|
||||
LL | impl Foo for dyn Send + Sync {}
|
||||
| ---------------------------- first implementation here
|
||||
LL |
|
||||
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!
|
||||
= 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
|
||||
|
|
||||
LL | impl Foo for dyn Sync + Send {}
|
||||
| ---------------------------- first implementation here
|
||||
...
|
||||
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!
|
||||
= 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
|
||||
|
||||
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
|
||||
|
|
||||
LL | impl Foo for dyn Send {}
|
||||
| --------------------- first implementation here
|
||||
LL |
|
||||
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!
|
||||
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
||||
= note: `#[deny(order_dependent_trait_objects)]` on by default
|
||||
|
||||
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
|
||||
|
|
||||
LL | impl Foo for dyn Send + Sync {}
|
||||
| ---------------------------- first implementation here
|
||||
LL |
|
||||
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!
|
||||
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
||||
= note: `#[deny(order_dependent_trait_objects)]` on by default
|
||||
|
||||
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
|
||||
|
|
||||
LL | impl Foo for dyn Sync + Send {}
|
||||
| ---------------------------- first implementation here
|
||||
...
|
||||
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!
|
||||
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
||||
|
31
src/test/ui/parser/recover-fn-ptr-with-generics.rs
Normal file
31
src/test/ui/parser/recover-fn-ptr-with-generics.rs
Normal 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 `>`
|
||||
}
|
111
src/test/ui/parser/recover-fn-ptr-with-generics.stderr
Normal file
111
src/test/ui/parser/recover-fn-ptr-with-generics.stderr
Normal 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`.
|
@ -10,7 +10,7 @@ LL | impl const std::ops::Add for i32 {
|
||||
|
|
||||
= 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
|
||||
|
|
||||
LL | impl std::ops::Add for Int {
|
||||
|
@ -8,7 +8,7 @@ LL | #![feature(specialization)]
|
||||
= help: consider using `min_specialization` instead, which is more stable and complete
|
||||
= 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
|
||||
|
|
||||
LL | unsafe impl<T: Clone> Send for TestType<T> {}
|
||||
|
@ -8,13 +8,13 @@ LL | #![feature(specialization)]
|
||||
= help: consider using `min_specialization` instead, which is more stable and complete
|
||||
= 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
|
||||
|
|
||||
LL | impl<T: Clone> Foo for T {}
|
||||
| ------------------------ first implementation here
|
||||
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)`
|
||||
--> $DIR/specialization-overlap.rs:9:1
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl Trait1 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
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
|
||||
|
|
||||
LL | impl Trait2 for dyn Send {}
|
||||
@ -14,21 +14,21 @@ LL | impl Trait2 for dyn Send {}
|
||||
LL | impl !Trait2 for dyn Send {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
|
||||
LL | impl Trait3<dyn Sync> for dyn Send {}
|
||||
| ---------------------------------- first implementation here
|
||||
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
|
||||
|
|
||||
LL | impl<T: ?Sized> Trait4a for T {}
|
||||
| ----------------------------- first implementation here
|
||||
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 `()`
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:46:1
|
||||
@ -38,42 +38,42 @@ LL | impl Trait4b for () {}
|
||||
LL | impl Trait4b 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
|
||||
|
|
||||
LL | impl Trait4c for dyn Trait1 + Send {}
|
||||
| ---------------------------------- first implementation here
|
||||
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
|
||||
|
|
||||
LL | impl<'a> Trait4d for dyn Send + 'a {}
|
||||
| ---------------------------------- first implementation here
|
||||
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
|
||||
|
|
||||
LL | impl Trait5 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
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
|
||||
|
||||
Some errors have detailed explanations: E0119, E0751.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
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
|
||||
|
|
||||
LL | impl Trait0 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
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!
|
||||
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl Trait for dyn Send + Sync {
|
||||
| ------------------------------ first implementation here
|
||||
...
|
||||
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
|
||||
|
|
||||
LL | impl Trait2 for dyn Send + Sync {
|
||||
| ------------------------------- first implementation here
|
||||
...
|
||||
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`
|
||||
--> $DIR/issue-33140.rs:29:5
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<'a> Clone for &'a mut MyType<'a> {
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl<'a> DerefMut for &'a MyType<'a> {
|
||||
|
@ -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
|
||||
|
|
||||
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
|
||||
| ------------------------------------------------------ first implementation here
|
||||
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!
|
||||
= 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)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
|
|
||||
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
|
||||
| ------------------------------------------------------------- first implementation here
|
||||
...
|
||||
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!
|
||||
= 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
|
||||
|
|
||||
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
|
||||
| ------------------------------------------------------ first implementation here
|
||||
...
|
||||
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!
|
||||
= 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
|
||||
|
||||
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
|
||||
|
|
||||
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
|
||||
| ------------------------------------------------------ first implementation here
|
||||
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!
|
||||
= 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:
|
||||
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
|
||||
|
|
||||
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
|
||||
| ------------------------------------------------------------- first implementation here
|
||||
...
|
||||
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!
|
||||
= 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:
|
||||
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
|
||||
|
|
||||
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
|
||||
| ------------------------------------------------------ first implementation here
|
||||
...
|
||||
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!
|
||||
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
||||
|
@ -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
|
||||
|
|
||||
LL | impl !Send for MyStruct {}
|
||||
|
@ -8,7 +8,8 @@
|
||||
//! `x.py`, in that order of preference.
|
||||
|
||||
use std::{
|
||||
env, io,
|
||||
env::{self, consts::EXE_EXTENSION},
|
||||
io,
|
||||
process::{self, Command, ExitStatus},
|
||||
};
|
||||
|
||||
@ -27,12 +28,12 @@ fn python() -> &'static str {
|
||||
|
||||
for dir in env::split_paths(&val) {
|
||||
// `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;
|
||||
}
|
||||
|
||||
python2 |= dir.join(PYTHON2).exists();
|
||||
python3 |= dir.join(PYTHON3).exists();
|
||||
python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists();
|
||||
python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists();
|
||||
}
|
||||
|
||||
// try 3 before 2
|
||||
|
Loading…
Reference in New Issue
Block a user