Auto merge of #122607 - fmease:rollup-ozl1eeq, r=fmease

Rollup of 9 pull requests

Successful merges:

 - #117918 (Add `wasm_c_abi` `future-incompat` lint)
 - #121545 (fix attribute validation on associated items in traits)
 - #121720 (Split refining_impl_trait lint into _reachable, _internal variants)
 - #122270 (fix `long-linker-command-lines` failure caused by `rust.rpath=false`)
 - #122564 (Delegation: fix ICE on duplicated associative items)
 - #122577 (Remove obsolete parameter `speculative` from `instantiate_poly_trait_ref`)
 - #122601 (Optimize `ptr::replace`)
 - #122604 (Mention jieyouxu for changes to compiletest, run-make tests and the run-make-support library)
 - #122605 (rustc-metadata: Store crate name in self-profile of metadata_register_crate)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-03-17 00:22:29 +00:00
commit c8813ddd6d
27 changed files with 454 additions and 104 deletions

View File

@ -373,6 +373,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
(trait_ref, lowered_ty)
});
self.is_in_trait_impl = trait_ref.is_some();
let new_impl_items = self
.arena
.alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
@ -978,13 +979,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
let trait_item_def_id = self
.resolver
.get_partial_res(i.id)
.map(|r| r.expect_full_res().opt_def_id())
.unwrap_or(None);
self.is_in_trait_impl = trait_item_def_id.is_some();
hir::ImplItemRef {
id: hir::ImplItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } },
ident: self.lower_ident(i.ident),
@ -1000,7 +994,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
},
AssocItemKind::MacCall(..) => unimplemented!(),
},
trait_item_def_id,
trait_item_def_id: self
.resolver
.get_partial_res(i.id)
.map(|r| r.expect_full_res().opt_def_id())
.unwrap_or(None),
}
}

View File

@ -1527,6 +1527,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
generics,
body.as_deref(),
);
walk_list!(self, visit_attribute, &item.attrs);
self.visit_fn(kind, item.span, item.id);
}
AssocItemKind::Type(_) => {

View File

@ -351,6 +351,7 @@ hir_analysis_rpitit_refined = impl trait in impl method signature does not match
.label = return type from trait method defined here
.unmatched_bound_label = this bound is stronger than that defined on the trait
.note = add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
.feedback_note = we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
hir_analysis_self_in_impl_self =
`Self` is not valid in the self type of an impl block

View File

@ -149,7 +149,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
polarity,
param_ty,
bounds,
false,
only_self_bounds,
);
}
@ -231,14 +230,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
/// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
/// the binder (e.g., `&'a u32`) and hence may reference bound regions.
#[instrument(level = "debug", skip(self, bounds, speculative, dup_bindings, path_span))]
#[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))]
pub(super) fn add_predicates_for_ast_type_binding(
&self,
hir_ref_id: hir::HirId,
trait_ref: ty::PolyTraitRef<'tcx>,
binding: &hir::TypeBinding<'tcx>,
bounds: &mut Bounds<'tcx>,
speculative: bool,
dup_bindings: &mut FxIndexMap<DefId, Span>,
path_span: Span,
only_self_bounds: OnlySelfBounds,
@ -317,19 +315,17 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
if !speculative {
dup_bindings
.entry(assoc_item.def_id)
.and_modify(|prev_span| {
tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
span: binding.span,
prev_span: *prev_span,
item_name: binding.ident,
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
});
})
.or_insert(binding.span);
}
dup_bindings
.entry(assoc_item.def_id)
.and_modify(|prev_span| {
tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
span: binding.span,
prev_span: *prev_span,
item_name: binding.ident,
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
});
})
.or_insert(binding.span);
let projection_ty = if let ty::AssocKind::Fn = assoc_kind {
let mut emitted_bad_param_err = None;
@ -433,9 +429,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
});
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
if !speculative
&& let hir::TypeBindingKind::Equality { term: hir::Term::Const(anon_const) } =
binding.kind
if let hir::TypeBindingKind::Equality { term: hir::Term::Const(anon_const) } =
binding.kind
{
let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args));
// Since the arguments passed to the alias type above may contain early-bound
@ -463,42 +458,40 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
};
if !speculative {
// Find any late-bound regions declared in `ty` that are not
// declared in the trait-ref or assoc_item. These are not well-formed.
//
// Example:
//
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
let late_bound_in_projection_ty =
tcx.collect_constrained_late_bound_regions(projection_ty);
let late_bound_in_term =
tcx.collect_referenced_late_bound_regions(trait_ref.rebind(term));
debug!(?late_bound_in_projection_ty);
debug!(?late_bound_in_term);
// Find any late-bound regions declared in `ty` that are not
// declared in the trait-ref or assoc_item. These are not well-formed.
//
// Example:
//
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
let late_bound_in_projection_ty =
tcx.collect_constrained_late_bound_regions(projection_ty);
let late_bound_in_term =
tcx.collect_referenced_late_bound_regions(trait_ref.rebind(term));
debug!(?late_bound_in_projection_ty);
debug!(?late_bound_in_term);
// FIXME: point at the type params that don't have appropriate lifetimes:
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
// ---- ---- ^^^^^^^
// NOTE(associated_const_equality): This error should be impossible to trigger
// with associated const equality bounds.
self.validate_late_bound_regions(
late_bound_in_projection_ty,
late_bound_in_term,
|br_name| {
struct_span_code_err!(
tcx.dcx(),
binding.span,
E0582,
"binding for associated type `{}` references {}, \
which does not appear in the trait input types",
binding.ident,
br_name
)
},
);
}
// FIXME: point at the type params that don't have appropriate lifetimes:
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
// ---- ---- ^^^^^^^
// NOTE(associated_const_equality): This error should be impossible to trigger
// with associated const equality bounds.
self.validate_late_bound_regions(
late_bound_in_projection_ty,
late_bound_in_term,
|br_name| {
struct_span_code_err!(
tcx.dcx(),
binding.span,
E0582,
"binding for associated type `{}` references {}, \
which does not appear in the trait input types",
binding.ident,
br_name
)
},
);
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
// the "projection predicate" for:

View File

@ -639,7 +639,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
/// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
/// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
/// however.
#[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
#[instrument(level = "debug", skip(self, span, constness, bounds))]
pub(crate) fn instantiate_poly_trait_ref(
&self,
trait_ref: &hir::TraitRef<'tcx>,
@ -648,7 +648,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
polarity: ty::ImplPolarity,
self_ty: Ty<'tcx>,
bounds: &mut Bounds<'tcx>,
speculative: bool,
only_self_bounds: OnlySelfBounds,
) -> GenericArgCountResult {
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
@ -697,7 +696,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
poly_trait_ref,
binding,
bounds,
speculative,
&mut dup_bindings,
binding.span,
only_self_bounds,

View File

@ -44,7 +44,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
ty::ImplPolarity::Positive,
dummy_self,
&mut bounds,
false,
// True so we don't populate `bounds` with associated type bounds, even
// though they're disallowed from object types.
OnlySelfBounds(true),

View File

@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt};
use rustc_lint_defs::builtin::REFINING_IMPL_TRAIT;
use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
use rustc_middle::traits::{ObligationCause, Reveal};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
@ -23,26 +23,23 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
if !tcx.impl_method_has_trait_impl_trait_tys(impl_m.def_id) {
return;
}
// unreachable traits don't have any library guarantees, there's no need to do this check.
if trait_m
let is_internal = trait_m
.container_id(tcx)
.as_local()
.is_some_and(|trait_def_id| !tcx.effective_visibilities(()).is_reachable(trait_def_id))
{
return;
}
// If a type in the trait ref is private, then there's also no reason to do this check.
|| impl_trait_ref.args.iter().any(|arg| {
if let Some(ty) = arg.as_type()
&& let Some(self_visibility) = type_visibility(tcx, ty)
{
return !self_visibility.is_public();
}
false
});
// If a type in the trait ref is private, then there's also no reason to do this check.
let impl_def_id = impl_m.container_id(tcx);
for arg in impl_trait_ref.args {
if let Some(ty) = arg.as_type()
&& let Some(self_visibility) = type_visibility(tcx, ty)
&& !self_visibility.is_public()
{
return;
}
}
let impl_m_args = ty::GenericArgs::identity_for_item(tcx, impl_m.def_id);
let trait_m_to_impl_m_args = impl_m_args.rebase_onto(tcx, impl_def_id, impl_trait_ref.args);
let bound_trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_to_impl_m_args);
@ -85,6 +82,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
trait_m.def_id,
impl_m.def_id,
None,
is_internal,
);
return;
};
@ -104,6 +102,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
trait_m.def_id,
impl_m.def_id,
None,
is_internal,
);
return;
}
@ -198,6 +197,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
trait_m.def_id,
impl_m.def_id,
Some(span),
is_internal,
);
return;
}
@ -235,6 +235,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
trait_m_def_id: DefId,
impl_m_def_id: DefId,
unmatched_bound: Option<Span>,
is_internal: bool,
) {
let mapping = std::iter::zip(
tcx.fn_sig(trait_m_def_id).skip_binder().bound_vars(),
@ -287,7 +288,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
let span = unmatched_bound.unwrap_or(span);
tcx.emit_node_span_lint(
REFINING_IMPL_TRAIT,
if is_internal { REFINING_IMPL_TRAIT_INTERNAL } else { REFINING_IMPL_TRAIT_REACHABLE },
tcx.local_def_id_to_hir_id(impl_m_def_id.expect_local()),
span,
crate::errors::ReturnPositionImplTraitInTraitRefined {

View File

@ -1072,6 +1072,7 @@ pub struct UnusedAssociatedTypeBounds {
#[derive(LintDiagnostic)]
#[diag(hir_analysis_rpitit_refined)]
#[note]
#[note(hir_analysis_feedback_note)]
pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
#[suggestion(applicability = "maybe-incorrect", code = "{pre}{return_ty}{post}")]
pub impl_return_span: Span,

View File

@ -313,6 +313,12 @@ fn register_builtins(store: &mut LintStore) {
// MACRO_USE_EXTERN_CRATE
);
add_lint_group!(
"refining_impl_trait",
REFINING_IMPL_TRAIT_REACHABLE,
REFINING_IMPL_TRAIT_INTERNAL
);
// Register renamed and removed lints.
store.register_renamed("single_use_lifetime", "single_use_lifetimes");
store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");

View File

@ -79,7 +79,8 @@ declare_lint_pass! {
PROC_MACRO_BACK_COMPAT,
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
REFINING_IMPL_TRAIT,
REFINING_IMPL_TRAIT_INTERNAL,
REFINING_IMPL_TRAIT_REACHABLE,
RENAMED_AND_REMOVED_LINTS,
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
@ -130,6 +131,7 @@ declare_lint_pass! {
UNUSED_VARIABLES,
USELESS_DEPRECATED,
WARNINGS,
WASM_C_ABI,
WHERE_CLAUSES_OBJECT_SAFETY,
WRITES_THROUGH_IMMUTABLE_POINTER,
// tidy-alphabetical-end
@ -4401,8 +4403,10 @@ declare_lint! {
}
declare_lint! {
/// The `refining_impl_trait` lint detects usages of return-position impl
/// traits in trait signatures which are refined by implementations.
/// The `refining_impl_trait_reachable` lint detects `impl Trait` return
/// types in method signatures that are refined by a publically reachable
/// trait implementation, meaning the implementation adds information about
/// the return type that is not present in the trait.
///
/// ### Example
///
@ -4424,7 +4428,7 @@ declare_lint! {
/// fn main() {
/// // users can observe that the return type of
/// // `<&str as AsDisplay>::as_display()` is `&str`.
/// let x: &str = "".as_display();
/// let _x: &str = "".as_display();
/// }
/// ```
///
@ -4432,13 +4436,80 @@ declare_lint! {
///
/// ### Explanation
///
/// Return-position impl trait in traits (RPITITs) desugar to associated types,
/// and callers of methods for types where the implementation is known are
/// Callers of methods for types where the implementation is known are
/// able to observe the types written in the impl signature. This may be
/// intended behavior, but may also pose a semver hazard for authors of libraries
/// who do not wish to make stronger guarantees about the types than what is
/// written in the trait signature.
pub REFINING_IMPL_TRAIT,
/// intended behavior, but may also lead to implementation details being
/// revealed unintentionally. In particular, it may pose a semver hazard
/// for authors of libraries who do not wish to make stronger guarantees
/// about the types than what is written in the trait signature.
///
/// `refining_impl_trait` is a lint group composed of two lints:
///
/// * `refining_impl_trait_reachable`, for refinements that are publically
/// reachable outside a crate, and
/// * `refining_impl_trait_internal`, for refinements that are only visible
/// within a crate.
///
/// We are seeking feedback on each of these lints; see issue
/// [#121718](https://github.com/rust-lang/rust/issues/121718) for more
/// information.
pub REFINING_IMPL_TRAIT_REACHABLE,
Warn,
"impl trait in impl method signature does not match trait method signature",
}
declare_lint! {
/// The `refining_impl_trait_internal` lint detects `impl Trait` return
/// types in method signatures that are refined by a trait implementation,
/// meaning the implementation adds information about the return type that
/// is not present in the trait.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(refining_impl_trait)]
///
/// use std::fmt::Display;
///
/// trait AsDisplay {
/// fn as_display(&self) -> impl Display;
/// }
///
/// impl<'s> AsDisplay for &'s str {
/// fn as_display(&self) -> Self {
/// *self
/// }
/// }
///
/// fn main() {
/// // users can observe that the return type of
/// // `<&str as AsDisplay>::as_display()` is `&str`.
/// let _x: &str = "".as_display();
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Callers of methods for types where the implementation is known are
/// able to observe the types written in the impl signature. This may be
/// intended behavior, but may also lead to implementation details being
/// revealed unintentionally. In particular, it may pose a semver hazard
/// for authors of libraries who do not wish to make stronger guarantees
/// about the types than what is written in the trait signature.
///
/// `refining_impl_trait` is a lint group composed of two lints:
///
/// * `refining_impl_trait_reachable`, for refinements that are publically
/// reachable outside a crate, and
/// * `refining_impl_trait_internal`, for refinements that are only visible
/// within a crate.
///
/// We are seeking feedback on each of these lints; see issue
/// [#121718](https://github.com/rust-lang/rust/issues/121718) for more
/// information.
pub REFINING_IMPL_TRAIT_INTERNAL,
Warn,
"impl trait in impl method signature does not match trait method signature",
}
@ -4564,3 +4635,41 @@ declare_lint! {
reference: "issue #120192 <https://github.com/rust-lang/rust/issues/120192>",
};
}
declare_lint! {
/// The `wasm_c_abi` lint detects crate dependencies that are incompatible
/// with future versions of Rust that will emit spec-compliant C ABI.
///
/// ### Example
///
/// ```rust,ignore (needs extern crate)
/// #![deny(wasm_c_abi)]
/// ```
///
/// This will produce:
///
/// ```text
/// error: the following packages contain code that will be rejected by a future version of Rust: wasm-bindgen v0.2.87
/// |
/// note: the lint level is defined here
/// --> src/lib.rs:1:9
/// |
/// 1 | #![deny(wasm_c_abi)]
/// | ^^^^^^^^^^
/// ```
///
/// ### Explanation
///
/// Rust has historically emitted non-spec-compliant C ABI. This has caused
/// incompatibilities between other compilers and Wasm targets. In a future
/// version of Rust this will be fixed and therefore dependencies relying
/// on the non-spec-compliant C ABI will stop functioning.
pub WASM_C_ABI,
Warn,
"detects dependencies that are incompatible with the Wasm C ABI",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
reference: "issue #71871 <https://github.com/rust-lang/rust/issues/71871>",
};
crate_level_only
}

View File

@ -281,6 +281,8 @@ metadata_unsupported_abi =
metadata_unsupported_abi_i686 =
ABI not supported by `#[link(kind = "raw-dylib")]` on i686
metadata_wasm_c_abi =
older versions of the `wasm-bindgen` crate will be incompatible with future versions of Rust; please update to `wasm-bindgen` v0.2.88
metadata_wasm_import_form =
wasm import module must be of the form `wasm_import_module = "string"`

View File

@ -31,8 +31,9 @@ use proc_macro::bridge::client::ProcMacro;
use std::error::Error;
use std::ops::Fn;
use std::path::Path;
use std::str::FromStr;
use std::time::Duration;
use std::{cmp, iter};
use std::{cmp, env, iter};
/// The backend's way to give the crate store access to the metadata in a library.
/// Note that it returns the raw metadata bytes stored in the library file, whether
@ -397,7 +398,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
name: Symbol,
private_dep: Option<bool>,
) -> Result<CrateNum, CrateError> {
let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
let _prof_timer =
self.sess.prof.generic_activity_with_arg("metadata_register_crate", name.as_str());
let Library { source, metadata } = lib;
let crate_root = metadata.get_root();
@ -985,6 +987,44 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
}
}
fn report_future_incompatible_deps(&self, krate: &ast::Crate) {
let name = self.tcx.crate_name(LOCAL_CRATE);
if name.as_str() == "wasm_bindgen" {
let major = env::var("CARGO_PKG_VERSION_MAJOR")
.ok()
.and_then(|major| u64::from_str(&major).ok());
let minor = env::var("CARGO_PKG_VERSION_MINOR")
.ok()
.and_then(|minor| u64::from_str(&minor).ok());
let patch = env::var("CARGO_PKG_VERSION_PATCH")
.ok()
.and_then(|patch| u64::from_str(&patch).ok());
match (major, minor, patch) {
// v1 or bigger is valid.
(Some(1..), _, _) => return,
// v0.3 or bigger is valid.
(Some(0), Some(3..), _) => return,
// v0.2.88 or bigger is valid.
(Some(0), Some(2), Some(88..)) => return,
// Not using Cargo.
(None, None, None) => return,
_ => (),
}
// Make a point span rather than covering the whole file
let span = krate.spans.inner_span.shrink_to_lo();
self.sess.psess.buffer_lint(
lint::builtin::WASM_C_ABI,
span,
ast::CRATE_NODE_ID,
crate::fluent_generated::metadata_wasm_c_abi,
);
}
}
pub fn postprocess(&mut self, krate: &ast::Crate) {
self.inject_forced_externs();
self.inject_profiler_runtime(krate);
@ -992,6 +1032,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
self.inject_panic_runtime(krate);
self.report_unused_deps(krate);
self.report_future_incompatible_deps(krate);
info!("{:?}", CrateDump(self.cstore));
}

View File

@ -1114,7 +1114,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, coun
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
#[rustc_diagnostic_item = "ptr_replace"]
pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
// SAFETY: the caller must guarantee that `dst` is valid to be
// cast to a mutable reference (valid for writes, aligned, initialized),
// and cannot overlap `src` since `dst` must point to a distinct
@ -1128,9 +1128,8 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
align: usize = align_of::<T>(),
) => is_aligned_and_not_null(addr, align)
);
mem::swap(&mut *dst, &mut src); // cannot overlap
mem::replace(&mut *dst, src)
}
src
}
/// Reads the value from `src` without moving it. This leaves the

View File

@ -16,6 +16,10 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
("rust-2018-compatibility", "Lints used to transition code from the 2015 edition to 2018"),
("rust-2021-compatibility", "Lints used to transition code from the 2018 edition to 2021"),
("rust-2024-compatibility", "Lints used to transition code from the 2021 edition to 2024"),
(
"refining-impl-trait",
"Detects refinement of `impl Trait` return types by trait implementations",
),
];
type LintGroups = BTreeMap<String, BTreeSet<String>>;

View File

@ -1,6 +1,8 @@
# ignore-cross-compile
include ../tools.mk
export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
all:
$(RUSTC) foo.rs -g -O
RUSTC="$(RUSTC_ORIGINAL)" $(call RUN,foo)

View File

@ -8,11 +8,13 @@ LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
note: the lint level is defined here
--> $DIR/async-example-desugared-boxed.rs:13:12
|
LL | #[warn(refining_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^
= note: `#[warn(refining_impl_trait_reachable)]` implied by `#[warn(refining_impl_trait)]`
help: replace the return type so that it matches the trait
|
LL | fn foo(&self) -> impl Future<Output = i32> {

View File

@ -8,11 +8,13 @@ LL | fn foo(&self) -> MyFuture {
| ^^^^^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
note: the lint level is defined here
--> $DIR/async-example-desugared-manual.rs:21:12
|
LL | #[warn(refining_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^
= note: `#[warn(refining_impl_trait_reachable)]` implied by `#[warn(refining_impl_trait)]`
help: replace the return type so that it matches the trait
|
LL | fn foo(&self) -> impl Future<Output = i32> {

View File

@ -0,0 +1,7 @@
trait MyTrait {
#[doc = MyTrait]
//~^ ERROR attribute value must be a literal
fn myfun();
}
fn main() {}

View File

@ -0,0 +1,8 @@
error: attribute value must be a literal
--> $DIR/validation-on-associated-items-issue-121537.rs:2:13
|
LL | #[doc = MyTrait]
| ^^^^^^^
error: aborting due to 1 previous error

View File

@ -0,0 +1,23 @@
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
trait Trait {
fn foo(&self) -> u32 { 0 }
}
struct F;
struct S;
mod to_reuse {
use crate::S;
pub fn foo(_: &S) -> u32 { 0 }
}
impl Trait for S {
reuse to_reuse::foo { self }
reuse Trait::foo;
//~^ ERROR duplicate definitions with name `foo`
}
fn main() {}

View File

@ -0,0 +1,23 @@
error[E0201]: duplicate definitions with name `foo`:
--> $DIR/duplicate-definition-inside-trait-impl.rs:19:5
|
LL | fn foo(&self) -> u32 { 0 }
| -------------------------- item in trait
...
LL | reuse to_reuse::foo { self }
| ---------------------------- previous definition here
LL | reuse Trait::foo;
| ^^^^^^^^^^^^^^^^^ duplicate definition
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/duplicate-definition-inside-trait-impl.rs:1:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0201`.

View File

@ -22,7 +22,8 @@ LL | fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
| ^^ this bound is stronger than that defined on the trait
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: `#[warn(refining_impl_trait)]` on by default
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
= note: `#[warn(refining_impl_trait_reachable)]` on by default
help: replace the return type so that it matches the trait
|
LL | fn iter(&self) -> impl Iterator<Item = <Self as Iterable>::Item<'_>> + '_ {

View File

@ -17,9 +17,29 @@ impl Foo for Local {
}
}
struct LocalIgnoreRefining;
impl Foo for LocalIgnoreRefining {
#[deny(refining_impl_trait)]
struct LocalOnlyRefiningA;
impl Foo for LocalOnlyRefiningA {
#[warn(refining_impl_trait)]
fn bar(self) -> Arc<String> {
//~^ WARN impl method signature does not match trait method signature
Arc::new(String::new())
}
}
struct LocalOnlyRefiningB;
impl Foo for LocalOnlyRefiningB {
#[warn(refining_impl_trait)]
#[allow(refining_impl_trait_reachable)]
fn bar(self) -> Arc<String> {
//~^ WARN impl method signature does not match trait method signature
Arc::new(String::new())
}
}
struct LocalOnlyRefiningC;
impl Foo for LocalOnlyRefiningC {
#[warn(refining_impl_trait)]
#[allow(refining_impl_trait_internal)]
fn bar(self) -> Arc<String> {
Arc::new(String::new())
}
@ -34,5 +54,7 @@ fn main() {
let &() = Foreign.bar();
let x: Arc<String> = Local.bar();
let x: Arc<String> = LocalIgnoreRefining.bar();
let x: Arc<String> = LocalOnlyRefiningA.bar();
let x: Arc<String> = LocalOnlyRefiningB.bar();
let x: Arc<String> = LocalOnlyRefiningC.bar();
}

View File

@ -0,0 +1,39 @@
warning: impl trait in impl method signature does not match trait method signature
--> $DIR/foreign.rs:23:21
|
LL | fn bar(self) -> Arc<String> {
| ^^^^^^^^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
note: the lint level is defined here
--> $DIR/foreign.rs:22:12
|
LL | #[warn(refining_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^
= note: `#[warn(refining_impl_trait_internal)]` implied by `#[warn(refining_impl_trait)]`
help: replace the return type so that it matches the trait
|
LL | fn bar(self) -> impl Deref<Target = impl Sized> {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: impl trait in impl method signature does not match trait method signature
--> $DIR/foreign.rs:33:21
|
LL | fn bar(self) -> Arc<String> {
| ^^^^^^^^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
note: the lint level is defined here
--> $DIR/foreign.rs:31:12
|
LL | #[warn(refining_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^
help: replace the return type so that it matches the trait
|
LL | fn bar(self) -> impl Deref<Target = impl Sized> {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: 2 warnings emitted

View File

@ -25,6 +25,7 @@ impl Foo for C {
struct Private;
impl Foo for Private {
fn bar() -> () {}
//~^ ERROR impl method signature does not match trait method signature
}
pub trait Arg<A> {
@ -32,6 +33,7 @@ pub trait Arg<A> {
}
impl Arg<Private> for A {
fn bar() -> () {}
//~^ ERROR impl method signature does not match trait method signature
}
pub trait Late {
@ -52,6 +54,7 @@ mod unreachable {
struct E;
impl UnreachablePub for E {
fn bar() {}
//~^ ERROR impl method signature does not match trait method signature
}
}

View File

@ -8,11 +8,13 @@ LL | fn bar() -> impl Copy {}
| ^^^^ this bound is stronger than that defined on the trait
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
note: the lint level is defined here
--> $DIR/refine.rs:1:9
|
LL | #![deny(refining_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^
= note: `#[deny(refining_impl_trait_reachable)]` implied by `#[deny(refining_impl_trait)]`
help: replace the return type so that it matches the trait
|
LL | fn bar() -> impl Sized {}
@ -28,6 +30,7 @@ LL | fn bar() {}
| ^^^^^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
help: replace the return type so that it matches the trait
|
LL | fn bar()-> impl Sized {}
@ -43,13 +46,47 @@ LL | fn bar() -> () {}
| ^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
help: replace the return type so that it matches the trait
|
LL | fn bar() -> impl Sized {}
| ~~~~~~~~~~
error: impl trait in impl method signature does not match trait method signature
--> $DIR/refine.rs:43:27
--> $DIR/refine.rs:27:17
|
LL | fn bar() -> impl Sized;
| ---------- return type from trait method defined here
...
LL | fn bar() -> () {}
| ^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
= note: `#[deny(refining_impl_trait_internal)]` implied by `#[deny(refining_impl_trait)]`
help: replace the return type so that it matches the trait
|
LL | fn bar() -> impl Sized {}
| ~~~~~~~~~~
error: impl trait in impl method signature does not match trait method signature
--> $DIR/refine.rs:35:17
|
LL | fn bar() -> impl Sized;
| ---------- return type from trait method defined here
...
LL | fn bar() -> () {}
| ^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
help: replace the return type so that it matches the trait
|
LL | fn bar() -> impl Sized {}
| ~~~~~~~~~~
error: impl trait in impl method signature does not match trait method signature
--> $DIR/refine.rs:45:27
|
LL | fn bar<'a>(&'a self) -> impl Sized + 'a;
| --------------- return type from trait method defined here
@ -58,10 +95,27 @@ LL | fn bar(&self) -> impl Copy + '_ {}
| ^^^^ this bound is stronger than that defined on the trait
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
help: replace the return type so that it matches the trait
|
LL | fn bar(&self) -> impl Sized + '_ {}
| ~~~~~~~~~~~~~~~
error: aborting due to 4 previous errors
error: impl trait in impl method signature does not match trait method signature
--> $DIR/refine.rs:56:9
|
LL | fn bar() -> impl Sized;
| ---------- return type from trait method defined here
...
LL | fn bar() {}
| ^^^^^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
help: replace the return type so that it matches the trait
|
LL | fn bar()-> impl Sized {}
| +++++++++++++
error: aborting due to 7 previous errors

View File

@ -548,6 +548,10 @@ cc = ["@GuillaumeGomez"]
message = "Some changes occurred in GUI tests."
cc = ["@GuillaumeGomez"]
[mentions."tests/run-make/"]
message = "Some changes occurred in run-make tests."
cc = ["@jieyouxu"]
[mentions."src/librustdoc/html/static/css/themes/ayu.css"]
message = "A change occurred in the Ayu theme."
cc = ["@Cldfire"]
@ -571,10 +575,17 @@ cc = ["@ehuss"]
[mentions."src/tools/clippy"]
cc = ["@rust-lang/clippy"]
[mentions."src/tools/compiletest"]
cc = ["@jieyouxu"]
[mentions."src/tools/miri"]
message = "The Miri subtree was changed"
cc = ["@rust-lang/miri"]
[mentions."src/tools/run-make-support"]
message = "The run-make-support library was changed"
cc = ["@jieyouxu"]
[mentions."src/tools/rust-analyzer"]
message = """
rust-analyzer is developed in its own repository. If possible, consider making \