Skip to content

Commit

Permalink
Unrolled build for rust-lang#134858
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#134858 - estebank:issue-81370, r=Noratrieb

Provide structured suggestion for `#![feature(..)]` in more cases

Fix rust-lang#81370.
  • Loading branch information
rust-timer authored Jan 19, 2025
2 parents 678e669 + e68a8ce commit ab6feeb
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 20 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ const_eval_unstable_in_stable_exposed =
.bypass_sugg = otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
const_eval_unstable_intrinsic = `{$name}` is not yet stable as a const intrinsic
.help = add `#![feature({$feature})]` to the crate attributes to enable
const_eval_unstable_intrinsic_suggestion = add `#![feature({$feature})]` to the crate attributes to enable
const_eval_unterminated_c_string =
reading a null-terminated string starting at {$pointer} with no null found before end of allocation
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,12 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
err_span,
);
}

fn crate_inject_span(&self) -> Option<Span> {
self.tcx.hir_crate_items(()).definitions().next().and_then(|id| {
self.tcx.crate_level_attribute_injection_span(self.tcx.local_def_id_to_hir_id(id))
})
}
}

impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Expand Down Expand Up @@ -809,6 +815,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
name: intrinsic.name,
feature,
const_stable_indirect: is_const_stable,
suggestion: self.crate_inject_span(),
});
}
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
Expand Down Expand Up @@ -897,7 +904,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// regular stability.
feature == sym::rustc_private
&& issue == NonZero::new(27812)
&& self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
&& tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
};
// Even if the feature is enabled, we still need check_op to double-check
// this if the callee is not safe to expose on stable.
Expand All @@ -907,6 +914,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
feature,
feature_enabled,
safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
suggestion_span: self.crate_inject_span(),
});
}
}
Expand Down
18 changes: 16 additions & 2 deletions compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Concrete error types for all operations which may be invalid in a certain const context.
use hir::{ConstContext, LangItem};
use rustc_errors::Diag;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
Expand Down Expand Up @@ -388,6 +388,7 @@ pub(crate) struct FnCallUnstable {
/// expose on stable.
pub feature_enabled: bool,
pub safe_to_expose_on_stable: bool,
pub suggestion_span: Option<Span>,
}

impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
Expand All @@ -407,8 +408,18 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
def_path: ccx.tcx.def_path_str(self.def_id),
});
// FIXME: make this translatable
let msg = format!("add `#![feature({})]` to the crate attributes to enable", self.feature);
#[allow(rustc::untranslatable_diagnostic)]
err.help(format!("add `#![feature({})]` to the crate attributes to enable", self.feature));
if let Some(span) = self.suggestion_span {
err.span_suggestion_verbose(
span,
msg,
format!("#![feature({})]\n", self.feature),
Applicability::MachineApplicable,
);
} else {
err.help(msg);
}

err
}
Expand Down Expand Up @@ -436,6 +447,7 @@ pub(crate) struct IntrinsicUnstable {
pub name: Symbol,
pub feature: Symbol,
pub const_stable_indirect: bool,
pub suggestion: Option<Span>,
}

impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
Expand All @@ -455,6 +467,8 @@ impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
span,
name: self.name,
feature: self.feature,
suggestion: self.suggestion,
help: self.suggestion.is_none(),
})
}
}
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,19 @@ pub(crate) struct UnstableConstFn {

#[derive(Diagnostic)]
#[diag(const_eval_unstable_intrinsic)]
#[help]
pub(crate) struct UnstableIntrinsic {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub feature: Symbol,
#[suggestion(
const_eval_unstable_intrinsic_suggestion,
code = "#![feature({feature})]\n",
applicability = "machine-applicable"
)]
pub suggestion: Option<Span>,
#[help(const_eval_unstable_intrinsic_suggestion)]
pub help: bool,
}

#[derive(Diagnostic)]
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@ use crate::fluent_generated as fluent;
pub(crate) struct BaseExpressionDoubleDot {
#[primary_span]
pub span: Span,
#[suggestion(
hir_typeck_base_expression_double_dot_enable_default_field_values,
code = "#![feature(default_field_values)]\n",
applicability = "machine-applicable",
style = "verbose"
)]
pub default_field_values_suggestion: Option<Span>,
#[subdiagnostic]
pub default_field_values: Option<BaseExpressionDoubleDotEnableDefaultFieldValues>,
pub default_field_values_help: Option<BaseExpressionDoubleDotEnableDefaultFieldValues>,
#[subdiagnostic]
pub add_expr: Option<BaseExpressionDoubleDotAddExpr>,
#[subdiagnostic]
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2138,13 +2138,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
if !self.tcx.features().default_field_values() {
let sugg = self.tcx.crate_level_attribute_injection_span(expr.hir_id);
self.dcx().emit_err(BaseExpressionDoubleDot {
span: span.shrink_to_hi(),
// We only mention enabling the feature if this is a nightly rustc *and* the
// expression would make sense with the feature enabled.
default_field_values: if self.tcx.sess.is_nightly_build()
default_field_values_suggestion: if self.tcx.sess.is_nightly_build()
&& missing_mandatory_fields.is_empty()
&& !missing_optional_fields.is_empty()
&& sugg.is_some()
{
sugg
} else {
None
},
default_field_values_help: if self.tcx.sess.is_nightly_build()
&& missing_mandatory_fields.is_empty()
&& !missing_optional_fields.is_empty()
&& sugg.is_none()
{
Some(BaseExpressionDoubleDotEnableDefaultFieldValues)
} else {
Expand Down
10 changes: 8 additions & 2 deletions tests/ui/consts/const-unstable-intrinsic.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,21 @@ error: `size_of_val` is not yet stable as a const intrinsic
LL | unstable_intrinsic::size_of_val(&x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(unstable)]` to the crate attributes to enable
help: add `#![feature(unstable)]` to the crate attributes to enable
|
LL + #![feature(unstable)]
|

error: `min_align_of_val` is not yet stable as a const intrinsic
--> $DIR/const-unstable-intrinsic.rs:20:9
|
LL | unstable_intrinsic::min_align_of_val(&x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(unstable)]` to the crate attributes to enable
help: add `#![feature(unstable)]` to the crate attributes to enable
|
LL + #![feature(unstable)]
|

error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local)]`
--> $DIR/const-unstable-intrinsic.rs:24:9
Expand Down
50 changes: 40 additions & 10 deletions tests/ui/feature-gates/feature-gate-default-field-values.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ error[E0797]: base expression required after `..`
LL | let x = Foo { .. };
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | let x = Foo { ../* expr */ };
Expand All @@ -142,7 +145,10 @@ error[E0797]: base expression required after `..`
LL | let z = Foo { baz: 1, .. };
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | let z = Foo { baz: 1, ../* expr */ };
Expand All @@ -154,7 +160,10 @@ error[E0797]: base expression required after `..`
LL | let x = Bar::Foo { .. };
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | let x = Bar::Foo { ../* expr */ };
Expand All @@ -166,7 +175,10 @@ error[E0797]: base expression required after `..`
LL | let z = Bar::Foo { baz: 1, .. };
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | let z = Bar::Foo { baz: 1, ../* expr */ };
Expand All @@ -178,7 +190,10 @@ error[E0797]: base expression required after `..`
LL | let x = Qux::<i32, 4> { .. };
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | let x = Qux::<i32, 4> { ../* expr */ };
Expand All @@ -190,7 +205,10 @@ error[E0797]: base expression required after `..`
LL | assert!(matches!(Qux::<i32, 4> { bar: S, baz: 42, bat: 2, bay: 4, .. }, x));
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | assert!(matches!(Qux::<i32, 4> { bar: S, baz: 42, bat: 2, bay: 4, ../* expr */ }, x));
Expand All @@ -202,7 +220,10 @@ error[E0797]: base expression required after `..`
LL | let y = Opt { mandatory: None, .. };
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | let y = Opt { mandatory: None, ../* expr */ };
Expand All @@ -214,7 +235,10 @@ error[E0797]: base expression required after `..`
LL | assert!(matches!(Opt { mandatory: None, .. }, z));
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | assert!(matches!(Opt { mandatory: None, ../* expr */ }, z));
Expand Down Expand Up @@ -260,7 +284,10 @@ error[E0797]: base expression required after `..`
LL | let y = OptEnum::Variant { mandatory: None, .. };
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | let y = OptEnum::Variant { mandatory: None, ../* expr */ };
Expand All @@ -272,7 +299,10 @@ error[E0797]: base expression required after `..`
LL | assert!(matches!(OptEnum::Variant { mandatory: None, .. }, z));
| ^
|
= help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
help: add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
|
LL + #![feature(default_field_values)]
|
help: add a base expression here
|
LL | assert!(matches!(OptEnum::Variant { mandatory: None, ../* expr */ }, z));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ error: `foobar` is not yet stable as a const fn
LL | foobar();
| ^^^^^^^^
|
= help: add `#![feature(const_foobar)]` to the crate attributes to enable
help: add `#![feature(const_foobar)]` to the crate attributes to enable
|
LL + #![feature(const_foobar)]
|

error: aborting due to 1 previous error

0 comments on commit ab6feeb

Please sign in to comment.