Skip to content

Rollup of 9 pull requests #122607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Mar 17, 2024
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
8b576d5
fix attribute validation on associated items in traits
gvozdvmozgu Feb 24, 2024
c121a26
Split refining_impl_trait lint into _reachable, _internal variants
tmandry Feb 28, 2024
f25809d
fix `long-linker-command-lines` failure caused by `rust.rpath=false`
onur-ozkan Mar 10, 2024
a37fe00
Remove obsolete parameter `speculative` from `instantiate_poly_trait_…
fmease Mar 16, 2024
873a0f2
Add `wasm_c_abi` `future-incompat` lint
daxpedda Nov 14, 2023
f272133
core: optimize `ptr::replace`
joboet Mar 16, 2024
b2ed9d0
Delegation: fix ICE on duplicated associative items
Bryanskiy Mar 16, 2024
fc42f3b
Mention @jieyouxu for changes to compiletest, run-make tests and the …
jieyouxu Mar 16, 2024
ad84934
rustc-metadata: Store crate name in self-profile of metadata_register…
osiewicz Mar 16, 2024
c00c5fe
Rollup merge of #117918 - daxpedda:wasm-c-abi-warning, r=workingjubilee
fmease Mar 16, 2024
79c1e58
Rollup merge of #121545 - gvozdvmozgu:fix-attribute-validation-associ…
fmease Mar 16, 2024
0995508
Rollup merge of #121720 - tmandry:split-refining, r=compiler-errors
fmease Mar 16, 2024
c2b7d77
Rollup merge of #122270 - onur-ozkan:fix-rmake-test-with-rpath-false,…
fmease Mar 16, 2024
7b7a7fc
Rollup merge of #122564 - Bryanskiy:delegation-fixes, r=compiler-errors
fmease Mar 16, 2024
4cbfa15
Rollup merge of #122577 - fmease:speculative-say-what, r=compiler-errors
fmease Mar 16, 2024
de0c2a4
Rollup merge of #122601 - joboet:ptr_replace, r=workingjubilee
fmease Mar 16, 2024
53515f3
Rollup merge of #122604 - jieyouxu:triagebot-mention-compiletest-run-…
fmease Mar 16, 2024
caa6131
Rollup merge of #122605 - osiewicz:metadata-register-crate-store-crat…
fmease Mar 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
@@ -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),
}
}

1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
@@ -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(_) => {
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
@@ -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
101 changes: 47 additions & 54 deletions compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
@@ -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:
4 changes: 1 addition & 3 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/astconv/object_safety.rs
Original file line number Diff line number Diff line change
@@ -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),
33 changes: 17 additions & 16 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
Original file line number Diff line number Diff line change
@@ -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 {
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
@@ -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,
6 changes: 6 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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");
129 changes: 119 additions & 10 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -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,21 +4428,88 @@ 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();
/// }
/// ```
///
/// {{produces}}
///
/// ### 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
}
2 changes: 2 additions & 0 deletions compiler/rustc_metadata/messages.ftl
Original file line number Diff line number Diff line change
@@ -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"`
45 changes: 43 additions & 2 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
@@ -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,13 +987,52 @@ 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);
self.inject_allocator_crate(krate);
self.inject_panic_runtime(krate);

self.report_unused_deps(krate);
self.report_future_incompatible_deps(krate);

info!("{:?}", CrateDump(self.cstore));
}
5 changes: 2 additions & 3 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions src/tools/lint-docs/src/groups.rs
Original file line number Diff line number Diff line change
@@ -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>>;
2 changes: 2 additions & 0 deletions tests/run-make/long-linker-command-lines/Makefile
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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> {
Original file line number Diff line number Diff line change
@@ -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> {
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
trait MyTrait {
#[doc = MyTrait]
//~^ ERROR attribute value must be a literal
fn myfun();
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -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

23 changes: 23 additions & 0 deletions tests/ui/delegation/duplicate-definition-inside-trait-impl.rs
Original file line number Diff line number Diff line change
@@ -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() {}
23 changes: 23 additions & 0 deletions tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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<'_>> + '_ {
30 changes: 26 additions & 4 deletions tests/ui/impl-trait/in-trait/foreign.rs
Original file line number Diff line number Diff line change
@@ -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();
}
39 changes: 39 additions & 0 deletions tests/ui/impl-trait/in-trait/foreign.stderr
Original file line number Diff line number Diff line change
@@ -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

3 changes: 3 additions & 0 deletions tests/ui/impl-trait/in-trait/refine.rs
Original file line number Diff line number Diff line change
@@ -25,13 +25,15 @@ 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> {
fn bar() -> impl Sized;
}
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
}
}

58 changes: 56 additions & 2 deletions tests/ui/impl-trait/in-trait/refine.stderr
Original file line number Diff line number Diff line change
@@ -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

11 changes: 11 additions & 0 deletions triagebot.toml
Original file line number Diff line number Diff line change
@@ -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 \