mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 21:47:04 +00:00
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:
commit
c8813ddd6d
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(_) => {
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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"`
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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>>;
|
||||
|
@ -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)
|
||||
|
@ -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> {
|
||||
|
@ -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> {
|
||||
|
@ -0,0 +1,7 @@
|
||||
trait MyTrait {
|
||||
#[doc = MyTrait]
|
||||
//~^ ERROR attribute value must be a literal
|
||||
fn myfun();
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -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
|
||||
|
@ -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() {}
|
@ -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`.
|
@ -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<'_>> + '_ {
|
||||
|
@ -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
tests/ui/impl-trait/in-trait/foreign.stderr
Normal file
39
tests/ui/impl-trait/in-trait/foreign.stderr
Normal 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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user