Skip to content

Commit f97cbaf

Browse files
committed
Auto merge of #122712 - matthiaskrgr:rollup-xup9a3i, r=matthiaskrgr
Rollup of 12 pull requests Successful merges: - #121258 (Reject overly generic assoc const binding types) - #121823 (never patterns: suggest `!` patterns on non-exhaustive matches) - #122060 (Stabilize `imported_main`) - #122158 (Provide structured suggestion for `#![feature(foo)]`) - #122642 (Improve wording of `Vec::swap_remove`) - #122675 (core: document default attribute stabilization) - #122687 (`NormalizesTo`: return nested goals to caller) - #122691 (Fix ICE: `global_asm!()` Don't Panic When Unable to Evaluate Constant) - #122693 (Fix heading anchors in doc pages.) - #122699 (Fix a typo in the 1.77.0 relnotes) - #122700 (Remove redundant files, rename base riscv32 file) - #122701 (Detect allocator for box in `must_not_suspend` lint) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d31b6fb + 010dc4a commit f97cbaf

File tree

182 files changed

+2622
-788
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+2622
-788
lines changed

‎RELEASES.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ Cargo
8282

8383
- [Extend the build directive syntax with `cargo::`.](https://github.com/rust-lang/cargo/pull/12201/)
8484
- [Stabilize metadata `id` format as `PackageIDSpec`.](https://github.com/rust-lang/cargo/pull/12914/)
85-
- [Pull out as `cargo-util-schemas` as a crate.](https://github.com/rust-lang/cargo/pull/13178/)
85+
- [Pull out `cargo-util-schemas` as a crate.](https://github.com/rust-lang/cargo/pull/13178/)
8686
- [Strip all debuginfo when debuginfo is not requested.](https://github.com/rust-lang/cargo/pull/13257/)
8787
- [Inherit jobserver from env for all kinds of runners.](https://github.com/rust-lang/cargo/pull/12776/)
8888
- [Deprecate rustc plugin support in cargo.](https://github.com/rust-lang/cargo/pull/13248/)

‎compiler/rustc_codegen_ssa/src/mono_item.rs‎

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::base;
22
use crate::common;
33
use crate::traits::*;
44
use rustc_hir as hir;
5+
use rustc_middle::mir::interpret::ErrorHandled;
56
use rustc_middle::mir::mono::MonoItem;
67
use rustc_middle::mir::mono::{Linkage, Visibility};
78
use rustc_middle::ty;
@@ -40,23 +41,34 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
4041
.iter()
4142
.map(|(op, op_sp)| match *op {
4243
hir::InlineAsmOperand::Const { ref anon_const } => {
43-
let const_value = cx
44-
.tcx()
45-
.const_eval_poly(anon_const.def_id.to_def_id())
46-
.unwrap_or_else(|_| {
47-
span_bug!(*op_sp, "asm const cannot be resolved")
48-
});
49-
let ty = cx
50-
.tcx()
51-
.typeck_body(anon_const.body)
52-
.node_type(anon_const.hir_id);
53-
let string = common::asm_const_to_str(
54-
cx.tcx(),
55-
*op_sp,
56-
const_value,
57-
cx.layout_of(ty),
58-
);
59-
GlobalAsmOperandRef::Const { string }
44+
match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) {
45+
Ok(const_value) => {
46+
let ty = cx
47+
.tcx()
48+
.typeck_body(anon_const.body)
49+
.node_type(anon_const.hir_id);
50+
let string = common::asm_const_to_str(
51+
cx.tcx(),
52+
*op_sp,
53+
const_value,
54+
cx.layout_of(ty),
55+
);
56+
GlobalAsmOperandRef::Const { string }
57+
}
58+
Err(ErrorHandled::Reported { .. }) => {
59+
// An error has already been reported and
60+
// compilation is guaranteed to fail if execution
61+
// hits this path. So an empty string instead of
62+
// a stringified constant value will suffice.
63+
GlobalAsmOperandRef::Const { string: String::new() }
64+
}
65+
Err(ErrorHandled::TooGeneric(_)) => {
66+
span_bug!(
67+
*op_sp,
68+
"asm const cannot be resolved; too generic"
69+
)
70+
}
71+
}
6072
}
6173
hir::InlineAsmOperand::SymFn { ref anon_const } => {
6274
let ty = cx

‎compiler/rustc_const_eval/src/transform/check_consts/ops.rs‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
9999
#[allow(rustc::untranslatable_diagnostic)]
100100
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
101101
let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
102-
let ConstCx { tcx, param_env, .. } = *ccx;
102+
let ConstCx { tcx, param_env, body, .. } = *ccx;
103103

104104
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
105105
let trait_ref = TraitRef::from_method(tcx, trait_id, args);
@@ -297,10 +297,12 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
297297
ccx.const_kind(),
298298
));
299299

300-
if let Some(feature) = feature
301-
&& ccx.tcx.sess.is_nightly_build()
302-
{
303-
err.help(format!("add `#![feature({feature})]` to the crate attributes to enable",));
300+
if let Some(feature) = feature {
301+
ccx.tcx.disabled_nightly_features(
302+
&mut err,
303+
body.source.def_id().as_local().map(|local| ccx.tcx.local_def_id_to_hir_id(local)),
304+
[(String::new(), feature)],
305+
);
304306
}
305307

306308
if let ConstContext::Static(_) = ccx.const_kind() {

‎compiler/rustc_feature/src/accepted.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ declare_features! (
203203
(accepted, impl_header_lifetime_elision, "1.31.0", Some(15872)),
204204
/// Allows referencing `Self` and projections in impl-trait.
205205
(accepted, impl_trait_projections, "1.74.0", Some(103532)),
206+
/// Allows using imported `main` function
207+
(accepted, imported_main, "CURRENT_RUSTC_VERSION", Some(28937)),
206208
/// Allows using `a..=b` and `..=b` as inclusive range syntaxes.
207209
(accepted, inclusive_range_syntax, "1.26.0", Some(28237)),
208210
/// Allows inferring outlives requirements (RFC 2093).

‎compiler/rustc_feature/src/unstable.rs‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,6 @@ declare_features! (
495495
(unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)),
496496
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
497497
(unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
498-
/// Allows using imported `main` function
499-
(unstable, imported_main, "1.53.0", Some(28937)),
500498
/// Allows associated types in inherent impls.
501499
(incomplete, inherent_associated_types, "1.52.0", Some(8995)),
502500
/// Allow anonymous constants from an inline `const` block

‎compiler/rustc_hir_analysis/messages.ftl‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ hir_analysis_enum_discriminant_overflowed = enum discriminant overflowed
118118
.label = overflowed on value after {$discr}
119119
.note = explicitly set `{$item_name} = {$wrapped_discr}` if that is desired outcome
120120
121+
hir_analysis_escaping_bound_var_in_ty_of_assoc_const_binding =
122+
the type of the associated constant `{$assoc_const}` cannot capture late-bound generic parameters
123+
.label = its type cannot capture the late-bound {$var_def_kind} `{$var_name}`
124+
.var_defined_here_label = the late-bound {$var_def_kind} `{$var_name}` is defined here
125+
121126
hir_analysis_field_already_declared =
122127
field `{$field_name}` is already declared
123128
.label = field already declared
@@ -316,6 +321,22 @@ hir_analysis_opaque_captures_higher_ranked_lifetime = `impl Trait` cannot captur
316321
.label = `impl Trait` implicitly captures all lifetimes in scope
317322
.note = lifetime declared here
318323
324+
hir_analysis_param_in_ty_of_assoc_const_binding =
325+
the type of the associated constant `{$assoc_const}` must not depend on {$param_category ->
326+
[self] `Self`
327+
[synthetic] `impl Trait`
328+
*[normal] generic parameters
329+
}
330+
.label = its type must not depend on {$param_category ->
331+
[self] `Self`
332+
[synthetic] `impl Trait`
333+
*[normal] the {$param_def_kind} `{$param_name}`
334+
}
335+
.param_defined_here_label = {$param_category ->
336+
[synthetic] the `impl Trait` is specified here
337+
*[normal] the {$param_def_kind} `{$param_name}` is defined here
338+
}
339+
319340
hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation
320341
.help = add `#![feature(unboxed_closures)]` to the crate attributes to use it
321342
@@ -432,6 +453,8 @@ hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$de
432453
.label = needs at most one field with non-trivial size or alignment, but has {$field_count}
433454
.labels = this field has non-zero size or requires alignment
434455
456+
hir_analysis_ty_of_assoc_const_binding_note = `{$assoc_const}` has type `{$ty}`
457+
435458
hir_analysis_ty_param_first_local = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`)
436459
.label = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`)
437460
.note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type

‎compiler/rustc_hir_analysis/src/astconv/bounds.rs‎

Lines changed: 172 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
use rustc_data_structures::fx::FxIndexMap;
1+
use std::ops::ControlFlow;
2+
3+
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
24
use rustc_errors::{codes::*, struct_span_code_err};
35
use rustc_hir as hir;
46
use rustc_hir::def::{DefKind, Res};
57
use rustc_hir::def_id::{DefId, LocalDefId};
6-
use rustc_middle::ty::{self as ty, Ty};
8+
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
79
use rustc_span::symbol::Ident;
8-
use rustc_span::{ErrorGuaranteed, Span};
10+
use rustc_span::{ErrorGuaranteed, Span, Symbol};
911
use rustc_trait_selection::traits;
12+
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
1013
use smallvec::SmallVec;
1114

1215
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
@@ -433,14 +436,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
433436
binding.kind
434437
{
435438
let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args));
436-
// Since the arguments passed to the alias type above may contain early-bound
437-
// generic parameters, the instantiated type may contain some as well.
438-
// Therefore wrap it in `EarlyBinder`.
439-
// FIXME(fmease): Reject escaping late-bound vars.
440-
tcx.feed_anon_const_type(
441-
anon_const.def_id,
442-
ty::EarlyBinder::bind(ty.skip_binder()),
443-
);
439+
let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, binding.hir_id);
440+
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
444441
}
445442

446443
alias_ty
@@ -530,3 +527,167 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
530527
Ok(())
531528
}
532529
}
530+
531+
/// Detect and reject early-bound & escaping late-bound generic params in the type of assoc const bindings.
532+
///
533+
/// FIXME(const_generics): This is a temporary and semi-artifical restriction until the
534+
/// arrival of *generic const generics*[^1].
535+
///
536+
/// It might actually be possible that we can already support early-bound generic params
537+
/// in such types if we just lifted some more checks in other places, too, for example
538+
/// inside [`ty::Const::from_anon_const`]. However, even if that were the case, we should
539+
/// probably gate this behind another feature flag.
540+
///
541+
/// [^1]: <https://github.com/rust-lang/project-const-generics/issues/28>.
542+
fn check_assoc_const_binding_type<'tcx>(
543+
tcx: TyCtxt<'tcx>,
544+
assoc_const: Ident,
545+
ty: ty::Binder<'tcx, Ty<'tcx>>,
546+
hir_id: hir::HirId,
547+
) -> Ty<'tcx> {
548+
// We can't perform the checks for early-bound params during name resolution unlike E0770
549+
// because this information depends on *type* resolution.
550+
// We can't perform these checks in `resolve_bound_vars` either for the same reason.
551+
// Consider the trait ref `for<'a> Trait<'a, C = { &0 }>`. We need to know the fully
552+
// resolved type of `Trait::C` in order to know if it references `'a` or not.
553+
554+
let ty = ty.skip_binder();
555+
if !ty.has_param() && !ty.has_escaping_bound_vars() {
556+
return ty;
557+
}
558+
559+
let mut collector = GenericParamAndBoundVarCollector {
560+
tcx,
561+
params: Default::default(),
562+
vars: Default::default(),
563+
depth: ty::INNERMOST,
564+
};
565+
let mut guar = ty.visit_with(&mut collector).break_value();
566+
567+
let ty_note = ty
568+
.make_suggestable(tcx, false)
569+
.map(|ty| crate::errors::TyOfAssocConstBindingNote { assoc_const, ty });
570+
571+
let enclosing_item_owner_id = tcx
572+
.hir()
573+
.parent_owner_iter(hir_id)
574+
.find_map(|(owner_id, parent)| parent.generics().map(|_| owner_id))
575+
.unwrap();
576+
let generics = tcx.generics_of(enclosing_item_owner_id);
577+
for index in collector.params {
578+
let param = generics.param_at(index as _, tcx);
579+
let is_self_param = param.name == rustc_span::symbol::kw::SelfUpper;
580+
guar.get_or_insert(tcx.dcx().emit_err(crate::errors::ParamInTyOfAssocConstBinding {
581+
span: assoc_const.span,
582+
assoc_const,
583+
param_name: param.name,
584+
param_def_kind: tcx.def_descr(param.def_id),
585+
param_category: if is_self_param {
586+
"self"
587+
} else if param.kind.is_synthetic() {
588+
"synthetic"
589+
} else {
590+
"normal"
591+
},
592+
param_defined_here_label:
593+
(!is_self_param).then(|| tcx.def_ident_span(param.def_id).unwrap()),
594+
ty_note,
595+
}));
596+
}
597+
for (var_def_id, var_name) in collector.vars {
598+
guar.get_or_insert(tcx.dcx().emit_err(
599+
crate::errors::EscapingBoundVarInTyOfAssocConstBinding {
600+
span: assoc_const.span,
601+
assoc_const,
602+
var_name,
603+
var_def_kind: tcx.def_descr(var_def_id),
604+
var_defined_here_label: tcx.def_ident_span(var_def_id).unwrap(),
605+
ty_note,
606+
},
607+
));
608+
}
609+
610+
let guar = guar.unwrap_or_else(|| bug!("failed to find gen params or bound vars in ty"));
611+
Ty::new_error(tcx, guar)
612+
}
613+
614+
struct GenericParamAndBoundVarCollector<'tcx> {
615+
tcx: TyCtxt<'tcx>,
616+
params: FxIndexSet<u32>,
617+
vars: FxIndexSet<(DefId, Symbol)>,
618+
depth: ty::DebruijnIndex,
619+
}
620+
621+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'tcx> {
622+
type Result = ControlFlow<ErrorGuaranteed>;
623+
624+
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
625+
&mut self,
626+
binder: &ty::Binder<'tcx, T>,
627+
) -> Self::Result {
628+
self.depth.shift_in(1);
629+
let result = binder.super_visit_with(self);
630+
self.depth.shift_out(1);
631+
result
632+
}
633+
634+
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
635+
match ty.kind() {
636+
ty::Param(param) => {
637+
self.params.insert(param.index);
638+
}
639+
ty::Bound(db, bt) if *db >= self.depth => {
640+
self.vars.insert(match bt.kind {
641+
ty::BoundTyKind::Param(def_id, name) => (def_id, name),
642+
ty::BoundTyKind::Anon => {
643+
let reported = self
644+
.tcx
645+
.dcx()
646+
.delayed_bug(format!("unexpected anon bound ty: {:?}", bt.var));
647+
return ControlFlow::Break(reported);
648+
}
649+
});
650+
}
651+
_ if ty.has_param() || ty.has_bound_vars() => return ty.super_visit_with(self),
652+
_ => {}
653+
}
654+
ControlFlow::Continue(())
655+
}
656+
657+
fn visit_region(&mut self, re: ty::Region<'tcx>) -> Self::Result {
658+
match re.kind() {
659+
ty::ReEarlyParam(param) => {
660+
self.params.insert(param.index);
661+
}
662+
ty::ReBound(db, br) if db >= self.depth => {
663+
self.vars.insert(match br.kind {
664+
ty::BrNamed(def_id, name) => (def_id, name),
665+
ty::BrAnon | ty::BrEnv => {
666+
let guar = self
667+
.tcx
668+
.dcx()
669+
.delayed_bug(format!("unexpected bound region kind: {:?}", br.kind));
670+
return ControlFlow::Break(guar);
671+
}
672+
});
673+
}
674+
_ => {}
675+
}
676+
ControlFlow::Continue(())
677+
}
678+
679+
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
680+
match ct.kind() {
681+
ty::ConstKind::Param(param) => {
682+
self.params.insert(param.index);
683+
}
684+
ty::ConstKind::Bound(db, ty::BoundVar { .. }) if db >= self.depth => {
685+
let guar = self.tcx.dcx().delayed_bug("unexpected escaping late-bound const var");
686+
return ControlFlow::Break(guar);
687+
}
688+
_ if ct.has_param() || ct.has_bound_vars() => return ct.super_visit_with(self),
689+
_ => {}
690+
}
691+
ControlFlow::Continue(())
692+
}
693+
}

‎compiler/rustc_hir_analysis/src/astconv/generics.rs‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_middle::ty::{
1616
self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt,
1717
};
1818
use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
19-
use rustc_span::symbol::kw;
19+
use rustc_span::symbol::{kw, sym};
2020
use smallvec::SmallVec;
2121

2222
/// Report an error that a generic argument did not match the generic parameter that was
@@ -41,9 +41,11 @@ fn generic_arg_mismatch_err(
4141
if let GenericParamDefKind::Const { .. } = param.kind {
4242
if matches!(arg, GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. })) {
4343
err.help("const arguments cannot yet be inferred with `_`");
44-
if sess.is_nightly_build() {
45-
err.help("add `#![feature(generic_arg_infer)]` to the crate attributes to enable");
46-
}
44+
tcx.disabled_nightly_features(
45+
&mut err,
46+
param.def_id.as_local().map(|local| tcx.local_def_id_to_hir_id(local)),
47+
[(String::new(), sym::generic_arg_infer)],
48+
);
4749
}
4850
}
4951

0 commit comments

Comments
 (0)