diff options
| author | bors <bors@rust-lang.org> | 2024-12-03 00:51:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-12-03 00:51:25 +0000 |
| commit | 41cbe3e4d1ef8de310fbbd77043082960def9446 (patch) | |
| tree | c44e61acec0543e267febfc795db865490b9d241 /compiler | |
| parent | 42b4b9c669ba8ddbf4291211711a79d66e933f41 (diff) | |
| parent | 73f225acf6823ae8487478b3654f1db5236bff83 (diff) | |
| download | rust-41cbe3e4d1ef8de310fbbd77043082960def9446.tar.gz rust-41cbe3e4d1ef8de310fbbd77043082960def9446.zip | |
Auto merge of #133770 - GuillaumeGomez:rollup-l62iyyx, r=GuillaumeGomez
Rollup of 10 pull requests
Successful merges:
- #131713 (Stabilize `const_maybe_uninit_write`)
- #133535 (show forbidden_lint_groups in future-compat reports)
- #133610 (Move `Const::{from_anon_const,try_from_lit}` to hir_ty_lowering)
- #133701 (Use c"lit" for CStrings without unwrap)
- #133704 (fix ICE when promoted has layout size overflow)
- #133705 (add "profiler" and "optimized-compiler-builtins" option coverage for ci-rustc)
- #133710 (Reducing `target_feature` check-cfg merge conflicts)
- #133732 (Fix `-Zdump-mir-dataflow`)
- #133746 (Change `AttrArgs::Eq` to a struct variant)
- #133763 (Fix `f16::midpoint` const feature gate)
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
29 files changed, 263 insertions, 248 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 14205f66491..ed2a3a507c8 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1731,12 +1731,12 @@ pub enum AttrArgs { /// Delimited arguments: `#[attr()/[]/{}]`. Delimited(DelimArgs), /// Arguments of a key-value attribute: `#[attr = "value"]`. - Eq( + Eq { /// Span of the `=` token. - Span, - /// The "value". - AttrArgsEq, - ), + eq_span: Span, + + value: AttrArgsEq, + }, } // The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro @@ -1748,15 +1748,39 @@ pub enum AttrArgsEq { Hir(MetaItemLit), } +impl AttrArgsEq { + pub fn span(&self) -> Span { + match self { + AttrArgsEq::Ast(p) => p.span, + AttrArgsEq::Hir(lit) => lit.span, + } + } + + pub fn unwrap_ast(&self) -> &Expr { + match self { + AttrArgsEq::Ast(p) => p, + AttrArgsEq::Hir(lit) => { + unreachable!("in literal form when getting inner tokens: {lit:?}") + } + } + } + + pub fn unwrap_ast_mut(&mut self) -> &mut P<Expr> { + match self { + AttrArgsEq::Ast(p) => p, + AttrArgsEq::Hir(lit) => { + unreachable!("in literal form when getting inner tokens: {lit:?}") + } + } + } +} + impl AttrArgs { pub fn span(&self) -> Option<Span> { match self { AttrArgs::Empty => None, AttrArgs::Delimited(args) => Some(args.dspan.entire()), - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when getting span: {:?}", lit); - } + AttrArgs::Eq { eq_span, value } => Some(eq_span.to(value.span())), } } @@ -1766,10 +1790,7 @@ impl AttrArgs { match self { AttrArgs::Empty => TokenStream::default(), AttrArgs::Delimited(args) => args.tokens.clone(), - AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr), - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when getting inner tokens: {:?}", lit) - } + AttrArgs::Eq { value, .. } => TokenStream::from_ast(value.unwrap_ast()), } } } @@ -1783,10 +1804,10 @@ where match self { AttrArgs::Empty => {} AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher), - AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => { + AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { unreachable!("hash_stable {:?}", expr); } - AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => { + AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) } => { eq_span.hash_stable(ctx, hasher); lit.hash_stable(ctx, hasher); } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 888b13efa31..0d79cadef34 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -250,7 +250,7 @@ impl AttrItem { AttrArgs::Delimited(args) if args.delim == Delimiter::Parenthesis => { MetaItemKind::list_from_tokens(args.tokens.clone()) } - AttrArgs::Delimited(_) | AttrArgs::Eq(..) | AttrArgs::Empty => None, + AttrArgs::Delimited(_) | AttrArgs::Eq { .. } | AttrArgs::Empty => None, } } @@ -268,7 +268,7 @@ impl AttrItem { /// ``` fn value_str(&self) -> Option<Symbol> { match &self.args { - AttrArgs::Eq(_, args) => args.value_str(), + AttrArgs::Eq { value, .. } => value.value_str(), AttrArgs::Delimited(_) | AttrArgs::Empty => None, } } @@ -492,7 +492,7 @@ impl MetaItemKind { MetaItemKind::list_from_tokens(tokens.clone()).map(MetaItemKind::List) } AttrArgs::Delimited(..) => None, - AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind { + AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => match expr.kind { ExprKind::Lit(token_lit) => { // Turn failures to `None`, we'll get parse errors elsewhere. MetaItemLit::from_token_lit(token_lit, expr.span) @@ -501,7 +501,9 @@ impl MetaItemKind { } _ => None, }, - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), + AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { + Some(MetaItemKind::NameValue(lit.clone())) + } } } } @@ -702,7 +704,7 @@ pub fn mk_attr_name_value_str( tokens: None, }); let path = Path::from_ident(Ident::new(name, span)); - let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr)); + let args = AttrArgs::Eq { eq_span: span, value: AttrArgsEq::Ast(expr) }; mk_attr(g, style, unsafety, path, args, span) } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 0aceed45028..196fcc1af30 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -451,13 +451,10 @@ fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) { match args { AttrArgs::Empty => {} AttrArgs::Delimited(args) => visit_delim_args(vis, args), - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { - vis.visit_expr(expr); + AttrArgs::Eq { eq_span, value } => { + vis.visit_expr(value.unwrap_ast_mut()); vis.visit_span(eq_span); } - AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when visiting mac args eq: {:?}", lit) - } } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 718397e8ca0..2f6998783fa 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1273,10 +1273,7 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) - match args { AttrArgs::Empty => {} AttrArgs::Delimited(_args) => {} - AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => try_visit!(visitor.visit_expr(expr)), - AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when walking mac args eq: {:?}", lit) - } + AttrArgs::Eq { value, .. } => try_visit!(visitor.visit_expr(value.unwrap_ast())), } V::Result::output() } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7ffe4db6e45..8ec1272e360 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -889,7 +889,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle // nonterminals in `#[doc]` (e.g. `#[doc = $e]`). - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { + &AttrArgs::Eq { eq_span, ref value } => { + let expr = value.unwrap_ast(); // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. let lit = if let ExprKind::Lit(token_lit) = expr.kind @@ -905,10 +906,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: DUMMY_SP, } }; - AttrArgs::Eq(*eq_span, AttrArgsEq::Hir(lit)) - } - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when lowering mac args eq: {:?}", lit) + AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) } } } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index d7c531f3760..479677b0a5a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -648,14 +648,14 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere AttrArgs::Empty => { self.print_path(&item.path, false, 0); } - AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => { + AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); let token_str = self.expr_to_string(expr); self.word(token_str); } - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { + AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 48beb9be2b2..f6d2ec24da6 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -148,7 +148,7 @@ fn prepare_lto( // __llvm_profile_counter_bias is pulled in at link time by an undefined reference to // __llvm_profile_runtime, therefore we won't know until link time if this symbol // should have default visibility. - symbols_below_threshold.push(CString::new("__llvm_profile_counter_bias").unwrap()); + symbols_below_threshold.push(c"__llvm_profile_counter_bias".to_owned()); Ok((symbols_below_threshold, upstream_modules)) } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 2744795d998..bde6668929c 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -509,7 +509,7 @@ fn get_pgo_sample_use_path(config: &ModuleConfig) -> Option<CString> { } fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> { - config.instrument_coverage.then(|| CString::new("default_%m_%p.profraw").unwrap()) + config.instrument_coverage.then(|| c"default_%m_%p.profraw".to_owned()) } pub(crate) unsafe fn llvm_optimize( diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 1271d9d2d0d..3cb77d1dcb5 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -139,12 +139,14 @@ where match error { // Don't emit a new diagnostic for these errors, they are already reported elsewhere or // should remain silent. + err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span), err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { ErrorHandled::TooGeneric(span) } - err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span), err_inval!(Layout(LayoutError::ReferencesError(guar))) => { - ErrorHandled::Reported(ReportedErrorInfo::tainted_by_errors(guar), span) + // This can occur in infallible promoteds e.g. when a non-existent type or field is + // encountered. + ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), span) } // Report remaining errors. _ => { @@ -152,7 +154,12 @@ where let span = span.substitute_dummy(our_span); let err = mk(span, frames); let mut err = tcx.dcx().create_err(err); - let can_be_spurious = matches!(error, InterpErrorKind::ResourceExhaustion(_)); + // We allow invalid programs in infallible promoteds since invalid layouts can occur + // anyway (e.g. due to size overflow). And we allow OOM as that can happen any time. + let allowed_in_infallible = matches!( + error, + InterpErrorKind::ResourceExhaustion(_) | InterpErrorKind::InvalidProgram(_) + ); let msg = error.diagnostic_message(); error.add_args(&mut err); @@ -160,8 +167,8 @@ where // Use *our* span to label the interp error err.span_label(our_span, msg); let g = err.emit(); - let reported = if can_be_spurious { - ReportedErrorInfo::spurious(g) + let reported = if allowed_in_infallible { + ReportedErrorInfo::allowed_in_infallible(g) } else { ReportedErrorInfo::from(g) }; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index fe93a48c2f2..241be5e175c 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -268,7 +268,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; // do not continue if typeck errors occurred (can only occur in local crate) if let Some(err) = body.tainted_by_errors { - throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err))); + throw_inval!(AlreadyReported(ReportedErrorInfo::from(err))); } interp_ok(body) } @@ -585,13 +585,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { match err { ErrorHandled::TooGeneric(..) => {}, ErrorHandled::Reported(reported, span) => { - if reported.is_tainted_by_errors() { - // const-eval will return "tainted" errors if e.g. the layout cannot - // be computed as the type references non-existing names. - // See <https://github.com/rust-lang/rust/issues/124348>. - } else if reported.can_be_spurious() { + if reported.is_allowed_in_infallible() { // These errors can just sometimes happen, even when the expression - // is nominally "infallible", e.g. when running out of memory. + // is nominally "infallible", e.g. when running out of memory + // or when some layout could not be computed. } else { // Looks like the const is not captured by `required_consts`, that's bad. span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts"); diff --git a/compiler/rustc_error_codes/src/error_codes/E0060.md b/compiler/rustc_error_codes/src/error_codes/E0060.md index 54b10c886cc..a6831c881e3 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0060.md +++ b/compiler/rustc_error_codes/src/error_codes/E0060.md @@ -15,7 +15,7 @@ unsafe { printf(); } // error! Using this declaration, it must be called with at least one argument, so simply calling `printf()` is invalid. But the following uses are allowed: -``` +```rust,edition2021 # use std::os::raw::{c_char, c_int}; # #[cfg_attr(all(windows, target_env = "msvc"), # link(name = "legacy_stdio_definitions", @@ -23,16 +23,11 @@ simply calling `printf()` is invalid. But the following uses are allowed: # extern "C" { fn printf(_: *const c_char, ...) -> c_int; } # fn main() { unsafe { - use std::ffi::CString; - - let fmt = CString::new("test\n").unwrap(); - printf(fmt.as_ptr()); + printf(c"test\n".as_ptr()); - let fmt = CString::new("number = %d\n").unwrap(); - printf(fmt.as_ptr(), 3); + printf(c"number = %d\n".as_ptr(), 3); - let fmt = CString::new("%d, %d\n").unwrap(); - printf(fmt.as_ptr(), 10, 5); + printf(c"%d, %d\n".as_ptr(), 10, 5); } # } ``` diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 19c2d466f7c..e5500c8bba1 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -732,7 +732,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => item.to_tokens(), }; let attr_item = attr.unwrap_normal_item(); - if let AttrArgs::Eq(..) = attr_item.args { + if let AttrArgs::Eq { .. } = attr_item.args { self.cx.dcx().emit_err(UnsupportedKeyValue { span }); } let inner_tokens = attr_item.args.inner_tokens(); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 8fa797db246..ed3ae1e12b9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -13,6 +13,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_macros::LintDiagnostic; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::query::Providers; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::trait_def::TraitSpecializationKind; @@ -1170,19 +1171,13 @@ fn check_type_defn<'tcx>( // Explicit `enum` discriminant values must const-evaluate successfully. if let ty::VariantDiscr::Explicit(discr_def_id) = variant.discr { - let cause = traits::ObligationCause::new( - tcx.def_span(discr_def_id), - wfcx.body_def_id, - ObligationCauseCode::Misc, - ); - wfcx.register_obligation(Obligation::new( - tcx, - cause, - wfcx.param_env, - ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable( - ty::Const::from_anon_const(tcx, discr_def_id.expect_local()), - ))), - )); + match tcx.const_eval_poly(discr_def_id) { + Ok(_) => {} + Err(ErrorHandled::Reported(..)) => {} + Err(ErrorHandled::TooGeneric(sp)) => { + span_bug!(sp, "enum variant discr was too generic to eval") + } + } } } diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 8648a7d1e32..f1022d95753 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -1,6 +1,6 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::intravisit; -use rustc_middle::hir::nested_filter::OnlyBodies; +use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::sym; @@ -42,7 +42,8 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { } pub(crate) fn def_parents(tcx: TyCtxt<'_>) { - for did in tcx.hir().body_owners() { + for iid in tcx.hir().items() { + let did = iid.owner_id.def_id; if tcx.has_attr(did, sym::rustc_dump_def_parents) { struct AnonConstFinder<'tcx> { tcx: TyCtxt<'tcx>, @@ -50,7 +51,7 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) { } impl<'tcx> intravisit::Visitor<'tcx> for AnonConstFinder<'tcx> { - type NestedFilter = OnlyBodies; + type NestedFilter = nested_filter::All; fn nested_visit_map(&mut self) -> Self::Map { self.tcx.hir() @@ -62,11 +63,11 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) { } } - // Look for any anon consts inside of this body owner as there is no way to apply + // Look for any anon consts inside of this item as there is no way to apply // the `rustc_dump_def_parents` attribute to the anon const so it would not be possible // to see what its def parent is. let mut anon_ct_finder = AnonConstFinder { tcx, anon_consts: vec![] }; - intravisit::walk_expr(&mut anon_ct_finder, tcx.hir().body_owned_by(did).value); + intravisit::walk_item(&mut anon_ct_finder, tcx.hir().item(iid)); for did in [did].into_iter().chain(anon_ct_finder.anon_consts) { let span = tcx.def_span(did); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index bfee5d33598..ca2597e79fd 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -1,12 +1,13 @@ use std::assert_matches::assert_matches; -use hir::{HirId, Node}; +use hir::Node; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit::{self, Visitor}; -use rustc_middle::ty::{self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, Upcast}; +use rustc_middle::ty::{ + self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast, +}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span}; @@ -305,7 +306,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } if tcx.features().generic_const_exprs() { - predicates.extend(const_evaluatable_predicates_of(tcx, def_id)); + predicates.extend(const_evaluatable_predicates_of(tcx, def_id, &predicates)); } let mut predicates: Vec<_> = predicates.into_iter().collect(); @@ -369,32 +370,48 @@ fn compute_bidirectional_outlives_predicates<'tcx>( } } -fn const_evaluatable_predicates_of( - tcx: TyCtxt<'_>, +#[instrument(level = "debug", skip(tcx, predicates), ret)] +fn const_evaluatable_predicates_of<'tcx>( + tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> FxIndexSet<(ty::Clause<'_>, Span)> { + predicates: &FxIndexSet<(ty::Clause<'tcx>, Span)>, +) -> FxIndexSet<(ty::Clause<'tcx>, Span)> { struct ConstCollector<'tcx> { tcx: TyCtxt<'tcx>, preds: FxIndexSet<(ty::Clause<'tcx>, Span)>, } - impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> { - fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { - let ct = ty::Const::from_anon_const(self.tcx, c.def_id); - if let ty::ConstKind::Unevaluated(_) = ct.kind() { - let span = self.tcx.def_span(c.def_id); - self.preds.insert((ty::ClauseKind::ConstEvaluatable(ct).upcast(self.tcx), span)); - } - } + fn is_const_param_default(tcx: TyCtxt<'_>, def: LocalDefId) -> bool { + let hir_id = tcx.local_def_id_to_hir_id(def); + let (_, parent_node) = tcx + .hir() + .parent_iter(hir_id) + .skip_while(|(_, n)| matches!(n, Node::ConstArg(..))) + .next() + .unwrap(); + matches!( + parent_node, + Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { .. }, .. }) + ) + } - fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::ConstArg<'tcx>) { - // Do not look into const param defaults, - // these get checked when they are actually instantiated. - // - // We do not want the following to error: - // - // struct Foo<const N: usize, const M: usize = { N + 1 }>; - // struct Bar<const N: usize>(Foo<N, 3>); + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstCollector<'tcx> { + fn visit_const(&mut self, c: ty::Const<'tcx>) { + if let ty::ConstKind::Unevaluated(uv) = c.kind() { + if is_const_param_default(self.tcx, uv.def.expect_local()) { + // Do not look into const param defaults, + // these get checked when they are actually instantiated. + // + // We do not want the following to error: + // + // struct Foo<const N: usize, const M: usize = { N + 1 }>; + // struct Bar<const N: usize>(Foo<N, 3>); + return; + } + + let span = self.tcx.def_span(uv.def); + self.preds.insert((ty::ClauseKind::ConstEvaluatable(c).upcast(self.tcx), span)); + } } } @@ -402,28 +419,31 @@ fn const_evaluatable_predicates_of( let node = tcx.hir_node(hir_id); let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() }; + + for (clause, _sp) in predicates { + clause.visit_with(&mut collector); + } + if let hir::Node::Item(item) = node - && let hir::ItemKind::Impl(impl_) = item.kind + && let hir::ItemKind::Impl(_) = item.kind { - if let Some(of_trait) = &impl_.of_trait { - debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id); - collector.visit_trait_ref(of_trait); + if let Some(of_trait) = tcx.impl_trait_ref(def_id) { + debug!("visit impl trait_ref"); + of_trait.instantiate_identity().visit_with(&mut collector); } - debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id); - collector.visit_ty(impl_.self_ty); - } - - if let Some(generics) = node.generics() { - debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id); - collector.visit_generics(generics); + debug!("visit self_ty"); + let self_ty = tcx.type_of(def_id); + self_ty.instantiate_identity().visit_with(&mut collector); } - if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) { - debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id); - collector.visit_fn_decl(fn_sig.decl); + if let Some(_) = tcx.hir().fn_sig_by_hir_id(hir_id) { + debug!("visit fn sig"); + let fn_sig = tcx.fn_sig(def_id); + let fn_sig = fn_sig.instantiate_identity(); + debug!(?fn_sig); + fn_sig.visit_with(&mut collector); } - debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds); collector.preds } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 9d60759ae48..0404e38a293 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -703,7 +703,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// It might actually be possible that we can already support early-bound generic params /// in such types if we just lifted some more checks in other places, too, for example -/// inside [`ty::Const::from_anon_const`]. However, even if that were the case, we should +/// inside `HirTyLowerer::lower_anon_const`. However, even if that were the case, we should /// probably gate this behind another feature flag. /// /// [^1]: <https://github.com/rust-lang/project-const-generics/issues/28>. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 7b8e95f3434..cb4209116ac 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2089,7 +2089,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { qpath.span(), format!("Const::lower_const_arg: invalid qpath {qpath:?}"), ), - hir::ConstArgKind::Anon(anon) => Const::from_anon_const(tcx, anon.def_id), + hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon.def_id), hir::ConstArgKind::Infer(span) => self.ct_infer(None, span), } } @@ -2177,6 +2177,92 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + /// Literals and const generic parameters are eagerly converted to a constant, everything else + /// becomes `Unevaluated`. + #[instrument(skip(self), level = "debug")] + fn lower_anon_const(&self, def: LocalDefId) -> Const<'tcx> { + let tcx = self.tcx(); + + let body_id = match tcx.hir_node_by_def_id(def) { + hir::Node::AnonConst(ac) => ac.body, + node => span_bug!( + tcx.def_span(def.to_def_id()), + "from_anon_const can only process anonymous constants, not {node:?}" + ), + }; + + let expr = &tcx.hir().body(body_id).value; + debug!(?expr); + + let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic"); + + match self.try_lower_anon_const_lit(ty, expr) { + Some(v) => v, + None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst { + def: def.to_def_id(), + args: ty::GenericArgs::identity_for_item(tcx, def.to_def_id()), + }), + } + } + + #[instrument(skip(self), level = "debug")] + fn try_lower_anon_const_lit( + &self, + ty: Ty<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + ) -> Option<Const<'tcx>> { + let tcx = self.tcx(); + + // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments + // currently have to be wrapped in curly brackets, so it's necessary to special-case. + let expr = match &expr.kind { + hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { + block.expr.as_ref().unwrap() + } + _ => expr, + }; + + if let hir::ExprKind::Path(hir::QPath::Resolved( + _, + &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. }, + )) = expr.kind + { + span_bug!( + expr.span, + "try_lower_anon_const_lit: received const param which shouldn't be possible" + ); + }; + + let lit_input = match expr.kind { + hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }), + hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind { + hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }), + _ => None, + }, + _ => None, + }; + + if let Some(lit_input) = lit_input { + // If an error occurred, ignore that it's a literal and leave reporting the error up to + // mir. + match tcx.at(expr.span).lit_to_const(lit_input) { + Ok(c) => return Some(c), + Err(_) if lit_input.ty.has_aliases() => { + // allow the `ty` to be an alias type, though we cannot handle it here + return None; + } + Err(e) => { + tcx.dcx().span_delayed_bug( + expr.span, + format!("try_lower_anon_const_lit: couldn't lit_to_const {e:?}"), + ); + } + } + } + + None + } + fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> { let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); match idx { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 3b406c7e161..d2b7ae620e2 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -179,7 +179,7 @@ declare_lint! { Warn, "applying forbid to lint-groups", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, reference: "issue #81670 <https://github.com/rust-lang/rust/issues/81670>", }; } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 08afa33c6b4..ad5d678178d 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -46,7 +46,7 @@ impl ErrorHandled { pub fn emit_note(&self, tcx: TyCtxt<'_>) { match self { &ErrorHandled::Reported(err, span) => { - if !err.is_tainted_by_errors && !span.is_dummy() { + if !err.allowed_in_infallible && !span.is_dummy() { tcx.dcx().emit_note(error::ErroneousConstant { span }); } } @@ -58,34 +58,26 @@ impl ErrorHandled { #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub struct ReportedErrorInfo { error: ErrorGuaranteed, - is_tainted_by_errors: bool, - /// Whether this is the kind of error that can sometimes occur, and sometimes not. - /// Used for resource exhaustion errors. - can_be_spurious: bool, + /// Whether this error is allowed to show up even in otherwise "infallible" promoteds. + /// This is for things like overflows during size computation or resource exhaustion. + allowed_in_infallible: bool, } impl ReportedErrorInfo { #[inline] - pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo { - ReportedErrorInfo { is_tainted_by_errors: true, can_be_spurious: false, error } - } - #[inline] - pub fn spurious(error: ErrorGuaranteed) -> ReportedErrorInfo { - ReportedErrorInfo { can_be_spurious: true, is_tainted_by_errors: false, error } + pub fn allowed_in_infallible(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { allowed_in_infallible: true, error } } - pub fn is_tainted_by_errors(&self) -> bool { - self.is_tainted_by_errors - } - pub fn can_be_spurious(&self) -> bool { - self.can_be_spurious + pub fn is_allowed_in_infallible(&self) -> bool { + self.allowed_in_infallible } } impl From<ErrorGuaranteed> for ReportedErrorInfo { #[inline] fn from(error: ErrorGuaranteed) -> ReportedErrorInfo { - ReportedErrorInfo { is_tainted_by_errors: false, can_be_spurious: false, error } + ReportedErrorInfo { allowed_in_infallible: false, error } } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d27205e26ab..31055276422 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -2,15 +2,11 @@ use std::borrow::Cow; use rustc_data_structures::intern::Interned; use rustc_error_messages::MultiSpan; -use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::LocalDefId; -use rustc_hir::{self as hir}; use rustc_macros::HashStable; use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo}; -use tracing::{debug, instrument}; -use crate::mir::interpret::{LitToConstInput, Scalar}; -use crate::ty::{self, GenericArgs, Ty, TyCtxt, TypeVisitableExt}; +use crate::mir::interpret::Scalar; +use crate::ty::{self, Ty, TyCtxt}; mod int; mod kind; @@ -181,82 +177,6 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> { } impl<'tcx> Const<'tcx> { - // FIXME: move this and try_from_lit to hir_ty_lowering like lower_const_arg/from_const_arg - /// Literals and const generic parameters are eagerly converted to a constant, everything else - /// becomes `Unevaluated`. - #[instrument(skip(tcx), level = "debug")] - pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { - let body_id = match tcx.hir_node_by_def_id(def) { - hir::Node::AnonConst(ac) => ac.body, - node => span_bug!( - tcx.def_span(def.to_def_id()), - "from_anon_const can only process anonymous constants, not {node:?}" - ), - }; - - let expr = &tcx.hir().body(body_id).value; - debug!(?expr); - - let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic"); - - match Self::try_from_lit(tcx, ty, expr) { - Some(v) => v, - None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst { - def: def.to_def_id(), - args: GenericArgs::identity_for_item(tcx, def.to_def_id()), - }), - } - } - - #[instrument(skip(tcx), level = "debug")] - fn try_from_lit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) -> Option<Self> { - // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments - // currently have to be wrapped in curly brackets, so it's necessary to special-case. - let expr = match &expr.kind { - hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { - block.expr.as_ref().unwrap() - } - _ => expr, - }; - - if let hir::ExprKind::Path(hir::QPath::Resolved( - _, - &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. }, - )) = expr.kind - { - span_bug!(expr.span, "try_from_lit: received const param which shouldn't be possible"); - }; - - let lit_input = match expr.kind { - hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }), - hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind { - hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }), - _ => None, - }, - _ => None, - }; - - if let Some(lit_input) = lit_input { - // If an error occurred, ignore that it's a literal and leave reporting the error up to - // mir. - match tcx.at(expr.span).lit_to_const(lit_input) { - Ok(c) => return Some(c), - Err(_) if lit_input.ty.has_aliases() => { - // allow the `ty` to be an alias type, though we cannot handle it here - return None; - } - Err(e) => { - tcx.dcx().span_delayed_bug( - expr.span, - format!("Const::try_from_lit: couldn't lit_to_const {e:?}"), - ); - } - } - } - - None - } - /// Creates a constant with the given integer value and interns it. #[inline] pub fn from_bits( diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs index 11cf8c3e898..4a9bcdaddb3 100644 --- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs @@ -15,7 +15,6 @@ pub enum ResultsHandle<'a, 'tcx, A> where A: Analysis<'tcx>, { - Borrowed(&'a Results<'tcx, A>), BorrowedMut(&'a mut Results<'tcx, A>), Owned(Results<'tcx, A>), } @@ -28,7 +27,6 @@ where fn deref(&self) -> &Results<'tcx, A> { match self { - ResultsHandle::Borrowed(borrowed) => borrowed, ResultsHandle::BorrowedMut(borrowed) => borrowed, ResultsHandle::Owned(owned) => owned, } @@ -41,9 +39,6 @@ where { fn deref_mut(&mut self) -> &mut Results<'tcx, A> { match self { - ResultsHandle::Borrowed(_borrowed) => { - panic!("tried to deref_mut a `ResultsHandle::Borrowed") - } ResultsHandle::BorrowedMut(borrowed) => borrowed, ResultsHandle::Owned(owned) => owned, } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index 6e4994af8b4..561229cf725 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -47,7 +47,7 @@ where { pub(crate) fn new( body: &'mir Body<'tcx>, - results: &'mir Results<'tcx, A>, + results: &'mir mut Results<'tcx, A>, style: OutputStyle, ) -> Self { let reachable = mir::traversal::reachable_as_bitset(body); diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index f1ea94e1689..b9407882ec5 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -281,10 +281,10 @@ pub trait Analysis<'tcx> { ); } - let results = Results { analysis: self, entry_sets }; + let mut results = Results { analysis: self, entry_sets }; if tcx.sess.opts.unstable_opts.dump_mir_dataflow { - let res = write_graphviz_results(tcx, body, &results, pass_name); + let res = write_graphviz_results(tcx, body, &mut results, pass_name); if let Err(e) = res { error!("Failed to write graphviz dataflow results: {}", e); } diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs index 8493a7aa44b..c4321c454e6 100644 --- a/compiler/rustc_mir_dataflow/src/framework/results.rs +++ b/compiler/rustc_mir_dataflow/src/framework/results.rs @@ -37,18 +37,9 @@ impl<'tcx, A> Results<'tcx, A> where A: Analysis<'tcx>, { - /// Creates a `ResultsCursor` that can inspect these `Results`. Immutably borrows the `Results`, - /// which is appropriate when the `Results` is used outside the cursor. + /// Creates a `ResultsCursor` that mutably borrows the `Results`, which is appropriate when the + /// `Results` is also used outside the cursor. pub fn as_results_cursor<'mir>( - &'mir self, - body: &'mir mir::Body<'tcx>, - ) -> ResultsCursor<'mir, 'tcx, A> { - ResultsCursor::new(body, ResultsHandle::Borrowed(self)) - } - - /// Creates a `ResultsCursor` that can mutate these `Results`. Mutably borrows the `Results`, - /// which is appropriate when the `Results` is used outside the cursor. - pub fn as_results_cursor_mut<'mir>( &'mir mut self, body: &'mir mir::Body<'tcx>, ) -> ResultsCursor<'mir, 'tcx, A> { @@ -95,7 +86,7 @@ where pub(super) fn write_graphviz_results<'tcx, A>( tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>, - results: &Results<'tcx, A>, + results: &mut Results<'tcx, A>, pass_name: Option<&'static str>, ) -> std::io::Result<()> where diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 9b9aeccf890..858752a3f01 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -680,7 +680,7 @@ fn locals_live_across_suspend_points<'tcx>( let mut requires_storage_results = MaybeRequiresStorage::new(borrowed_locals_results.into_results_cursor(body)) .iterate_to_fixpoint(tcx, body, None); - let mut requires_storage_cursor = requires_storage_results.as_results_cursor_mut(body); + let mut requires_storage_cursor = requires_storage_results.as_results_cursor(body); // Calculate the liveness of MIR locals ignoring borrows. let mut liveness = diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 0ed8d152d2d..37556c064d8 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1376,7 +1376,7 @@ impl<'a> Parser<'a> { AttrArgs::Delimited(args) } else if self.eat(&token::Eq) { let eq_span = self.prev_token.span; - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(self.parse_expr_force_collect()?)) + AttrArgs::Eq { eq_span, value: AttrArgsEq::Ast(self.parse_expr_force_collect()?) } } else { AttrArgs::Empty }) diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index f3174e7dea2..aab3f10bc66 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -43,7 +43,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { } } _ => { - if let AttrArgs::Eq(..) = attr_item.args { + if let AttrArgs::Eq { .. } = attr_item.args { // All key-value attributes are restricted to meta-item syntax. match parse_meta(psess, attr) { Ok(_) => {} @@ -70,7 +70,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met parse_in(psess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?; MetaItemKind::List(nmis) } - AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => { + AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => { if let ast::ExprKind::Lit(token_lit) = expr.kind { let res = ast::MetaItemLit::from_token_lit(token_lit, expr.span); let res = match res { @@ -116,7 +116,9 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met return Err(err); } } - AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()), + AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => { + MetaItemKind::NameValue(lit.clone()) + } }, }) } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 02e255d7726..65128ceb866 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -220,9 +220,9 @@ pub fn attrs_to_doc_fragments<'a>( fn span_for_value(attr: &ast::Attribute) -> Span { if let ast::AttrKind::Normal(normal) = &attr.kind - && let ast::AttrArgs::Eq(_, ast::AttrArgsEq::Hir(meta)) = &normal.item.args + && let ast::AttrArgs::Eq { value, .. } = &normal.item.args { - meta.span.with_ctxt(attr.span.ctxt()) + value.span().with_ctxt(attr.span.ctxt()) } else { attr.span } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 7f42c932fcf..f10314c1c9e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -1,7 +1,7 @@ use std::iter; use std::path::PathBuf; -use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, MetaItemInner}; +use rustc_ast::{AttrArgs, AttrKind, Attribute, MetaItemInner}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; @@ -639,8 +639,7 @@ impl<'tcx> OnUnimplementedDirective { let report_span = match &item.args { AttrArgs::Empty => item.path.span, AttrArgs::Delimited(args) => args.dspan.entire(), - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => eq_span.to(expr.span), - AttrArgs::Eq(span, AttrArgsEq::Hir(expr)) => span.to(expr.span), + AttrArgs::Eq { eq_span, value } => eq_span.to(value.span()), }; if let Some(item_def_id) = item_def_id.as_local() { |
