Skip to content

Commit 02557f6

Browse files
committed
Auto merge of rust-lang#129365 - matthiaskrgr:rollup-ebwx6ya, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#127279 (use old ctx if has same expand environment during decode span) - rust-lang#127945 (Implement `debug_more_non_exhaustive`) - rust-lang#128941 ( Improve diagnostic-related lints: `untranslatable_diagnostic` & `diagnostic_outside_of_impl`) - rust-lang#129070 (Point at explicit `'static` obligations on a trait) - rust-lang#129187 (bootstrap: fix clean's remove_dir_all implementation) - rust-lang#129231 (improve submodule updates) - rust-lang#129264 (Update `library/Cargo.toml` in weekly job) - rust-lang#129284 (rustdoc: animate the `:target` highlight) - rust-lang#129302 (compiletest: use `std::fs::remove_dir_all` now that it is available) r? `@ghost` `@rustbot` modify labels: rollup
2 parents a32d4a0 + 33dc313 commit 02557f6

File tree

25 files changed

+987
-368
lines changed

25 files changed

+987
-368
lines changed

.github/workflows/dependencies.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ jobs:
6464
- name: cargo update
6565
# Remove first line that always just says "Updating crates.io index"
6666
run: cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
67+
- name: cargo update library
68+
run: |
69+
echo -e "\nlibrary dependencies:" >> cargo_update.log
70+
cargo update --manifest-path library/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
6771
- name: cargo update rustbook
6872
run: |
6973
echo -e "\nrustbook dependencies:" >> cargo_update.log
@@ -74,6 +78,7 @@ jobs:
7478
name: Cargo-lock
7579
path: |
7680
Cargo.lock
81+
library/Cargo.lock
7782
src/tools/rustbook/Cargo.lock
7883
retention-days: 1
7984
- name: upload cargo-update log artifact for use in PR
@@ -119,7 +124,7 @@ jobs:
119124
git config user.name github-actions
120125
git config user.email [email protected]
121126
git switch --force-create cargo_update
122-
git add ./Cargo.lock ./src/tools/rustbook/Cargo.lock
127+
git add ./Cargo.lock ./library/Cargo.lock ./src/tools/rustbook/Cargo.lock
123128
git commit --no-verify --file=commit.txt
124129
125130
- name: push

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ fn region_known_to_outlive<'tcx>(
747747
region_b: ty::Region<'tcx>,
748748
) -> bool {
749749
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
750-
infcx.sub_regions(infer::RelateRegionParamBound(DUMMY_SP), region_b, region_a);
750+
infcx.sub_regions(infer::RelateRegionParamBound(DUMMY_SP, None), region_b, region_a);
751751
})
752752
}
753753

compiler/rustc_infer/src/infer/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
167167
}
168168

169169
fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) {
170-
self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup)
170+
self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None), sub, sup)
171171
}
172172

173173
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) {

compiler/rustc_infer/src/infer/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ pub enum SubregionOrigin<'tcx> {
390390

391391
/// The given region parameter was instantiated with a region
392392
/// that must outlive some other region.
393-
RelateRegionParamBound(Span),
393+
RelateRegionParamBound(Span, Option<Ty<'tcx>>),
394394

395395
/// Creating a pointer `b` to contents of another reference.
396396
Reborrow(Span),
@@ -859,7 +859,7 @@ impl<'tcx> InferCtxt<'tcx> {
859859
) {
860860
self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
861861
let origin = SubregionOrigin::from_obligation_cause(cause, || {
862-
RelateRegionParamBound(cause.span)
862+
RelateRegionParamBound(cause.span, None)
863863
});
864864
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
865865
})
@@ -1685,7 +1685,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
16851685
Subtype(ref a) => a.span(),
16861686
RelateObjectBound(a) => a,
16871687
RelateParamBound(a, ..) => a,
1688-
RelateRegionParamBound(a) => a,
1688+
RelateRegionParamBound(a, _) => a,
16891689
Reborrow(a) => a,
16901690
ReferenceOutlivesReferent(_, a) => a,
16911691
CompareImplItemObligation { span, .. } => span,
@@ -1726,6 +1726,10 @@ impl<'tcx> SubregionOrigin<'tcx> {
17261726
SubregionOrigin::AscribeUserTypeProvePredicate(span)
17271727
}
17281728

1729+
traits::ObligationCauseCode::ObjectTypeBound(ty, _reg) => {
1730+
SubregionOrigin::RelateRegionParamBound(cause.span, Some(ty))
1731+
}
1732+
17291733
_ => default(),
17301734
}
17311735
}

compiler/rustc_lint/src/internal.rs

+84-68
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir::{
88
BinOp, BinOpKind, Expr, ExprKind, GenericArg, HirId, Impl, Item, ItemKind, Node, Pat, PatKind,
99
Path, PathSegment, QPath, Ty, TyKind,
1010
};
11-
use rustc_middle::ty::{self, Ty as MiddleTy};
11+
use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy};
1212
use rustc_session::{declare_lint_pass, declare_tool_lint};
1313
use rustc_span::hygiene::{ExpnKind, MacroKind};
1414
use rustc_span::symbol::{kw, sym, Symbol};
@@ -415,14 +415,17 @@ declare_lint_pass!(Diagnostics => [UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE
415415

416416
impl LateLintPass<'_> for Diagnostics {
417417
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
418+
let collect_args_tys_and_spans = |args: &[Expr<'_>], reserve_one_extra: bool| {
419+
let mut result = Vec::with_capacity(args.len() + usize::from(reserve_one_extra));
420+
result.extend(args.iter().map(|arg| (cx.typeck_results().expr_ty(arg), arg.span)));
421+
result
422+
};
418423
// Only check function calls and method calls.
419-
let (span, def_id, fn_gen_args, call_tys) = match expr.kind {
424+
let (span, def_id, fn_gen_args, arg_tys_and_spans) = match expr.kind {
420425
ExprKind::Call(callee, args) => {
421426
match cx.typeck_results().node_type(callee.hir_id).kind() {
422427
&ty::FnDef(def_id, fn_gen_args) => {
423-
let call_tys: Vec<_> =
424-
args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect();
425-
(callee.span, def_id, fn_gen_args, call_tys)
428+
(callee.span, def_id, fn_gen_args, collect_args_tys_and_spans(args, false))
426429
}
427430
_ => return, // occurs for fns passed as args
428431
}
@@ -432,66 +435,94 @@ impl LateLintPass<'_> for Diagnostics {
432435
else {
433436
return;
434437
};
435-
let mut call_tys: Vec<_> =
436-
args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect();
437-
call_tys.insert(0, cx.tcx.types.self_param); // dummy inserted for `self`
438-
(span, def_id, fn_gen_args, call_tys)
438+
let mut args = collect_args_tys_and_spans(args, true);
439+
args.insert(0, (cx.tcx.types.self_param, _recv.span)); // dummy inserted for `self`
440+
(span, def_id, fn_gen_args, args)
439441
}
440442
_ => return,
441443
};
442444

443-
// Is the callee marked with `#[rustc_lint_diagnostics]`?
444-
let has_attr = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args)
445-
.ok()
446-
.flatten()
447-
.is_some_and(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics));
448-
449-
// Closure: is the type `{D,Subd}iagMessage`?
450-
let is_diag_message = |ty: MiddleTy<'_>| {
451-
if let Some(adt_def) = ty.ty_adt_def()
452-
&& let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did())
453-
&& matches!(name, sym::DiagMessage | sym::SubdiagMessage)
454-
{
455-
true
456-
} else {
457-
false
458-
}
459-
};
445+
Self::diagnostic_outside_of_impl(cx, span, expr.hir_id, def_id, fn_gen_args);
446+
Self::untranslatable_diagnostic(cx, def_id, &arg_tys_and_spans);
447+
}
448+
}
460449

461-
// Does the callee have one or more `impl Into<{D,Subd}iagMessage>` parameters?
462-
let mut impl_into_diagnostic_message_params = vec![];
450+
impl Diagnostics {
451+
// Is the type `{D,Subd}iagMessage`?
452+
fn is_diag_message<'cx>(cx: &LateContext<'cx>, ty: MiddleTy<'cx>) -> bool {
453+
if let Some(adt_def) = ty.ty_adt_def()
454+
&& let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did())
455+
&& matches!(name, sym::DiagMessage | sym::SubdiagMessage)
456+
{
457+
true
458+
} else {
459+
false
460+
}
461+
}
462+
463+
fn untranslatable_diagnostic<'cx>(
464+
cx: &LateContext<'cx>,
465+
def_id: DefId,
466+
arg_tys_and_spans: &[(MiddleTy<'cx>, Span)],
467+
) {
463468
let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
464469
let predicates = cx.tcx.predicates_of(def_id).instantiate_identity(cx.tcx).predicates;
465470
for (i, &param_ty) in fn_sig.inputs().iter().enumerate() {
466-
if let ty::Param(p) = param_ty.kind() {
471+
if let ty::Param(sig_param) = param_ty.kind() {
467472
// It is a type parameter. Check if it is `impl Into<{D,Subd}iagMessage>`.
468473
for pred in predicates.iter() {
469474
if let Some(trait_pred) = pred.as_trait_clause()
470475
&& let trait_ref = trait_pred.skip_binder().trait_ref
471476
&& trait_ref.self_ty() == param_ty // correct predicate for the param?
472477
&& cx.tcx.is_diagnostic_item(sym::Into, trait_ref.def_id)
473478
&& let ty1 = trait_ref.args.type_at(1)
474-
&& is_diag_message(ty1)
479+
&& Self::is_diag_message(cx, ty1)
475480
{
476-
impl_into_diagnostic_message_params.push((i, p.name));
481+
// Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
482+
// with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
483+
// `UNTRANSLATABLE_DIAGNOSTIC` lint.
484+
let (arg_ty, arg_span) = arg_tys_and_spans[i];
485+
486+
// Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
487+
let is_translatable = Self::is_diag_message(cx, arg_ty)
488+
|| matches!(arg_ty.kind(), ty::Param(arg_param) if arg_param.name == sig_param.name);
489+
if !is_translatable {
490+
cx.emit_span_lint(
491+
UNTRANSLATABLE_DIAGNOSTIC,
492+
arg_span,
493+
UntranslatableDiag,
494+
);
495+
}
477496
}
478497
}
479498
}
480499
}
500+
}
481501

482-
// Is the callee interesting?
483-
if !has_attr && impl_into_diagnostic_message_params.is_empty() {
502+
fn diagnostic_outside_of_impl<'cx>(
503+
cx: &LateContext<'cx>,
504+
span: Span,
505+
current_id: HirId,
506+
def_id: DefId,
507+
fn_gen_args: GenericArgsRef<'cx>,
508+
) {
509+
// Is the callee marked with `#[rustc_lint_diagnostics]`?
510+
let Some(inst) =
511+
ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args).ok().flatten()
512+
else {
484513
return;
485-
}
514+
};
515+
let has_attr = cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics);
516+
if !has_attr {
517+
return;
518+
};
486519

487-
// Is the parent method marked with `#[rustc_lint_diagnostics]`?
488-
let mut parent_has_attr = false;
489-
for (hir_id, _parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
520+
for (hir_id, _parent) in cx.tcx.hir().parent_iter(current_id) {
490521
if let Some(owner_did) = hir_id.as_owner()
491522
&& cx.tcx.has_attr(owner_did, sym::rustc_lint_diagnostics)
492523
{
493-
parent_has_attr = true;
494-
break;
524+
// The parent method is marked with `#[rustc_lint_diagnostics]`
525+
return;
495526
}
496527
}
497528

@@ -500,37 +531,22 @@ impl LateLintPass<'_> for Diagnostics {
500531
// - inside a parent function that is itself marked with `#[rustc_lint_diagnostics]`.
501532
//
502533
// Otherwise, emit a `DIAGNOSTIC_OUTSIDE_OF_IMPL` lint.
503-
if has_attr && !parent_has_attr {
504-
let mut is_inside_appropriate_impl = false;
505-
for (_hir_id, parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
506-
debug!(?parent);
507-
if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent
508-
&& let Impl { of_trait: Some(of_trait), .. } = impl_
509-
&& let Some(def_id) = of_trait.trait_def_id()
510-
&& let Some(name) = cx.tcx.get_diagnostic_name(def_id)
511-
&& matches!(name, sym::Diagnostic | sym::Subdiagnostic | sym::LintDiagnostic)
512-
{
513-
is_inside_appropriate_impl = true;
514-
break;
515-
}
516-
}
517-
debug!(?is_inside_appropriate_impl);
518-
if !is_inside_appropriate_impl {
519-
cx.emit_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl);
534+
let mut is_inside_appropriate_impl = false;
535+
for (_hir_id, parent) in cx.tcx.hir().parent_iter(current_id) {
536+
debug!(?parent);
537+
if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent
538+
&& let Impl { of_trait: Some(of_trait), .. } = impl_
539+
&& let Some(def_id) = of_trait.trait_def_id()
540+
&& let Some(name) = cx.tcx.get_diagnostic_name(def_id)
541+
&& matches!(name, sym::Diagnostic | sym::Subdiagnostic | sym::LintDiagnostic)
542+
{
543+
is_inside_appropriate_impl = true;
544+
break;
520545
}
521546
}
522-
523-
// Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
524-
// with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
525-
// `UNTRANSLATABLE_DIAGNOSTIC` lint.
526-
for (param_i, param_i_p_name) in impl_into_diagnostic_message_params {
527-
// Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
528-
let arg_ty = call_tys[param_i];
529-
let is_translatable = is_diag_message(arg_ty)
530-
|| matches!(arg_ty.kind(), ty::Param(p) if p.name == param_i_p_name);
531-
if !is_translatable {
532-
cx.emit_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, UntranslatableDiag);
533-
}
547+
debug!(?is_inside_appropriate_impl);
548+
if !is_inside_appropriate_impl {
549+
cx.emit_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl);
534550
}
535551
}
536552
}

compiler/rustc_span/src/hygiene.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,14 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
14151415

14161416
// Overwrite the dummy data with our decoded SyntaxContextData
14171417
HygieneData::with(|hygiene_data| {
1418+
if let Some(old) = hygiene_data.syntax_context_data.get(raw_id as usize)
1419+
&& old.outer_expn == ctxt_data.outer_expn
1420+
&& old.outer_transparency == ctxt_data.outer_transparency
1421+
&& old.parent == ctxt_data.parent
1422+
{
1423+
ctxt_data = old.clone();
1424+
}
1425+
14181426
let dummy = std::mem::replace(
14191427
&mut hygiene_data.syntax_context_data[ctxt.as_u32() as usize],
14201428
ctxt_data,

compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
1111
pub(super) fn try_report_placeholder_relation(&self) -> Option<Diag<'tcx>> {
1212
match &self.error {
1313
Some(RegionResolutionError::ConcreteFailure(
14-
SubregionOrigin::RelateRegionParamBound(span),
14+
SubregionOrigin::RelateRegionParamBound(span, _),
1515
Region(Interned(
1616
RePlaceholder(ty::Placeholder {
1717
bound: ty::BoundRegion { kind: sub_name, .. },

compiler/rustc_trait_selection/src/error_reporting/infer/note.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
5252
.add_to_diag(err);
5353
}
5454
}
55-
infer::RelateRegionParamBound(span) => {
55+
infer::RelateRegionParamBound(span, _) => {
5656
RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
5757
.add_to_diag(err);
5858
}
@@ -199,7 +199,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
199199
note,
200200
})
201201
}
202-
infer::RelateRegionParamBound(span) => {
202+
infer::RelateRegionParamBound(span, _) => {
203203
let param_instantiated = note_and_explain::RegionExplanation::new(
204204
self.tcx,
205205
generic_param_scope,

compiler/rustc_trait_selection/src/error_reporting/infer/region.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
257257
.add_to_diag(err);
258258
}
259259
}
260-
infer::RelateRegionParamBound(span) => {
260+
infer::RelateRegionParamBound(span, _) => {
261261
RegionOriginNote::Plain {
262262
span,
263263
msg: fluent::trait_selection_relate_region_param_bound,
@@ -410,7 +410,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
410410
note,
411411
})
412412
}
413-
infer::RelateRegionParamBound(span) => {
413+
infer::RelateRegionParamBound(span, ty) => {
414414
let param_instantiated = note_and_explain::RegionExplanation::new(
415415
self.tcx,
416416
generic_param_scope,
@@ -419,11 +419,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
419419
note_and_explain::PrefixKind::LfParamInstantiatedWith,
420420
note_and_explain::SuffixKind::Empty,
421421
);
422+
let mut alt_span = None;
423+
if let Some(ty) = ty
424+
&& sub.is_static()
425+
&& let ty::Dynamic(preds, _, ty::DynKind::Dyn) = ty.kind()
426+
&& let Some(def_id) = preds.principal_def_id()
427+
{
428+
for (clause, span) in
429+
self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
430+
{
431+
if let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) =
432+
clause.kind().skip_binder()
433+
&& let ty::Param(param) = a.kind()
434+
&& param.name == kw::SelfUpper
435+
&& b.is_static()
436+
{
437+
// Point at explicit `'static` bound on the trait (`trait T: 'static`).
438+
alt_span = Some(span);
439+
}
440+
}
441+
}
422442
let param_must_outlive = note_and_explain::RegionExplanation::new(
423443
self.tcx,
424444
generic_param_scope,
425445
sub,
426-
None,
446+
alt_span,
427447
note_and_explain::PrefixKind::LfParamMustOutlive,
428448
note_and_explain::SuffixKind::Empty,
429449
);

0 commit comments

Comments
 (0)