Skip to content

Commit 62463eb

Browse files
committed
Auto merge of #152421 - matthiaskrgr:rollup-iLA2nqY, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #151152 (Add FCW for derive helper attributes that will conflict with built-in attributes) - #151954 (Add help message suggesting explicit reference cast for From/TryFrom) - #152148 (Move `impl Interner for TyCtxt` to its own submodule) - #152226 (Modernize diagnostic for indeterminate trait object lifetime bounds) - #150688 (typeck: Make it clearer that `check_pat_lit` only handles literal patterns) - #152293 (Format heterogeneous try blocks) - #152396 (Uplift `Predicate::allow_normalization` to `rustc_type_ir`)
2 parents f21b4c0 + f1f8dee commit 62463eb

33 files changed

Lines changed: 1346 additions & 868 deletions

compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use rustc_hir::lints::AttributeLintKind;
2+
use rustc_session::lint::builtin::AMBIGUOUS_DERIVE_HELPERS;
3+
14
use super::prelude::*;
25

36
const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets =
@@ -126,6 +129,13 @@ fn parse_derive_like<S: Stage>(
126129
cx.expected_identifier(ident.span);
127130
return None;
128131
}
132+
if rustc_feature::is_builtin_attr_name(ident.name) {
133+
cx.emit_lint(
134+
AMBIGUOUS_DERIVE_HELPERS,
135+
AttributeLintKind::AmbiguousDeriveHelpers,
136+
ident.span,
137+
);
138+
}
129139
attributes.push(ident.name);
130140
}
131141
}

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ use rustc_abi::{ExternAbi, Size};
2222
use rustc_ast::Recovered;
2323
use rustc_data_structures::assert_matches;
2424
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
25-
use rustc_errors::{
26-
Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey, struct_span_code_err,
27-
};
25+
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey};
2826
use rustc_hir::attrs::AttributeKind;
2927
use rustc_hir::def::{DefKind, Res};
3028
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -318,16 +316,24 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
318316
}
319317

320318
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
321-
if let RegionInferReason::ObjectLifetimeDefault = reason {
322-
let e = struct_span_code_err!(
323-
self.dcx(),
324-
span,
325-
E0228,
326-
"the lifetime bound for this object type cannot be deduced \
327-
from context; please supply an explicit bound"
328-
)
329-
.emit();
330-
ty::Region::new_error(self.tcx(), e)
319+
if let RegionInferReason::ObjectLifetimeDefault(sugg_sp) = reason {
320+
// FIXME: Account for trailing plus `dyn Trait+`, the need of parens in
321+
// `*const dyn Trait` and `Fn() -> *const dyn Trait`.
322+
let guar = self
323+
.dcx()
324+
.struct_span_err(
325+
span,
326+
"cannot deduce the lifetime bound for this trait object type from context",
327+
)
328+
.with_code(E0228)
329+
.with_span_suggestion_verbose(
330+
sugg_sp,
331+
"please supply an explicit bound",
332+
" + /* 'a */",
333+
Applicability::HasPlaceholders,
334+
)
335+
.emit();
336+
ty::Region::new_error(self.tcx(), guar)
331337
} else {
332338
// This indicates an illegal lifetime in a non-assoc-trait position
333339
ty::Region::new_error_with_message(self.tcx(), span, "unelided lifetime in signature")

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
460460
// Parent lifetime must have failed to resolve. Don't emit a redundant error.
461461
RegionInferReason::ExplicitObjectLifetime
462462
} else {
463-
RegionInferReason::ObjectLifetimeDefault
463+
RegionInferReason::ObjectLifetimeDefault(span.shrink_to_hi())
464464
}
465465
} else {
466466
RegionInferReason::ExplicitObjectLifetime

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub enum RegionInferReason<'a> {
104104
/// Lifetime on a trait object that is spelled explicitly, e.g. `+ 'a` or `+ '_`.
105105
ExplicitObjectLifetime,
106106
/// A trait object's lifetime when it is elided, e.g. `dyn Any`.
107-
ObjectLifetimeDefault,
107+
ObjectLifetimeDefault(Span),
108108
/// Generic lifetime parameter
109109
Param(&'a ty::GenericParamDef),
110110
RegionPredicate,

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
33

44
use rustc_abi::FieldIdx;
55
use rustc_ast as ast;
6+
use rustc_data_structures::assert_matches;
67
use rustc_data_structures::fx::FxHashMap;
78
use rustc_errors::codes::*;
89
use rustc_errors::{
@@ -24,7 +25,6 @@ use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
2425
use rustc_session::parse::feature_err;
2526
use rustc_span::edit_distance::find_best_match_for_name;
2627
use rustc_span::edition::Edition;
27-
use rustc_span::source_map::Spanned;
2828
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym};
2929
use rustc_trait_selection::infer::InferCtxtExt;
3030
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
@@ -611,7 +611,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
611611
self.write_ty(*hir_id, ty);
612612
ty
613613
}
614-
PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, &pat_info.top_info),
614+
PatKind::Expr(expr @ PatExpr { kind: PatExprKind::Lit { lit, .. }, .. }) => {
615+
self.check_pat_lit(pat.span, expr, &lit.node, expected, &pat_info.top_info)
616+
}
615617
PatKind::Range(lhs, rhs, _) => {
616618
self.check_pat_range(pat.span, lhs, rhs, expected, &pat_info.top_info)
617619
}
@@ -938,31 +940,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
938940
fn check_pat_lit(
939941
&self,
940942
span: Span,
941-
lt: &hir::PatExpr<'tcx>,
943+
expr: &hir::PatExpr<'tcx>,
944+
lit_kind: &ast::LitKind,
942945
expected: Ty<'tcx>,
943946
ti: &TopInfo<'tcx>,
944947
) -> Ty<'tcx> {
948+
assert_matches!(expr.kind, hir::PatExprKind::Lit { .. });
949+
945950
// We've already computed the type above (when checking for a non-ref pat),
946951
// so avoid computing it again.
947-
let ty = self.node_ty(lt.hir_id);
952+
let ty = self.node_ty(expr.hir_id);
948953

949954
// Byte string patterns behave the same way as array patterns
950955
// They can denote both statically and dynamically-sized byte arrays.
951956
// Additionally, when `deref_patterns` is enabled, byte string literal patterns may have
952957
// types `[u8]` or `[u8; N]`, in order to type, e.g., `deref!(b"..."): Vec<u8>`.
953958
let mut pat_ty = ty;
954-
if let hir::PatExprKind::Lit {
955-
lit: Spanned { node: ast::LitKind::ByteStr(..), .. }, ..
956-
} = lt.kind
957-
{
959+
if matches!(lit_kind, ast::LitKind::ByteStr(..)) {
958960
let tcx = self.tcx;
959961
let expected = self.structurally_resolve_type(span, expected);
960962
match *expected.kind() {
961963
// Allow `b"...": &[u8]`
962964
ty::Ref(_, inner_ty, _)
963965
if self.try_structurally_resolve_type(span, inner_ty).is_slice() =>
964966
{
965-
trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
967+
trace!(?expr.hir_id.local_id, "polymorphic byte string lit");
966968
pat_ty = Ty::new_imm_ref(
967969
tcx,
968970
tcx.lifetimes.re_static,
@@ -988,9 +990,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
988990
// When `deref_patterns` is enabled, in order to allow `deref!("..."): String`, we allow
989991
// string literal patterns to have type `str`. This is accounted for when lowering to MIR.
990992
if self.tcx.features().deref_patterns()
991-
&& let hir::PatExprKind::Lit {
992-
lit: Spanned { node: ast::LitKind::Str(..), .. }, ..
993-
} = lt.kind
993+
&& matches!(lit_kind, ast::LitKind::Str(..))
994994
&& self.try_structurally_resolve_type(span, expected).is_str()
995995
{
996996
pat_ty = self.tcx.types.str_;

compiler/rustc_lint/src/early/diagnostics.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,10 @@ pub fn decorate_attribute_lint(
383383
lints::DocAutoCfgExpectsHideOrShow.decorate_lint(diag)
384384
}
385385

386+
&AttributeLintKind::AmbiguousDeriveHelpers => {
387+
lints::AmbiguousDeriveHelpers.decorate_lint(diag)
388+
}
389+
386390
&AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name } => {
387391
lints::DocAutoCfgHideShowUnexpectedItem { attr_name }.decorate_lint(diag)
388392
}

compiler/rustc_lint/src/lints.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3752,6 +3752,10 @@ pub(crate) struct DocAliasDuplicated {
37523752
#[diag("only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]`")]
37533753
pub(crate) struct DocAutoCfgExpectsHideOrShow;
37543754

3755+
#[derive(LintDiagnostic)]
3756+
#[diag("there exists a built-in attribute with the same name")]
3757+
pub(crate) struct AmbiguousDeriveHelpers;
3758+
37553759
#[derive(LintDiagnostic)]
37563760
#[diag("`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items")]
37573761
pub(crate) struct DocAutoCfgHideShowUnexpectedItem {

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ declare_lint_pass! {
1717
AARCH64_SOFTFLOAT_NEON,
1818
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
1919
AMBIGUOUS_ASSOCIATED_ITEMS,
20+
AMBIGUOUS_DERIVE_HELPERS,
2021
AMBIGUOUS_GLOB_IMPORTED_TRAITS,
2122
AMBIGUOUS_GLOB_IMPORTS,
2223
AMBIGUOUS_GLOB_REEXPORTS,
@@ -4267,6 +4268,75 @@ declare_lint! {
42674268
};
42684269
}
42694270

4271+
declare_lint! {
4272+
/// The `ambiguous_derive_helpers` lint detects cases where a derive macro's helper attribute
4273+
/// is the same name as that of a built-in attribute.
4274+
///
4275+
/// ### Example
4276+
///
4277+
/// ```rust,ignore (proc-macro)
4278+
/// #![crate_type = "proc-macro"]
4279+
/// #![deny(ambiguous_derive_helpers)]
4280+
///
4281+
/// use proc_macro::TokenStream;
4282+
///
4283+
/// #[proc_macro_derive(Trait, attributes(ignore))]
4284+
/// pub fn example(input: TokenStream) -> TokenStream {
4285+
/// TokenStream::new()
4286+
/// }
4287+
/// ```
4288+
///
4289+
/// Produces:
4290+
///
4291+
/// ```text
4292+
/// warning: there exists a built-in attribute with the same name
4293+
/// --> file.rs:5:39
4294+
/// |
4295+
/// 5 | #[proc_macro_derive(Trait, attributes(ignore))]
4296+
/// | ^^^^^^
4297+
/// |
4298+
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4299+
/// = note: for more information, see issue #151152 <https://github.com/rust-lang/rust/issues/151152>
4300+
/// = note: `#[deny(ambiguous_derive_helpers)]` (part of `#[deny(future_incompatible)]`) on by default
4301+
/// ```
4302+
///
4303+
/// ### Explanation
4304+
///
4305+
/// Attempting to use this helper attribute will throw an error:
4306+
///
4307+
/// ```rust,ignore (needs-dependency)
4308+
/// #[derive(Trait)]
4309+
/// struct Example {
4310+
/// #[ignore]
4311+
/// fields: ()
4312+
/// }
4313+
/// ```
4314+
///
4315+
/// Produces:
4316+
///
4317+
/// ```text
4318+
/// error[E0659]: `ignore` is ambiguous
4319+
/// --> src/lib.rs:5:7
4320+
/// |
4321+
/// 5 | #[ignore]
4322+
/// | ^^^^^^ ambiguous name
4323+
/// |
4324+
/// = note: ambiguous because of a name conflict with a builtin attribute
4325+
/// = note: `ignore` could refer to a built-in attribute
4326+
/// note: `ignore` could also refer to the derive helper attribute defined here
4327+
/// --> src/lib.rs:3:10
4328+
/// |
4329+
/// 3 | #[derive(Trait)]
4330+
/// | ^^^^^
4331+
/// ```
4332+
pub AMBIGUOUS_DERIVE_HELPERS,
4333+
Warn,
4334+
"detects derive helper attributes that are ambiguous with built-in attributes",
4335+
@future_incompatible = FutureIncompatibleInfo {
4336+
reason: fcw!(FutureReleaseError #151276),
4337+
};
4338+
}
4339+
42704340
declare_lint! {
42714341
/// The `private_interfaces` lint detects types in a primary interface of an item,
42724342
/// that are more private than the item itself. Primary interface of an item is all

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,7 @@ pub enum AttributeLintKind {
800800
attr_name: Symbol,
801801
},
802802
DocInvalid,
803+
AmbiguousDeriveHelpers,
803804
DocUnknownInclude {
804805
span: Span,
805806
inner: &'static str,

0 commit comments

Comments
 (0)