1
Fork 0

Merge from rustc

This commit is contained in:
The Miri Conjob Bot 2024-01-23 05:02:41 +00:00
commit cc08dd1898
705 changed files with 12408 additions and 6206 deletions

View file

@ -15,6 +15,7 @@ If you wish to _contribute_ to the compiler, you should read
<summary>Table of Contents</summary>
- [Quick Start](#quick-start)
- [Installing from Source](#installing-from-source)
- [Getting Help](#getting-help)
- [Contributing](#contributing)
- [License](#license)
@ -29,9 +30,10 @@ Read ["Installation"] from [The Book].
["Installation"]: https://doc.rust-lang.org/book/ch01-01-installation.html
[The Book]: https://doc.rust-lang.org/book/index.html
## Installing from source
## Installing from Source
If you really want to install from source (though this is not recommended), see [INSTALL.md](INSTALL.md).
If you really want to install from source (though this is not recommended), see
[INSTALL.md](INSTALL.md).
## Getting Help

View file

@ -484,6 +484,19 @@ impl DroplessArena {
}
}
/// Used by `Lift` to check whether this slice is allocated
/// in this arena.
#[inline]
pub fn contains_slice<T>(&self, slice: &[T]) -> bool {
for chunk in self.chunks.borrow_mut().iter_mut() {
let ptr = slice.as_ptr().cast::<u8>().cast_mut();
if chunk.start() <= ptr && chunk.end() >= ptr {
return true;
}
}
false
}
/// Allocates a string slice that is copied into the `DroplessArena`, returning a
/// reference to it. Will panic if passed an empty string.
///

View file

@ -27,6 +27,7 @@ pub use UnsafeSource::*;
use crate::ptr::P;
use crate::token::{self, CommentKind, Delimiter};
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
use rustc_data_structures::packed::Pu128;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
@ -1833,7 +1834,7 @@ pub enum LitKind {
/// A character literal (`'a'`).
Char(char),
/// An integer literal (`1`).
Int(u128, LitIntType),
Int(Pu128, LitIntType),
/// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
/// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
/// and `Hash`.
@ -3304,13 +3305,9 @@ mod size_asserts {
static_assert_size!(Impl, 136);
static_assert_size!(Item, 136);
static_assert_size!(ItemKind, 64);
// This can be removed after i128:128 is in the bootstrap compiler's target.
#[cfg(not(bootstrap))]
static_assert_size!(LitKind, 32);
static_assert_size!(LitKind, 24);
static_assert_size!(Local, 72);
// This can be removed after i128:128 is in the bootstrap compiler's target.
#[cfg(not(bootstrap))]
static_assert_size!(MetaItemLit, 48);
static_assert_size!(MetaItemLit, 40);
static_assert_size!(Param, 40);
static_assert_size!(Pat, 72);
static_assert_size!(Path, 24);

View file

@ -366,7 +366,7 @@ fn integer_lit(symbol: Symbol, suffix: Option<Symbol>) -> Result<LitKind, LitErr
};
let s = &s[if base != 10 { 2 } else { 0 }..];
u128::from_str_radix(s, base).map(|i| LitKind::Int(i, ty)).map_err(|_| {
u128::from_str_radix(s, base).map(|i| LitKind::Int(i.into(), ty)).map_err(|_| {
// Small bases are lexed as if they were base 10, e.g, the string
// might be `0b10201`. This will cause the conversion above to fail,
// but these kinds of errors are already reported by the lexer.

View file

@ -1899,7 +1899,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> {
let lit = self.arena.alloc(hir::Lit {
span: sp,
node: ast::LitKind::Int(value as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)),
node: ast::LitKind::Int(
(value as u128).into(),
ast::LitIntType::Unsigned(ast::UintTy::Usize),
),
});
self.expr(sp, hir::ExprKind::Lit(lit))
}
@ -1907,7 +1910,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn expr_u32(&mut self, sp: Span, value: u32) -> hir::Expr<'hir> {
let lit = self.arena.alloc(hir::Lit {
span: sp,
node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)),
node: ast::LitKind::Int(
u128::from(value).into(),
ast::LitIntType::Unsigned(ast::UintTy::U32),
),
});
self.expr(sp, hir::ExprKind::Lit(lit))
}

View file

@ -398,7 +398,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
&self,
exclusive_range_pattern,
pattern.span,
"exclusive range pattern syntax is experimental"
"exclusive range pattern syntax is experimental",
"use an inclusive range pattern, like N..=M"
);
}
_ => {}

View file

@ -1185,9 +1185,9 @@ fn allow_unstable<'a>(
pub fn parse_alignment(node: &ast::LitKind) -> Result<u32, &'static str> {
if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
if literal.is_power_of_two() {
if literal.get().is_power_of_two() {
// rustc_middle::ty::layout::Align restricts align to <= 2^29
if *literal <= 1 << 29 { Ok(*literal as u32) } else { Err("larger than 2^29") }
if *literal <= 1 << 29 { Ok(literal.get() as u32) } else { Err("larger than 2^29") }
} else {
Err("not a power of two")
}

View file

@ -296,7 +296,7 @@ impl<'a> IncorrectReprFormatGenericCause<'a> {
pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
match kind {
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
Some(Self::Int { span, name, int: *int })
Some(Self::Int { span, name, int: int.get() })
}
ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
_ => None,

View file

@ -415,7 +415,7 @@ fn do_mir_borrowck<'tcx>(
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
tcx.emit_node_span_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
}
let tainted_by_errors = mbcx.emit_errors();

View file

@ -54,7 +54,7 @@ fn invalid_type_err(
val,
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
)) => {
assert!(val > u8::MAX.into()); // must be an error
assert!(val.get() > u8::MAX.into()); // must be an error
dcx.emit_err(ConcatBytesOob { span });
}
Ok(ast::LitKind::Int(_, _)) => {
@ -86,7 +86,7 @@ fn handle_array_element(
Ok(ast::LitKind::Int(
val,
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
)) if val <= u8::MAX.into() => Some(val as u8),
)) if val.get() <= u8::MAX.into() => Some(val.get() as u8),
Ok(ast::LitKind::Byte(val)) => Some(val),
Ok(ast::LitKind::ByteStr(..)) => {
@ -148,7 +148,7 @@ pub fn expand_concat_bytes(
if let Some(elem) =
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
{
for _ in 0..count_val {
for _ in 0..count_val.get() {
accumulator.push(elem);
}
}

View file

@ -529,7 +529,7 @@ fn make_format_args(
// Only check for unused named argument names if there are no other errors to avoid causing
// too much noise in output errors, such as when a named argument is entirely unused.
if invalid_refs.is_empty() && ecx.dcx().err_count() == 0 {
if invalid_refs.is_empty() && ecx.dcx().has_errors().is_none() {
for &(index, span, used_as) in &numeric_refences_to_named_arg {
let (position_sp_to_replace, position_sp_for_msg) = match used_as {
Placeholder(pspan) => (span, pspan),

View file

@ -325,7 +325,7 @@ codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)
codegen_ssa_version_script_write_failure = failed to write version script: {$error}

View file

@ -563,7 +563,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
if codegen_fn_attrs.inline == InlineAttr::Always {
if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) {
let hir_id = tcx.local_def_id_to_hir_id(did);
tcx.struct_span_lint_hir(
tcx.node_span_lint(
lint::builtin::INLINE_NO_SANITIZE,
hir_id,
no_sanitize_span,
@ -658,7 +658,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
// if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment
// about LINK.EXE failing.)
if *ordinal <= u16::MAX as u128 {
Some(*ordinal as u16)
Some(ordinal.get() as u16)
} else {
let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal);
tcx.dcx()

View file

@ -175,7 +175,7 @@ pub(super) fn lint<'tcx, 'mir, L>(
{
let (span, frames) = get_span_and_frames(tcx, machine);
tcx.emit_spanned_lint(
tcx.emit_node_span_lint(
lint,
// We use the root frame for this so the crate that defines the const defines whether the
// lint is emitted.

View file

@ -611,7 +611,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
.0
.is_error();
let span = ecx.cur_span();
ecx.tcx.emit_spanned_lint(
ecx.tcx.emit_node_span_lint(
rustc_session::lint::builtin::LONG_RUNNING_CONST_EVAL,
hir_id,
span,

View file

@ -796,7 +796,67 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
}
match rvalue {
Rvalue::Use(_) | Rvalue::CopyForDeref(_) | Rvalue::Aggregate(..) => {}
Rvalue::Use(_) | Rvalue::CopyForDeref(_) => {}
Rvalue::Aggregate(kind, fields) => match **kind {
AggregateKind::Tuple => {}
AggregateKind::Array(dest) => {
for src in fields {
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
self.fail(location, "array field has the wrong type");
}
}
}
AggregateKind::Adt(def_id, idx, args, _, Some(field)) => {
let adt_def = self.tcx.adt_def(def_id);
assert!(adt_def.is_union());
assert_eq!(idx, FIRST_VARIANT);
let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args);
if fields.len() != 1 {
self.fail(location, "unions should have one initialized field");
}
if !self.mir_assign_valid_types(fields.raw[0].ty(self.body, self.tcx), dest) {
self.fail(location, "union field has the wrong type");
}
}
AggregateKind::Adt(def_id, idx, args, _, None) => {
let adt_def = self.tcx.adt_def(def_id);
assert!(!adt_def.is_union());
let variant = &adt_def.variants()[idx];
if variant.fields.len() != fields.len() {
self.fail(location, "adt has the wrong number of initialized fields");
}
for (src, dest) in std::iter::zip(fields, &variant.fields) {
if !self.mir_assign_valid_types(
src.ty(self.body, self.tcx),
dest.ty(self.tcx, args),
) {
self.fail(location, "adt field has the wrong type");
}
}
}
AggregateKind::Closure(_, args) => {
let upvars = args.as_closure().upvar_tys();
if upvars.len() != fields.len() {
self.fail(location, "closure has the wrong number of initialized fields");
}
for (src, dest) in std::iter::zip(fields, upvars) {
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
self.fail(location, "closure field has the wrong type");
}
}
}
AggregateKind::Coroutine(_, args) => {
let upvars = args.as_coroutine().upvar_tys();
if upvars.len() != fields.len() {
self.fail(location, "coroutine has the wrong number of initialized fields");
}
for (src, dest) in std::iter::zip(fields, upvars) {
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
self.fail(location, "coroutine field has the wrong type");
}
}
}
},
Rvalue::Ref(_, BorrowKind::Fake, _) => {
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(

View file

@ -93,6 +93,7 @@ pub mod aligned;
pub mod frozen;
mod hashes;
pub mod owned_slice;
pub mod packed;
pub mod sso;
pub mod steal;
pub mod tagged_ptr;

View file

@ -0,0 +1,71 @@
use crate::stable_hasher::{HashStable, StableHasher};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::cmp::Ordering;
use std::fmt;
#[repr(packed(8))]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Pu128(pub u128);
impl Pu128 {
#[inline]
pub fn get(self) -> u128 {
self.0
}
}
impl From<u128> for Pu128 {
#[inline]
fn from(value: u128) -> Self {
Self(value)
}
}
impl PartialEq<u128> for Pu128 {
#[inline]
fn eq(&self, other: &u128) -> bool {
({ self.0 }) == *other
}
}
impl PartialOrd<u128> for Pu128 {
#[inline]
fn partial_cmp(&self, other: &u128) -> Option<Ordering> {
{ self.0 }.partial_cmp(other)
}
}
impl fmt::Display for Pu128 {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
{ self.0 }.fmt(f)
}
}
impl fmt::UpperHex for Pu128 {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
{ self.0 }.fmt(f)
}
}
impl<CTX> HashStable<CTX> for Pu128 {
#[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
{ self.0 }.hash_stable(ctx, hasher)
}
}
impl<S: Encoder> Encodable<S> for Pu128 {
#[inline]
fn encode(&self, s: &mut S) {
{ self.0 }.encode(s);
}
}
impl<D: Decoder> Decodable<D> for Pu128 {
#[inline]
fn decode(d: &mut D) -> Self {
Self(u128::decode(d))
}
}

View file

@ -110,6 +110,14 @@ impl IntoDiagnosticArg for char {
}
}
impl IntoDiagnosticArg for Vec<char> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::StrListSepByAnd(
self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(),
)
}
}
impl IntoDiagnosticArg for Symbol {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
self.to_ident_string().into_diagnostic_arg()

View file

@ -421,16 +421,16 @@ pub struct DiagCtxt {
struct DiagCtxtInner {
flags: DiagCtxtFlags,
/// The number of lint errors that have been emitted.
/// The number of lint errors that have been emitted, including duplicates.
lint_err_count: usize,
/// The number of errors that have been emitted, including duplicates.
///
/// This is not necessarily the count that's reported to the user once
/// compilation ends.
/// The number of non-lint errors that have been emitted, including duplicates.
err_count: usize,
/// The error count shown to the user at the end.
deduplicated_err_count: usize,
/// The warning count, used for a recap upon finishing
/// The warning count shown to the user at the end.
deduplicated_warn_count: usize,
/// Has this diagnostic context printed any diagnostics? (I.e. has
/// `self.emitter.emit_diagnostic()` been called?
has_printed: bool,
@ -927,11 +927,13 @@ impl DiagCtxt {
self.struct_bug(msg).emit()
}
/// This excludes lint errors and delayed bugs.
#[inline]
pub fn err_count(&self) -> usize {
self.inner.borrow().err_count
}
/// This excludes lint errors and delayed bugs.
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
self.inner.borrow().has_errors().then(|| {
#[allow(deprecated)]
@ -939,30 +941,24 @@ impl DiagCtxt {
})
}
/// This excludes delayed bugs. Unless absolutely necessary, prefer
/// `has_errors` to this method.
pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
let inner = self.inner.borrow();
let has_errors_or_lint_errors = inner.has_errors() || inner.lint_err_count > 0;
has_errors_or_lint_errors.then(|| {
let result = inner.has_errors() || inner.lint_err_count > 0;
result.then(|| {
#[allow(deprecated)]
ErrorGuaranteed::unchecked_claim_error_was_emitted()
})
}
pub fn has_errors_or_span_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
/// Unless absolutely necessary, prefer `has_errors` or
/// `has_errors_or_lint_errors` to this method.
pub fn has_errors_or_lint_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
let inner = self.inner.borrow();
let has_errors_or_span_delayed_bugs =
inner.has_errors() || !inner.span_delayed_bugs.is_empty();
has_errors_or_span_delayed_bugs.then(|| {
#[allow(deprecated)]
ErrorGuaranteed::unchecked_claim_error_was_emitted()
})
}
pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> {
let inner = self.inner.borrow();
let will_fail =
let result =
inner.has_errors() || inner.lint_err_count > 0 || !inner.span_delayed_bugs.is_empty();
will_fail.then(|| {
result.then(|| {
#[allow(deprecated)]
ErrorGuaranteed::unchecked_claim_error_was_emitted()
})
@ -1162,7 +1158,7 @@ impl DiagCtxt {
let mut inner = self.inner.borrow_mut();
if loud && lint_level.is_error() {
inner.err_count += 1;
inner.lint_err_count += 1;
inner.panic_if_treat_err_as_bug();
}

View file

@ -124,7 +124,7 @@ fn parse_depth<'sess>(
};
if let Ok(lit_kind) = LitKind::from_token_lit(*lit)
&& let LitKind::Int(n_u128, LitIntType::Unsuffixed) = lit_kind
&& let Ok(n_usize) = usize::try_from(n_u128)
&& let Ok(n_usize) = usize::try_from(n_u128.get())
{
Ok(n_usize)
} else {

View file

@ -339,9 +339,6 @@ declare_features! (
/// Allows `#[track_caller]` to be used which provides
/// accurate caller location reporting during panic (RFC 2091).
(accepted, track_caller, "1.46.0", Some(47809)),
/// Allows dyn upcasting trait objects via supertraits.
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
(accepted, trait_upcasting, "1.76.0", Some(65991)),
/// Allows #[repr(transparent)] on univariant enums (RFC 2645).
(accepted, transparent_enums, "1.42.0", Some(60405)),
/// Allows indexing tuples.

View file

@ -584,6 +584,9 @@ declare_features! (
(unstable, thread_local, "1.0.0", Some(29594)),
/// Allows defining `trait X = A + B;` alias items.
(unstable, trait_alias, "1.24.0", Some(41517)),
/// Allows dyn upcasting trait objects via supertraits.
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
(unstable, trait_upcasting, "1.56.0", Some(65991)),
/// Allows for transmuting between arrays with sizes that contain generic consts.
(unstable, transmute_generic_consts, "1.70.0", Some(109929)),
/// Allows #[repr(transparent)] on unions (RFC 2645).

View file

@ -213,8 +213,11 @@ language_item_table! {
Iterator, sym::iterator, iterator_trait, Target::Trait, GenericRequirement::Exact(0);
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
AsyncIterator, sym::async_iterator, async_iterator_trait, Target::Trait, GenericRequirement::Exact(0);
CoroutineState, sym::coroutine_state, coroutine_state, Target::Enum, GenericRequirement::None;
Coroutine, sym::coroutine, coroutine_trait, Target::Trait, GenericRequirement::Minimum(1);
CoroutineResume, sym::coroutine_resume, coroutine_resume, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None;
Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None;

View file

@ -329,7 +329,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}
let projection_ty = if let ty::AssocKind::Fn = assoc_kind {
let mut emitted_bad_param_err = false;
let mut emitted_bad_param_err = None;
// If we have an method return type bound, then we need to substitute
// the method's early bound params with suitable late-bound params.
let mut num_bound_vars = candidate.bound_vars().len();
@ -346,46 +346,30 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
)
.into(),
ty::GenericParamDefKind::Type { .. } => {
if !emitted_bad_param_err {
let guar = *emitted_bad_param_err.get_or_insert_with(|| {
tcx.dcx().emit_err(
crate::errors::ReturnTypeNotationIllegalParam::Type {
span: path_span,
param_span: tcx.def_span(param.def_id),
},
);
emitted_bad_param_err = true;
}
Ty::new_bound(
tcx,
ty::INNERMOST,
ty::BoundTy {
var: ty::BoundVar::from_usize(num_bound_vars),
kind: ty::BoundTyKind::Param(param.def_id, param.name),
},
)
.into()
)
});
Ty::new_error(tcx, guar).into()
}
ty::GenericParamDefKind::Const { .. } => {
if !emitted_bad_param_err {
let guar = *emitted_bad_param_err.get_or_insert_with(|| {
tcx.dcx().emit_err(
crate::errors::ReturnTypeNotationIllegalParam::Const {
span: path_span,
param_span: tcx.def_span(param.def_id),
},
);
emitted_bad_param_err = true;
}
)
});
let ty = tcx
.type_of(param.def_id)
.no_bound_vars()
.expect("ct params cannot have early bound vars");
ty::Const::new_bound(
tcx,
ty::INNERMOST,
ty::BoundVar::from_usize(num_bound_vars),
ty,
)
.into()
ty::Const::new_error(tcx, guar, ty).into()
}
};
num_bound_vars += 1;

View file

@ -656,7 +656,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
} else {
let mut multispan = MultiSpan::from_span(span);
multispan.push_span_label(span_late, note);
tcx.struct_span_lint_hir(
tcx.node_span_lint(
LATE_BOUND_LIFETIME_ARGUMENTS,
args.args[0].hir_id(),
multispan,

View file

@ -94,15 +94,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return false;
};
let impl_sugg = vec![(self_ty.span.shrink_to_lo(), "impl ".to_string())];
let mut is_downgradable = true;
let is_object_safe = match self_ty.kind {
hir::TyKind::TraitObject(objects, ..) => {
objects.iter().all(|o| match o.trait_ref.path.res {
Res::Def(DefKind::Trait, id) if Some(id) == owner => {
// When we're dealing with a recursive trait, we don't want to downgrade
// the error, so we consider them to be object safe always. (#119652)
true
Res::Def(DefKind::Trait, id) => {
if Some(id) == owner {
// For recursive traits, don't downgrade the error. (#119652)
is_downgradable = false;
}
tcx.check_is_object_safe(id)
}
Res::Def(DefKind::Trait, id) => tcx.check_is_object_safe(id),
_ => false,
})
}
@ -130,7 +132,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
],
Applicability::MachineApplicable,
);
} else if diag.is_error() {
} else if diag.is_error() && is_downgradable {
// We'll emit the object safety error already, with a structured suggestion.
diag.downgrade_to_delayed_bug();
}
@ -156,7 +158,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
if !is_object_safe {
diag.note(format!("`{trait_name}` it is not object safe, so it can't be `dyn`"));
if diag.is_error() {
if diag.is_error() && is_downgradable {
// We'll emit the object safety error already, with a structured suggestion.
diag.downgrade_to_delayed_bug();
}
@ -238,24 +240,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
} else {
let msg = "trait objects without an explicit `dyn` are deprecated";
tcx.struct_span_lint_hir(
BARE_TRAIT_OBJECTS,
self_ty.hir_id,
self_ty.span,
msg,
|lint| {
if self_ty.span.can_be_used_for_suggestions()
&& !self.maybe_lint_impl_trait(self_ty, lint)
{
lint.multipart_suggestion_verbose(
"use `dyn`",
sugg,
Applicability::MachineApplicable,
);
}
self.maybe_lint_blanket_trait_impl(self_ty, lint);
},
);
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
if self_ty.span.can_be_used_for_suggestions()
&& !self.maybe_lint_impl_trait(self_ty, lint)
{
lint.multipart_suggestion_verbose(
"use `dyn`",
sugg,
Applicability::MachineApplicable,
);
}
self.maybe_lint_blanket_trait_impl(self_ty, lint);
});
}
}
}

View file

@ -1394,7 +1394,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let ty = self.projected_ty_from_poly_trait_ref(span, assoc_ty_did, assoc_segment, bound);
if let Some(variant_def_id) = variant_resolution {
tcx.struct_span_lint_hir(
tcx.node_span_lint(
AMBIGUOUS_ASSOCIATED_ITEMS,
hir_ref_id,
span,

View file

@ -220,7 +220,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let def_id = projection_bound.projection_def_id();
def_ids.remove(&def_id);
if tcx.generics_require_sized_self(def_id) {
tcx.emit_spanned_lint(
tcx.emit_node_span_lint(
UNUSED_ASSOCIATED_TYPE_BOUNDS,
hir_id,
*span,

View file

@ -46,7 +46,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
.emit();
}
None => {
tcx.struct_span_lint_hir(
tcx.node_span_lint(
UNSUPPORTED_CALLING_CONVENTIONS,
hir_id,
span,
@ -183,7 +183,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
}
};
if layout.abi.is_uninhabited() {
tcx.struct_span_lint_hir(
tcx.node_span_lint(
UNINHABITED_STATIC,
tcx.local_def_id_to_hir_id(def_id),
span,
@ -1079,7 +1079,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
// If there are any non-trivial fields, then there can be no non-exhaustive 1-zsts.
// Otherwise, it's only an issue if there's >1 non-exhaustive 1-zst.
if non_trivial_count > 0 || prev_non_exhaustive_1zst {
tcx.struct_span_lint_hir(
tcx.node_span_lint(
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
tcx.local_def_id_to_hir_id(adt.did().expect_local()),
span,

View file

@ -283,7 +283,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
});
let span = unmatched_bound.unwrap_or(span);
tcx.emit_spanned_lint(
tcx.emit_node_span_lint(
REFINING_IMPL_TRAIT,
tcx.local_def_id_to_hir_id(impl_m_def_id.expect_local()),
span,

View file

@ -88,7 +88,7 @@ fn handle_static_mut_ref(
"shared ",
)
};
tcx.emit_spanned_lint(
tcx.emit_node_span_lint(
STATIC_MUT_REF,
hir_id,
span,

View file

@ -270,7 +270,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
if !spans.is_empty() {
let (default_modifier, default_result) =
reg_class.default_modifier(asm_arch).unwrap();
self.tcx.struct_span_lint_hir(
self.tcx.node_span_lint(
lint::builtin::ASM_SUB_REGISTER,
expr.hir_id,
spans,

View file

@ -116,7 +116,7 @@ where
let errors = wfcx.select_all_or_error();
if !errors.is_empty() {
let err = infcx.err_ctxt().report_fulfillment_errors(errors);
if tcx.dcx().err_count() > 0 {
if tcx.dcx().has_errors().is_some() {
return Err(err);
} else {
// HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs

View file

@ -40,12 +40,6 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
} else {
"unused import".to_owned()
};
tcx.struct_span_lint_hir(
lint::builtin::UNUSED_IMPORTS,
item.hir_id(),
path.span,
msg,
|_| {},
);
tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, msg, |_| {});
}
}

View file

@ -495,7 +495,7 @@ fn lint_auto_trait_impl<'tcx>(
return;
}
tcx.struct_span_lint_hir(
tcx.node_span_lint(
lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
tcx.local_def_id_to_hir_id(impl_def_id),
tcx.def_span(impl_def_id),

View file

@ -274,7 +274,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
Defaults::FutureCompatDisallowed
if tcx.features().default_type_parameter_fallback => {}
Defaults::FutureCompatDisallowed => {
tcx.struct_span_lint_hir(
tcx.node_span_lint(
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
param.hir_id,
param.span,

View file

@ -912,7 +912,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
continue;
}
self.insert_lifetime(lt, ResolvedArg::StaticLifetime);
self.tcx.struct_span_lint_hir(
self.tcx.node_span_lint(
lint::builtin::UNUSED_LIFETIMES,
lifetime.hir_id,
lifetime.ident.span,

View file

@ -587,7 +587,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
};
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
fcx.tcx.emit_spanned_lint(
fcx.tcx.emit_node_span_lint(
lint,
self.expr.hir_id,
self.span,
@ -900,7 +900,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
fcx.tcx.emit_spanned_lint(
fcx.tcx.emit_node_span_lint(
lint::builtin::CENUM_IMPL_DROP_CAST,
self.expr.hir_id,
self.span,
@ -934,7 +934,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
};
let lint = errors::LossyProvenancePtr2Int { expr_ty, cast_ty, sugg };
fcx.tcx.emit_spanned_lint(
fcx.tcx.emit_node_span_lint(
lint::builtin::LOSSY_PROVENANCE_CASTS,
self.expr.hir_id,
self.span,
@ -950,7 +950,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
let lint = errors::LossyProvenanceInt2Ptr { expr_ty, cast_ty, sugg };
fcx.tcx.emit_spanned_lint(
fcx.tcx.emit_node_span_lint(
lint::builtin::FUZZY_PROVENANCE_CASTS,
self.expr.hir_id,
self.span,

View file

@ -2,8 +2,7 @@ use std::cell::RefCell;
use crate::coercion::CoerceMany;
use crate::gather_locals::GatherLocalsVisitor;
use crate::CoroutineTypes;
use crate::FnCtxt;
use crate::{CoroutineTypes, Diverges, FnCtxt};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::intravisit::Visitor;
@ -76,6 +75,12 @@ pub(super) fn check_fn<'a, 'tcx>(
let ty: Option<&hir::Ty<'_>> = try { inputs_hir?.get(idx)? };
let ty_span = ty.map(|ty| ty.span);
fcx.check_pat_top(param.pat, param_ty, ty_span, None, None);
if param.pat.is_never_pattern() {
fcx.function_diverges_because_of_empty_arguments.set(Diverges::Always {
span: param.pat.span,
custom_note: Some("any code following a never pattern is unreachable"),
});
}
// Check that argument is Sized.
if !params_can_be_unsized {
@ -105,6 +110,7 @@ pub(super) fn check_fn<'a, 'tcx>(
hir::FnRetTy::Return(ty) => ty.span,
};
fcx.require_type_is_sized(declared_ret_ty, return_or_body_span, traits::SizedReturnType);
fcx.is_whole_body.set(true);
fcx.check_return_expr(body.value, false);
// Finalize the return check by taking the LUB of the return types

View file

@ -625,6 +625,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
)];
let mut has_unsized_tuple_coercion = false;
let mut has_trait_upcasting_coercion = None;
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
@ -692,6 +693,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// these here and emit a feature error if coercion doesn't fail
// due to another reason.
match impl_source {
traits::ImplSource::Builtin(
BuiltinImplSource::TraitUpcasting { .. },
_,
) => {
has_trait_upcasting_coercion =
Some((trait_pred.self_ty(), trait_pred.trait_ref.args.type_at(1)));
}
traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
has_unsized_tuple_coercion = true;
}
@ -702,6 +710,21 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
}
}
if let Some((sub, sup)) = has_trait_upcasting_coercion
&& !self.tcx().features().trait_upcasting
{
// Renders better when we erase regions, since they're not really the point here.
let (sub, sup) = self.tcx.erase_regions((sub, sup));
let mut err = feature_err(
&self.tcx.sess,
sym::trait_upcasting,
self.cause.span,
format!("cannot cast `{sub}` to `{sup}`, trait upcasting coercion is experimental"),
);
err.note(format!("required when coercing `{source}` into `{target}`"));
err.emit();
}
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
feature_err(
&self.tcx.sess,

View file

@ -208,10 +208,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// without the final expr (e.g. `try { return; }`). We don't want to generate an
// unreachable_code lint for it since warnings for autogenerated code are confusing.
let is_try_block_generated_unit_expr = match expr.kind {
ExprKind::Call(_, args) if expr.span.is_desugaring(DesugaringKind::TryBlock) => {
args.len() == 1 && args[0].span.is_desugaring(DesugaringKind::TryBlock)
ExprKind::Call(_, [arg]) => {
expr.span.is_desugaring(DesugaringKind::TryBlock)
&& arg.span.is_desugaring(DesugaringKind::TryBlock)
}
_ => false,
};
@ -220,9 +220,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
}
// Hide the outer diverging and has_errors flags.
// Whether a past expression diverges doesn't affect typechecking of this expression, so we
// reset `diverges` while checking `expr`.
let old_diverges = self.diverges.replace(Diverges::Maybe);
if self.is_whole_body.replace(false) {
// If this expression is the whole body and the function diverges because of its
// arguments, we check this here to ensure the body is considered to diverge.
self.diverges.set(self.function_diverges_because_of_empty_arguments.get())
};
let ty = ensure_sufficient_stack(|| match &expr.kind {
hir::ExprKind::Path(
qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),
@ -2981,10 +2988,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// fixed expression:
if let ExprKind::Lit(lit) = idx.kind
&& let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node
&& i < types
.len()
.try_into()
.expect("expected tuple index to be < usize length")
&& i.get()
< types
.len()
.try_into()
.expect("expected tuple index to be < usize length")
{
err.span_suggestion(
brackets_span,

View file

@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
let msg = format!("unreachable {kind}");
self.tcx().struct_span_lint_hir(
self.tcx().node_span_lint(
lint::builtin::UNREACHABLE_CODE,
id,
span,

View file

@ -1471,6 +1471,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Type check a `let` statement.
pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
self.check_decl(local.into());
if local.pat.is_never_pattern() {
self.diverges.set(Diverges::Always {
span: local.pat.span,
custom_note: Some("any code following a never pattern is unreachable"),
});
}
}
pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {

View file

@ -103,6 +103,13 @@ pub struct FnCtxt<'a, 'tcx> {
/// the diverges flag is set to something other than `Maybe`.
pub(super) diverges: Cell<Diverges>,
/// If one of the function arguments is a never pattern, this counts as diverging code. This
/// affect typechecking of the function body.
pub(super) function_diverges_because_of_empty_arguments: Cell<Diverges>,
/// Whether the currently checked node is the whole body of the function.
pub(super) is_whole_body: Cell<bool>,
pub(super) enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
pub(super) inh: &'a Inherited<'tcx>,
@ -124,6 +131,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ret_coercion_span: Cell::new(None),
coroutine_types: None,
diverges: Cell::new(Diverges::Maybe),
function_diverges_because_of_empty_arguments: Cell::new(Diverges::Maybe),
is_whole_body: Cell::new(false),
enclosing_breakables: RefCell::new(EnclosingBreakables {
stack: Vec::new(),
by_id: Default::default(),

View file

@ -11,6 +11,7 @@ use crate::ty::TypeAndMut;
use core::cmp::min;
use core::iter;
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
use rustc_data_structures::packed::Pu128;
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::Res;
@ -1409,8 +1410,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
let (_, suffix) = snippet.split_at(snippet.len() - 3);
let value = match suffix {
"f32" => (lit - 0xf32) / (16 * 16 * 16),
"f64" => (lit - 0xf64) / (16 * 16 * 16),
"f32" => (lit.get() - 0xf32) / (16 * 16 * 16),
"f64" => (lit.get() - 0xf64) / (16 * 16 * 16),
_ => return false,
};
err.span_suggestions(
@ -1440,7 +1441,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
// Provided expression needs to be a literal `0`.
let ExprKind::Lit(Spanned { node: rustc_ast::LitKind::Int(0, _), span }) = expr.kind else {
let ExprKind::Lit(Spanned { node: rustc_ast::LitKind::Int(Pu128(0), _), span }) = expr.kind
else {
return false;
};

View file

@ -77,7 +77,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Inherent impls only require not relying on autoref and autoderef in order to
// ensure that the trait implementation won't be used
self.tcx.struct_span_lint_hir(
self.tcx.node_span_lint(
prelude_or_array_lint,
self_expr.hir_id,
self_expr.span,
@ -127,7 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
// trait implementations require full disambiguation to not clash with the new prelude
// additions (i.e. convert from dot-call to fully-qualified call)
self.tcx.struct_span_lint_hir(
self.tcx.node_span_lint(
prelude_or_array_lint,
call_expr.hir_id,
call_expr.span,
@ -238,7 +238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return;
}
self.tcx.struct_span_lint_hir(
self.tcx.node_span_lint(
RUST_2021_PRELUDE_COLLISIONS,
expr_id,
span,

View file

@ -440,7 +440,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if self.tcx.sess.at_least_rust_2018() {
self.dcx().emit_err(MethodCallOnUnknownRawPointee { span });
} else {
self.tcx.struct_span_lint_hir(
self.tcx.node_span_lint(
lint::builtin::TYVAR_BEHIND_RAW_POINTER,
scope_expr_id,
span,
@ -1380,7 +1380,7 @@ impl<'tcx> Pick<'tcx> {
return;
}
let def_kind = self.item.kind.as_def_kind();
tcx.struct_span_lint_hir(
tcx.node_span_lint(
lint::builtin::UNSTABLE_NAME_COLLISIONS,
scope_expr_id,
span,

View file

@ -4,6 +4,7 @@ use super::method::MethodCallee;
use super::{has_expected_num_generic_args, FnCtxt};
use crate::Expectation;
use rustc_ast as ast;
use rustc_data_structures::packed::Pu128;
use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@ -834,7 +835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Expr {
kind:
hir::ExprKind::Lit(Spanned {
node: ast::LitKind::Int(1, _),
node: ast::LitKind::Int(Pu128(1), _),
..
}),
..

View file

@ -1840,7 +1840,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(),
);
self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| {
self.tcx.node_span_lint(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| {
lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns));
lint.help(
"ensure that all fields are mentioned explicitly by adding the suggested fields",

View file

@ -754,7 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let closure_hir_id = self.tcx.local_def_id_to_hir_id(closure_def_id);
let closure_head_span = self.tcx.def_span(closure_def_id);
self.tcx.struct_span_lint_hir(
self.tcx.node_span_lint(
lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
closure_hir_id,
closure_head_span,

View file

@ -312,7 +312,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) {
let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone();
if let Some(_) = sess.dcx().has_errors_or_span_delayed_bugs() {
if sess.dcx().has_errors_or_lint_errors_or_delayed_bugs().is_some() {
// If there have been any errors during compilation, we don't want to
// publish this session directory. Rather, we'll just delete it.

View file

@ -31,8 +31,8 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) {
if sess.opts.incremental.is_none() {
return;
}
// This is going to be deleted in finalize_session_directory, so let's not create it
if let Some(_) = sess.dcx().has_errors_or_span_delayed_bugs() {
// This is going to be deleted in finalize_session_directory, so let's not create it.
if sess.dcx().has_errors_or_lint_errors_or_delayed_bugs().is_some() {
return;
}
@ -87,7 +87,7 @@ pub fn save_work_product_index(
return;
}
// This is going to be deleted in finalize_session_directory, so let's not create it
if let Some(_) = sess.dcx().has_errors_or_span_delayed_bugs() {
if sess.dcx().has_errors_or_lint_errors().is_some() {
return;
}

View file

@ -117,9 +117,9 @@ fn escape_literal(s: &str) -> String {
/// field is only populated during an in-progress typeck.
/// Get an instance by calling `InferCtxt::err_ctxt` or `FnCtxt::err_ctxt`.
///
/// You must only create this if you intend to actually emit an error.
/// This provides a lot of utility methods which should not be used
/// during the happy path.
/// You must only create this if you intend to actually emit an error (or
/// perhaps a warning, though preferably not.) It provides a lot of utility
/// methods which should not be used during the happy path.
pub struct TypeErrCtxt<'a, 'tcx> {
pub infcx: &'a InferCtxt<'tcx>,
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
@ -133,9 +133,10 @@ pub struct TypeErrCtxt<'a, 'tcx> {
impl Drop for TypeErrCtxt<'_, '_> {
fn drop(&mut self) {
if let Some(_) = self.dcx().has_errors_or_span_delayed_bugs() {
// ok, emitted an error.
if self.dcx().has_errors().is_some() {
// Ok, emitted an error.
} else {
// Didn't emit an error; maybe it was created but not yet emitted.
self.infcx
.tcx
.sess

View file

@ -165,9 +165,9 @@ impl<'tcx> InferCtxt<'tcx> {
//
// This probe is probably not strictly necessary but it seems better to be safe and not accidentally find
// ourselves with a check to find bugs being required for code to compile because it made inference progress.
let compatible_types = self.probe(|_| {
self.probe(|_| {
if a.ty() == b.ty() {
return Ok(());
return;
}
// We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the
@ -177,32 +177,18 @@ impl<'tcx> InferCtxt<'tcx> {
relation.param_env().and((a.ty(), b.ty())),
&mut OriginalQueryValues::default(),
);
self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
self.tcx.check_tys_might_be_eq(canonical).unwrap_or_else(|_| {
// The error will only be reported later. If we emit an ErrorGuaranteed
// here, then we will never get to the code that actually emits the error.
self.tcx.dcx().delayed_bug(format!(
"cannot relate consts of different types (a={a:?}, b={b:?})",
))
})
));
// We treat these constants as if they were of the same type, so that any
// such constants being used in impls make these impls match barring other mismatches.
// This helps with diagnostics down the road.
});
});
// If the consts have differing types, just bail with a const error with
// the expected const's type. Specifically, we don't want const infer vars
// to do any type shapeshifting before and after resolution.
if let Err(guar) = compatible_types {
// HACK: equating both sides with `[const error]` eagerly prevents us
// from leaving unconstrained inference vars during things like impl
// matching in the solver.
let a_error = ty::Const::new_error(self.tcx, guar, a.ty());
if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
return self.unify_const_variable(vid, a_error, relation.param_env());
}
let b_error = ty::Const::new_error(self.tcx, guar, b.ty());
if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
return self.unify_const_variable(vid, b_error, relation.param_env());
}
return Ok(if relation.a_is_expected() { a_error } else { b_error });
}
match (a.kind(), b.kind()) {
(
ty::ConstKind::Infer(InferConst::Var(a_vid)),

View file

@ -98,6 +98,7 @@ fn assert_same_hash(x: &Options, y: &Options) {
assert_same_clone(y);
}
#[track_caller]
fn assert_different_hash(x: &Options, y: &Options) {
assert_ne!(x.dep_tracking_hash(true), y.dep_tracking_hash(true));
assert_ne!(x.dep_tracking_hash(false), y.dep_tracking_hash(false));
@ -713,7 +714,6 @@ fn test_unstable_options_tracking_hash() {
untracked!(unpretty, Some("expanded".to_string()));
untracked!(unstable_options, true);
untracked!(validate_mir, true);
untracked!(verbose_internals, true);
untracked!(write_long_types_to_disk, false);
// tidy-alphabetical-end
@ -845,6 +845,7 @@ fn test_unstable_options_tracking_hash() {
};
}
tracked_no_crate_hash!(no_codegen, true);
tracked_no_crate_hash!(verbose_internals, true);
}
#[test]

View file

@ -20,8 +20,9 @@
//! [`rustc_parse::lexer`]: ../rustc_parse/lexer/index.html
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
// We want to be able to build this crate with a stable compiler, so no
// `#![feature]` attributes should be added.
// We want to be able to build this crate with a stable compiler,
// so no `#![feature]` attributes should be added.
#![deny(unstable_features)]
mod cursor;
pub mod unescape;

View file

@ -148,7 +148,7 @@ lint_builtin_unsafe_impl = implementation of an `unsafe` trait
lint_builtin_unsafe_trait = declaration of an `unsafe` trait
lint_builtin_unstable_features = unstable feature
lint_builtin_unstable_features = use of an unstable feature
lint_builtin_unused_doc_comment = unused doc comment
.label = rustdoc does not generate documentation for {$kind}
@ -240,7 +240,10 @@ lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of
lint_identifier_non_ascii_char = identifier contains non-ASCII characters
lint_identifier_uncommon_codepoints = identifier contains uncommon Unicode codepoints
lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len ->
[one] an uncommon Unicode codepoint
*[other] uncommon Unicode codepoints
}: {$codepoints}
lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level
@ -345,6 +348,9 @@ lint_multiple_supertrait_upcastable = `{$ident}` is object-safe and has multiple
lint_node_source = `forbid` level set here
.note = {$reason}
lint_non_binding_let_multi_drop_fn =
consider immediately dropping the value using `drop(..)` after the `let` statement
lint_non_binding_let_multi_suggestion =
consider immediately dropping the value

View file

@ -132,7 +132,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
} else {
None
};
cx.emit_spanned_lint(
cx.emit_span_lint(
ARRAY_INTO_ITER,
call.ident.span,
ArrayIntoIterDiag { target, suggestion: call.ident.span, sub },

View file

@ -116,7 +116,7 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait {
def.owner_id.def_id,
" + Send",
);
cx.tcx.emit_spanned_lint(
cx.tcx.emit_node_span_lint(
ASYNC_FN_IN_TRAIT,
item.hir_id(),
async_span,

View file

@ -121,7 +121,7 @@ impl EarlyLintPass for WhileTrue {
"{}loop",
label.map_or_else(String::new, |label| format!("{}: ", label.ident,))
);
cx.emit_spanned_lint(
cx.emit_span_lint(
WHILE_TRUE,
condition_span,
BuiltinWhileTrue { suggestion: condition_span, replace },
@ -162,7 +162,7 @@ impl BoxPointers {
if let GenericArgKind::Type(leaf_ty) = leaf.unpack()
&& leaf_ty.is_box()
{
cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty });
cx.emit_span_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty });
}
}
}
@ -265,7 +265,7 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
if cx.tcx.find_field_index(ident, variant)
== Some(cx.typeck_results().field_index(fieldpat.hir_id))
{
cx.emit_spanned_lint(
cx.emit_span_lint(
NON_SHORTHAND_FIELD_PATTERNS,
fieldpat.span,
BuiltinNonShorthandFieldPatterns {
@ -334,7 +334,7 @@ impl UnsafeCode {
return;
}
cx.emit_spanned_lint(UNSAFE_CODE, span, decorate);
cx.emit_span_lint(UNSAFE_CODE, span, decorate);
}
}
@ -509,7 +509,7 @@ impl MissingDoc {
let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id));
let has_doc = attrs.iter().any(has_doc);
if !has_doc {
cx.emit_spanned_lint(
cx.emit_span_lint(
MISSING_DOCS,
cx.tcx.def_span(def_id),
BuiltinMissingDoc { article, desc },
@ -710,7 +710,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
)
.is_ok()
{
cx.emit_spanned_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, BuiltinMissingCopyImpl);
cx.emit_span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, BuiltinMissingCopyImpl);
}
}
}
@ -795,7 +795,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
.next()
.is_some();
if !has_impl {
cx.emit_spanned_lint(
cx.emit_span_lint(
MISSING_DEBUG_IMPLEMENTATIONS,
item.span,
BuiltinMissingDebugImpl { tcx: cx.tcx, def_id: debug },
@ -874,7 +874,7 @@ impl EarlyLintPass for AnonymousParameters {
} else {
("<type>", Applicability::HasPlaceholders)
};
cx.emit_spanned_lint(
cx.emit_span_lint(
ANONYMOUS_PARAMETERS,
arg.pat.span,
BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip },
@ -921,7 +921,7 @@ impl EarlyLintPass for DeprecatedAttr {
BuiltinDeprecatedAttrLinkSuggestion::Default { suggestion: attr.span }
}
};
cx.emit_spanned_lint(
cx.emit_span_lint(
DEPRECATED,
attr.span,
BuiltinDeprecatedAttrLink { name, reason, link, suggestion },
@ -931,7 +931,7 @@ impl EarlyLintPass for DeprecatedAttr {
}
}
if attr.has_name(sym::no_start) || attr.has_name(sym::crate_id) {
cx.emit_spanned_lint(
cx.emit_span_lint(
DEPRECATED,
attr.span,
BuiltinDeprecatedAttrUsed {
@ -973,7 +973,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
BuiltinUnusedDocCommentSub::BlockHelp
}
};
cx.emit_spanned_lint(
cx.emit_span_lint(
UNUSED_DOC_COMMENTS,
span,
BuiltinUnusedDocComment { kind: node_kind, label: node_span, sub },
@ -1107,7 +1107,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
cx.emit_spanned_lint(
cx.emit_span_lint(
NO_MANGLE_GENERIC_ITEMS,
span,
BuiltinNoMangleGeneric { suggestion: no_mangle_attr.span },
@ -1138,7 +1138,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
// Const items do not refer to a particular location in memory, and therefore
// don't have anything to attach a symbol to
cx.emit_spanned_lint(
cx.emit_span_lint(
NO_MANGLE_CONST_ITEMS,
it.span,
BuiltinConstNoMangle { suggestion },
@ -1201,7 +1201,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (ty1.kind(), ty2.kind()))
{
if from_mutbl < to_mutbl {
cx.emit_spanned_lint(MUTABLE_TRANSMUTES, expr.span, BuiltinMutablesTransmutes);
cx.emit_span_lint(MUTABLE_TRANSMUTES, expr.span, BuiltinMutablesTransmutes);
}
}
@ -1233,10 +1233,30 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
}
declare_lint! {
/// The `unstable_features` is deprecated and should no longer be used.
/// The `unstable_features` lint detects uses of `#![feature]`.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(unstable_features)]
/// #![feature(test)]
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// In larger nightly-based projects which
///
/// * consist of a multitude of crates where a subset of crates has to compile on
/// stable either unconditionally or depending on a `cfg` flag to for example
/// allow stable users to depend on them,
/// * don't use nightly for experimental features but for, e.g., unstable options only,
///
/// this lint may come in handy to enforce policies of these kinds.
UNSTABLE_FEATURES,
Allow,
"enabling unstable features (deprecated. do not use)"
"enabling unstable features"
}
declare_lint_pass!(
@ -1246,11 +1266,11 @@ declare_lint_pass!(
impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
if attr.has_name(sym::feature) {
if let Some(items) = attr.meta_item_list() {
for item in items {
cx.emit_spanned_lint(UNSTABLE_FEATURES, item.span(), BuiltinUnstableFeatures);
}
if attr.has_name(sym::feature)
&& let Some(items) = attr.meta_item_list()
{
for item in items {
cx.emit_span_lint(UNSTABLE_FEATURES, item.span(), BuiltinUnstableFeatures);
}
}
}
@ -1303,7 +1323,7 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {
// Now, check if the function has the `#[track_caller]` attribute
&& let Some(attr) = cx.tcx.get_attr(def_id, sym::track_caller)
{
cx.emit_spanned_lint(
cx.emit_span_lint(
UNGATED_ASYNC_FN_TRACK_CALLER,
attr.span,
BuiltinUngatedAsyncFnTrackCaller { label: span, session: &cx.tcx.sess },
@ -1369,7 +1389,7 @@ impl UnreachablePub {
applicability = Applicability::MaybeIncorrect;
}
let def_span = cx.tcx.def_span(def_id);
cx.emit_spanned_lint(
cx.emit_span_lint(
UNREACHABLE_PUB,
def_span,
BuiltinUnreachablePub {
@ -1498,7 +1518,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
suggested_changing_assoc_types = true;
SuggestChangingAssocTypes { ty: hir_ty }
});
cx.emit_spanned_lint(
cx.emit_span_lint(
TYPE_ALIAS_BOUNDS,
where_spans,
BuiltinTypeAliasWhereClause {
@ -1514,7 +1534,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
suggested_changing_assoc_types = true;
SuggestChangingAssocTypes { ty: hir_ty }
});
cx.emit_spanned_lint(
cx.emit_span_lint(
TYPE_ALIAS_BOUNDS,
inline_spans,
BuiltinTypeAliasGenericBounds { suggestion, sub },
@ -1613,7 +1633,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
| ClauseKind::ConstEvaluatable(..) => continue,
};
if predicate.is_global() {
cx.emit_spanned_lint(
cx.emit_span_lint(
TRIVIAL_BOUNDS,
span,
BuiltinTrivialBounds { predicate_kind_name, predicate },
@ -1731,7 +1751,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
replace,
});
} else {
cx.emit_spanned_lint(
cx.emit_span_lint(
ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
pat.span,
BuiltinEllipsisInclusiveRangePatternsLint::Parenthesise {
@ -1749,7 +1769,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
replace: replace.to_string(),
});
} else {
cx.emit_spanned_lint(
cx.emit_span_lint(
ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
join,
BuiltinEllipsisInclusiveRangePatternsLint::NonParenthesise {
@ -1875,7 +1895,7 @@ impl KeywordIdents {
return;
}
cx.emit_spanned_lint(
cx.emit_span_lint(
KEYWORD_IDENTS,
ident.span,
BuiltinKeywordIdents { kw: ident, next: next_edition, suggestion: ident.span },
@ -2183,7 +2203,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
lint_spans.sort_unstable();
lint_spans.dedup();
cx.emit_spanned_lint(
cx.emit_span_lint(
EXPLICIT_OUTLIVES_REQUIREMENTS,
lint_spans.clone(),
BuiltinExplicitOutlives {
@ -2270,13 +2290,13 @@ impl EarlyLintPass for IncompleteInternalFeatures {
let help =
HAS_MIN_FEATURES.contains(&name).then_some(BuiltinIncompleteFeaturesHelp);
cx.emit_spanned_lint(
cx.emit_span_lint(
INCOMPLETE_FEATURES,
span,
BuiltinIncompleteFeatures { name, note, help },
);
} else {
cx.emit_spanned_lint(INTERNAL_FEATURES, span, BuiltinInternalFeatures { name });
cx.emit_span_lint(INTERNAL_FEATURES, span, BuiltinInternalFeatures { name });
}
});
}
@ -2592,7 +2612,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_uninit,
};
let sub = BuiltinUnpermittedTypeInitSub { err };
cx.emit_spanned_lint(
cx.emit_span_lint(
INVALID_VALUE,
expr.span,
BuiltinUnpermittedTypeInit {
@ -2680,7 +2700,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
if let rustc_hir::ExprKind::Unary(rustc_hir::UnOp::Deref, expr_deref) = expr.kind {
if is_null_ptr(cx, expr_deref) {
cx.emit_spanned_lint(
cx.emit_span_lint(
DEREF_NULLPTR,
expr.span,
BuiltinDerefNullptr { label: expr.span },
@ -2829,7 +2849,7 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
let target_spans: MultiSpan =
if spans.len() > 0 { spans.into() } else { (*template_span).into() };
cx.lookup_with_diagnostics(
cx.span_lint_with_diagnostics(
NAMED_ASM_LABELS,
Some(target_spans),
fluent::lint_builtin_asm_labels,
@ -2905,12 +2925,12 @@ impl EarlyLintPass for SpecialModuleName {
}
match item.ident.name.as_str() {
"lib" => cx.emit_spanned_lint(
"lib" => cx.emit_span_lint(
SPECIAL_MODULE_NAME,
item.span,
BuiltinSpecialModuleNameUsed::Lib,
),
"main" => cx.emit_spanned_lint(
"main" => cx.emit_span_lint(
SPECIAL_MODULE_NAME,
item.span,
BuiltinSpecialModuleNameUsed::Main,

View file

@ -530,9 +530,9 @@ pub trait LintContext {
/// Emit a lint at the appropriate level, with an optional associated span and an existing
/// diagnostic.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn lookup_with_diagnostics(
fn span_lint_with_diagnostics(
&self,
lint: &'static Lint,
span: Option<impl Into<MultiSpan>>,
@ -541,7 +541,7 @@ pub trait LintContext {
diagnostic: BuiltinLintDiagnostics,
) {
// We first generate a blank diagnostic.
self.lookup(lint, span, msg, |db| {
self.opt_span_lint(lint, span, msg, |db| {
// Now, set up surrounding context.
diagnostics::builtin(self.sess(), diagnostic, db);
// Rewrap `db`, and pass control to the user.
@ -553,9 +553,9 @@ pub trait LintContext {
// set the span in their `decorate` function (preferably using set_span).
/// Emit a lint at the appropriate level, with an optional associated span.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn lookup<S: Into<MultiSpan>>(
fn opt_span_lint<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
span: Option<S>,
@ -565,42 +565,42 @@ pub trait LintContext {
/// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
/// typically generated by `#[derive(LintDiagnostic)]`).
fn emit_spanned_lint<S: Into<MultiSpan>>(
fn emit_span_lint<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
span: S,
decorator: impl for<'a> DecorateLint<'a, ()>,
) {
self.lookup(lint, Some(span), decorator.msg(), |diag| {
self.opt_span_lint(lint, Some(span), decorator.msg(), |diag| {
decorator.decorate_lint(diag);
});
}
/// Emit a lint at the appropriate level, with an associated span.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn struct_span_lint<S: Into<MultiSpan>>(
fn span_lint<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
span: S,
msg: impl Into<DiagnosticMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
) {
self.lookup(lint, Some(span), msg, decorate);
self.opt_span_lint(lint, Some(span), msg, decorate);
}
/// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
/// generated by `#[derive(LintDiagnostic)]`).
fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) {
self.lookup(lint, None as Option<Span>, decorator.msg(), |diag| {
self.opt_span_lint(lint, None as Option<Span>, decorator.msg(), |diag| {
decorator.decorate_lint(diag);
});
}
/// Emit a lint at the appropriate level, with no associated span.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn lint(
&self,
@ -608,7 +608,7 @@ pub trait LintContext {
msg: impl Into<DiagnosticMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
) {
self.lookup(lint, None as Option<Span>, msg, decorate);
self.opt_span_lint(lint, None as Option<Span>, msg, decorate);
}
/// This returns the lint level for the given lint at the current location.
@ -666,7 +666,7 @@ impl<'tcx> LintContext for LateContext<'tcx> {
}
#[rustc_lint_diagnostics]
fn lookup<S: Into<MultiSpan>>(
fn opt_span_lint<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
span: Option<S>,
@ -676,8 +676,8 @@ impl<'tcx> LintContext for LateContext<'tcx> {
let hir_id = self.last_node_with_lint_attrs;
match span {
Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, msg, decorate),
None => self.tcx.struct_lint_node(lint, hir_id, msg, decorate),
Some(s) => self.tcx.node_span_lint(lint, hir_id, s, msg, decorate),
None => self.tcx.node_lint(lint, hir_id, msg, decorate),
}
}
@ -693,14 +693,14 @@ impl LintContext for EarlyContext<'_> {
}
#[rustc_lint_diagnostics]
fn lookup<S: Into<MultiSpan>>(
fn opt_span_lint<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
span: Option<S>,
msg: impl Into<DiagnosticMessage>,
decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
) {
self.builder.struct_lint(lint, span.map(|s| s.into()), msg, decorate)
self.builder.opt_span_lint(lint, span.map(|s| s.into()), msg, decorate)
}
fn get_lint_level(&self, lint: &'static Lint) -> Level {

View file

@ -5,6 +5,7 @@ use crate::{
use rustc_hir as hir;
use rustc_middle::ty;
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_span::sym;
use rustc_trait_selection::traits::supertraits;
@ -12,6 +13,9 @@ declare_lint! {
/// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the
/// `Deref` implementation with a `dyn SuperTrait` type as `Output`.
///
/// These implementations will become shadowed when the `trait_upcasting` feature is stabilized.
/// The `deref` functions will no longer be called implicitly, so there might be behavior change.
///
/// ### Example
///
/// ```rust,compile_fail
@ -40,10 +44,15 @@ declare_lint! {
///
/// ### Explanation
///
/// The implicit dyn upcasting coercion take priority over those `Deref` impls.
/// The dyn upcasting coercion feature adds new coercion rules, taking priority
/// over certain other coercion rules, which will cause some behavior change.
pub DEREF_INTO_DYN_SUPERTRAIT,
Warn,
"`Deref` implementation usage with a supertrait trait object for output are shadow by implicit coercion",
"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
reference: "issue #89460 <https://github.com/rust-lang/rust/issues/89460>",
};
}
declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]);
@ -78,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
.find_map(|i| (i.ident.name == sym::Target).then_some(i.span))
.map(|label| SupertraitAsDerefTargetLabel { label });
let span = tcx.def_span(item.owner_id.def_id);
cx.emit_spanned_lint(
cx.emit_span_lint(
DEREF_INTO_DYN_SUPERTRAIT,
span,
SupertraitAsDerefTarget {

View file

@ -149,28 +149,28 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
match fn_name {
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
cx.emit_spanned_lint(
cx.emit_span_lint(
DROPPING_REFERENCES,
expr.span,
DropRefDiag { arg_ty, label: arg.span },
);
}
sym::mem_forget if arg_ty.is_ref() => {
cx.emit_spanned_lint(
cx.emit_span_lint(
FORGETTING_REFERENCES,
expr.span,
ForgetRefDiag { arg_ty, label: arg.span },
);
}
sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {
cx.emit_spanned_lint(
cx.emit_span_lint(
DROPPING_COPY_TYPES,
expr.span,
DropCopyDiag { arg_ty, label: arg.span },
);
}
sym::mem_forget if is_copy => {
cx.emit_spanned_lint(
cx.emit_span_lint(
FORGETTING_COPY_TYPES,
expr.span,
ForgetCopyDiag { arg_ty, label: arg.span },
@ -180,7 +180,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
if let ty::Adt(adt, _) = arg_ty.kind()
&& adt.is_manually_drop() =>
{
cx.emit_spanned_lint(
cx.emit_span_lint(
UNDROPPED_MANUALLY_DROPS,
expr.span,
UndroppedManuallyDropsDiag {

View file

@ -45,7 +45,13 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
fn inlined_check_id(&mut self, id: ast::NodeId) {
for early_lint in self.context.buffered.take(id) {
let BufferedEarlyLint { span, msg, node_id: _, lint_id, diagnostic } = early_lint;
self.context.lookup_with_diagnostics(lint_id.lint, Some(span), msg, |_| {}, diagnostic);
self.context.span_lint_with_diagnostics(
lint_id.lint,
Some(span),
msg,
|_| {},
diagnostic,
);
}
}

View file

@ -53,7 +53,7 @@ fn enforce_mem_discriminant(
) {
let ty_param = cx.typeck_results().node_args(func_expr.hir_id).type_at(0);
if is_non_enum(ty_param) {
cx.emit_spanned_lint(
cx.emit_span_lint(
ENUM_INTRINSICS_NON_ENUMS,
expr_span,
EnumIntrinsicsMemDiscriminate { ty_param, note: args_span },
@ -64,11 +64,7 @@ fn enforce_mem_discriminant(
fn enforce_mem_variant_count(cx: &LateContext<'_>, func_expr: &hir::Expr<'_>, span: Span) {
let ty_param = cx.typeck_results().node_args(func_expr.hir_id).type_at(0);
if is_non_enum(ty_param) {
cx.emit_spanned_lint(
ENUM_INTRINSICS_NON_ENUMS,
span,
EnumIntrinsicsMemVariant { ty_param },
);
cx.emit_span_lint(ENUM_INTRINSICS_NON_ENUMS, span, EnumIntrinsicsMemVariant { ty_param });
}
}

View file

@ -29,7 +29,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
{
let rationale = expectation.reason.map(|rationale| ExpectationNote { rationale });
let note = expectation.is_unfulfilled_lint_expectations.then_some(());
tcx.emit_spanned_lint(
tcx.emit_node_span_lint(
UNFULFILLED_LINT_EXPECTATIONS,
*hir_id,
expectation.emission_span,

View file

@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
end_span: pat.span.between(arg.span),
};
cx.emit_spanned_lint(
cx.emit_span_lint(
FOR_LOOPS_OVER_FALLIBLES,
arg.span,
ForLoopsOverFalliblesDiag { article, ty, sub, question_mark, suggestion },

View file

@ -161,7 +161,7 @@ impl ClashingExternDeclarations {
sub,
}
};
tcx.emit_spanned_lint(
tcx.emit_node_span_lint(
CLASHING_EXTERN_DECLARATIONS,
this_fi.hir_id(),
mismatch_label,

View file

@ -74,7 +74,7 @@ impl HiddenUnicodeCodepoints {
HiddenUnicodeCodepointsDiagSub::NoEscape { spans }
};
cx.emit_spanned_lint(
cx.emit_span_lint(
TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
span,
HiddenUnicodeCodepointsDiag { label, count, span_label: span, labels, sub },

View file

@ -43,7 +43,7 @@ impl LateLintPass<'_> for DefaultHashTypes {
Some(sym::HashSet) => "FxHashSet",
_ => return,
};
cx.emit_spanned_lint(
cx.emit_span_lint(
DEFAULT_HASH_TYPES,
path.span,
DefaultHashTypesDiag { preferred, used: cx.tcx.item_name(def_id) },
@ -91,7 +91,7 @@ impl LateLintPass<'_> for QueryStability {
if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, args) {
let def_id = instance.def_id();
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
cx.emit_spanned_lint(
cx.emit_span_lint(
POTENTIAL_QUERY_INSTABILITY,
span,
QueryInstability { query: cx.tcx.item_name(def_id) },
@ -136,7 +136,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
{
let span =
path.span.with_hi(segment.args.map_or(segment.ident.span, |a| a.span_ext).hi());
cx.emit_spanned_lint(USAGE_OF_TY_TYKIND, path.span, TykindKind { suggestion: span });
cx.emit_span_lint(USAGE_OF_TY_TYKIND, path.span, TykindKind { suggestion: span });
}
}
@ -186,19 +186,19 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
match span {
Some(span) => {
cx.emit_spanned_lint(
cx.emit_span_lint(
USAGE_OF_TY_TYKIND,
path.span,
TykindKind { suggestion: span },
);
}
None => cx.emit_spanned_lint(USAGE_OF_TY_TYKIND, path.span, TykindDiag),
None => cx.emit_span_lint(USAGE_OF_TY_TYKIND, path.span, TykindDiag),
}
} else if !ty.span.from_expansion()
&& path.segments.len() > 1
&& let Some(ty) = is_ty_or_ty_ctxt(cx, path)
{
cx.emit_spanned_lint(
cx.emit_span_lint(
USAGE_OF_QUALIFIED_TY,
path.span,
TyQualified { ty, suggestion: path.span },
@ -285,7 +285,7 @@ impl EarlyLintPass for LintPassImpl {
&& call_site.ctxt().outer_expn_data().kind
!= ExpnKind::Macro(MacroKind::Bang, sym::declare_lint_pass)
{
cx.emit_spanned_lint(
cx.emit_span_lint(
LINT_PASS_IMPL_WITHOUT_MACRO,
lint_pass.path.span,
LintPassByHand,
@ -327,7 +327,7 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword {
if is_doc_keyword(keyword) {
return;
}
cx.emit_spanned_lint(
cx.emit_span_lint(
EXISTING_DOC_KEYWORD,
attr.span,
NonExistentDocKeyword { keyword },
@ -405,7 +405,7 @@ impl LateLintPass<'_> for Diagnostics {
}
debug!(?found_impl);
if !found_parent_with_attr && !found_impl {
cx.emit_spanned_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl);
cx.emit_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl);
}
let mut found_diagnostic_message = false;
@ -421,7 +421,7 @@ impl LateLintPass<'_> for Diagnostics {
}
debug!(?found_diagnostic_message);
if !found_parent_with_attr && !found_diagnostic_message {
cx.emit_spanned_lint(UNTRANSLATABLE_DIAGNOSTIC, span, UntranslatableDiag);
cx.emit_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, UntranslatableDiag);
}
}
}
@ -490,7 +490,7 @@ impl EarlyLintPass for Diagnostics {
}) {
return;
}
cx.emit_spanned_lint(
cx.emit_span_lint(
UNTRANSLATABLE_DIAGNOSTIC_TRIVIAL,
stmt.span,
UntranslatableDiagnosticTrivial,
@ -528,7 +528,7 @@ impl LateLintPass<'_> for BadOptAccess {
&& let Some(lit) = item.lit()
&& let ast::LitKind::Str(val, _) = lit.kind
{
cx.emit_spanned_lint(
cx.emit_span_lint(
BAD_OPT_ACCESS,
expr.span,
BadOptAccessDiag { msg: val.as_str() },
@ -553,7 +553,7 @@ impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt {
expr.kind
{
if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) {
cx.emit_spanned_lint(SPAN_USE_EQ_CTXT, expr.span, SpanUseEqCtxtDiag);
cx.emit_span_lint(SPAN_USE_EQ_CTXT, expr.span, SpanUseEqCtxtDiag);
}
}
}

View file

@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 {
let valid_up_to = utf8_error.valid_up_to();
let is_unchecked_variant = diag_item.as_str().contains("unchecked");
cx.emit_spanned_lint(
cx.emit_span_lint(
if is_unchecked_variant {
INVALID_FROM_UTF8_UNCHECKED
} else {
@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 {
.map(|e| match &e.kind {
ExprKind::Lit(Spanned { node: lit, .. }) => match lit {
LitKind::Byte(b) => Some(*b),
LitKind::Int(b, _) => Some(*b as u8),
LitKind::Int(b, _) => Some(b.get() as u8),
_ => None,
},
_ => None,

View file

@ -5,7 +5,7 @@ use crate::{
use rustc_errors::MultiSpan;
use rustc_hir as hir;
use rustc_middle::ty;
use rustc_span::Symbol;
use rustc_span::{sym, Symbol};
declare_lint! {
/// The `let_underscore_drop` lint checks for statements which don't bind
@ -105,51 +105,66 @@ const SYNC_GUARD_SYMBOLS: [Symbol; 3] = [
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
if !matches!(local.pat.kind, hir::PatKind::Wild) {
return;
}
if matches!(local.source, rustc_hir::LocalSource::AsyncFn) {
return;
}
if let Some(init) = local.init {
let init_ty = cx.typeck_results().expr_ty(init);
// If the type has a trivial Drop implementation, then it doesn't
// matter that we drop the value immediately.
if !init_ty.needs_drop(cx.tcx, cx.param_env) {
let mut top_level = true;
// We recursively walk through all patterns, so that we can catch cases where the lock is nested in a pattern.
// For the basic `let_underscore_drop` lint, we only look at the top level, since there are many legitimate reasons
// to bind a sub-pattern to an `_`, if we're only interested in the rest.
// But with locks, we prefer having the chance of "false positives" over missing cases, since the effects can be
// quite catastrophic.
local.pat.walk_always(|pat| {
let is_top_level = top_level;
top_level = false;
if !matches!(pat.kind, hir::PatKind::Wild) {
return;
}
let is_sync_lock = match init_ty.kind() {
let ty = cx.typeck_results().pat_ty(pat);
// If the type has a trivial Drop implementation, then it doesn't
// matter that we drop the value immediately.
if !ty.needs_drop(cx.tcx, cx.param_env) {
return;
}
// Lint for patterns like `mutex.lock()`, which returns `Result<MutexGuard, _>` as well.
let potential_lock_type = match ty.kind() {
ty::Adt(adt, args) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => {
args.type_at(0)
}
_ => ty,
};
let is_sync_lock = match potential_lock_type.kind() {
ty::Adt(adt, _) => SYNC_GUARD_SYMBOLS
.iter()
.any(|guard_symbol| cx.tcx.is_diagnostic_item(*guard_symbol, adt.did())),
_ => false,
};
let can_use_init = is_top_level.then_some(local.init).flatten();
let sub = NonBindingLetSub {
suggestion: local.pat.span,
multi_suggestion_start: local.span.until(init.span),
multi_suggestion_end: init.span.shrink_to_hi(),
suggestion: pat.span,
// We can't suggest `drop()` when we're on the top level.
drop_fn_start_end: can_use_init
.map(|init| (local.span.until(init.span), init.span.shrink_to_hi())),
is_assign_desugar: matches!(local.source, rustc_hir::LocalSource::AssignDesugar(_)),
};
if is_sync_lock {
let mut span = MultiSpan::from_spans(vec![local.pat.span, init.span]);
let mut span = MultiSpan::from_span(pat.span);
span.push_span_label(
local.pat.span,
pat.span,
"this lock is not assigned to a binding and is immediately dropped".to_string(),
);
span.push_span_label(
init.span,
"this binding will immediately drop the value assigned to it".to_string(),
);
cx.emit_spanned_lint(LET_UNDERSCORE_LOCK, span, NonBindingLet::SyncLock { sub });
} else {
cx.emit_spanned_lint(
LET_UNDERSCORE_DROP,
local.span,
NonBindingLet::DropType { sub },
);
cx.emit_span_lint(LET_UNDERSCORE_LOCK, span, NonBindingLet::SyncLock { sub });
// Only emit let_underscore_drop for top-level `_` patterns.
} else if can_use_init.is_some() {
cx.emit_span_lint(LET_UNDERSCORE_DROP, local.span, NonBindingLet::DropType { sub });
}
}
});
}
}

View file

@ -24,7 +24,7 @@ use rustc_hir::HirId;
use rustc_index::IndexVec;
use rustc_middle::hir::nested_filter;
use rustc_middle::lint::{
reveal_actual_level, struct_lint_level, LevelAndSource, LintExpectation, LintLevelSource,
lint_level, reveal_actual_level, LevelAndSource, LintExpectation, LintLevelSource,
ShallowLintLevelMap,
};
use rustc_middle::query::Providers;
@ -682,7 +682,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
sub,
});
} else {
self.emit_spanned_lint(
self.emit_span_lint(
FORBIDDEN_LINT_GROUPS,
src.span().into(),
OverruledAttributeLint {
@ -925,7 +925,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
}
Err((Some(ids), ref new_lint_name)) => {
let lint = builtin::RENAMED_AND_REMOVED_LINTS;
self.emit_spanned_lint(
self.emit_span_lint(
lint,
sp.into(),
DeprecatedLintName {
@ -976,13 +976,13 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
RenamedLintSuggestion::WithSpan { suggestion: sp, replace };
let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
let lint = RenamedLint { name: name.as_str(), suggestion };
self.emit_spanned_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
}
CheckLintNameResult::Removed(ref reason) => {
let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
let lint = RemovedLint { name: name.as_str(), reason };
self.emit_spanned_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
}
CheckLintNameResult::NoLint(suggestion) => {
@ -995,7 +995,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
UnknownLintSuggestion::WithSpan { suggestion: sp, replace, from_rustc }
});
let lint = UnknownLint { name, suggestion };
self.emit_spanned_lint(UNKNOWN_LINTS, sp.into(), lint);
self.emit_span_lint(UNKNOWN_LINTS, sp.into(), lint);
}
}
// If this lint was renamed, apply the new lint instead of ignoring the attribute.
@ -1041,7 +1041,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
continue;
};
self.emit_spanned_lint(
self.emit_span_lint(
UNUSED_ATTRIBUTES,
lint_attr_span.into(),
IgnoredUnlessCrateSpecified { level: level.as_str(), name: lint_attr_name },
@ -1062,7 +1062,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
if self.lint_added_lints {
let lint = builtin::UNKNOWN_LINTS;
let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS);
struct_lint_level(
lint_level(
self.sess,
lint,
level,
@ -1096,10 +1096,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
/// Used to emit a lint-related diagnostic based on the current state of
/// this lint context.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics]
#[track_caller]
pub(crate) fn struct_lint(
pub(crate) fn opt_span_lint(
&self,
lint: &'static Lint,
span: Option<MultiSpan>,
@ -1107,18 +1107,18 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
) {
let (level, src) = self.lint_level(lint);
struct_lint_level(self.sess, lint, level, src, span, msg, decorate)
lint_level(self.sess, lint, level, src, span, msg, decorate)
}
#[track_caller]
pub fn emit_spanned_lint(
pub fn emit_span_lint(
&self,
lint: &'static Lint,
span: MultiSpan,
decorate: impl for<'a> DecorateLint<'a, ()>,
) {
let (level, src) = self.lint_level(lint);
struct_lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| {
lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| {
decorate.decorate_lint(lint);
});
}
@ -1126,7 +1126,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
#[track_caller]
pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> DecorateLint<'a, ()>) {
let (level, src) = self.lint_level(lint);
struct_lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| {
lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| {
decorate.decorate_lint(lint);
});
}

View file

@ -35,6 +35,7 @@
#![feature(iter_intersperse)]
#![feature(iter_order_by)]
#![feature(let_chains)]
#![cfg_attr(not(bootstrap), feature(trait_upcasting))]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(rustc_attrs)]

View file

@ -532,7 +532,6 @@ pub enum BuiltinSpecialModuleNameUsed {
// deref_into_dyn_supertrait.rs
#[derive(LintDiagnostic)]
#[diag(lint_supertrait_as_deref_target)]
#[help]
pub struct SupertraitAsDerefTarget<'a> {
pub self_ty: Ty<'a>,
pub supertrait_principal: PolyExistentialTraitRef<'a>,
@ -930,8 +929,7 @@ pub enum NonBindingLet {
pub struct NonBindingLetSub {
pub suggestion: Span,
pub multi_suggestion_start: Span,
pub multi_suggestion_end: Span,
pub drop_fn_start_end: Option<(Span, Span)>,
pub is_assign_desugar: bool,
}
@ -940,21 +938,31 @@ impl AddToDiagnostic for NonBindingLetSub {
where
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
{
let prefix = if self.is_assign_desugar { "let " } else { "" };
diag.span_suggestion_verbose(
self.suggestion,
fluent::lint_non_binding_let_suggestion,
format!("{prefix}_unused"),
Applicability::MachineApplicable,
);
diag.multipart_suggestion(
fluent::lint_non_binding_let_multi_suggestion,
vec![
(self.multi_suggestion_start, "drop(".to_string()),
(self.multi_suggestion_end, ")".to_string()),
],
Applicability::MachineApplicable,
);
let can_suggest_binding = self.drop_fn_start_end.is_some() || !self.is_assign_desugar;
if can_suggest_binding {
let prefix = if self.is_assign_desugar { "let " } else { "" };
diag.span_suggestion_verbose(
self.suggestion,
fluent::lint_non_binding_let_suggestion,
format!("{prefix}_unused"),
Applicability::MachineApplicable,
);
} else {
diag.span_help(self.suggestion, fluent::lint_non_binding_let_suggestion);
}
if let Some(drop_fn_start_end) = self.drop_fn_start_end {
diag.multipart_suggestion(
fluent::lint_non_binding_let_multi_suggestion,
vec![
(drop_fn_start_end.0, "drop(".to_string()),
(drop_fn_start_end.1, ")".to_string()),
],
Applicability::MachineApplicable,
);
} else {
diag.help(fluent::lint_non_binding_let_multi_drop_fn);
}
}
}
@ -1099,7 +1107,10 @@ pub struct IdentifierNonAsciiChar;
#[derive(LintDiagnostic)]
#[diag(lint_identifier_uncommon_codepoints)]
pub struct IdentifierUncommonCodepoints;
pub struct IdentifierUncommonCodepoints {
pub codepoints: Vec<char>,
pub codepoints_len: usize,
}
#[derive(LintDiagnostic)]
#[diag(lint_confusable_identifier_pair)]

View file

@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
let fn_ty = cx.tcx.fn_sig(id).skip_binder();
let ret_ty = fn_ty.output().skip_binder();
if is_unit_type(ret_ty) {
cx.emit_spanned_lint(
cx.emit_span_lint(
MAP_UNIT_FN,
span,
MappingToUnit {
@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
let cl_ty = subs.as_closure().sig();
let ret_ty = cl_ty.output().skip_binder();
if is_unit_type(ret_ty) {
cx.emit_spanned_lint(
cx.emit_span_lint(
MAP_UNIT_FN,
span,
MappingToUnit {

View file

@ -57,7 +57,7 @@ fn lint_cstring_as_ptr(
if cx.tcx.is_diagnostic_item(sym::Result, def.did()) {
if let ty::Adt(adt, _) = args.type_at(0).kind() {
if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) {
cx.emit_spanned_lint(
cx.emit_span_lint(
TEMPORARY_CSTRING_AS_PTR,
as_ptr_span,
CStringPtr { as_ptr: as_ptr_span, unwrap: unwrap.span },

View file

@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
.into_iter()
.filter_map(|(pred, _)| pred.as_trait_clause());
if direct_super_traits_iter.count() > 1 {
cx.emit_spanned_lint(
cx.emit_span_lint(
MULTIPLE_SUPERTRAIT_UPCASTABLE,
cx.tcx.def_span(def_id),
crate::lints::MultipleSupertraitUpcastable { ident: item.ident },

View file

@ -186,11 +186,21 @@ impl EarlyLintPass for NonAsciiIdents {
continue;
}
has_non_ascii_idents = true;
cx.emit_spanned_lint(NON_ASCII_IDENTS, sp, IdentifierNonAsciiChar);
cx.emit_span_lint(NON_ASCII_IDENTS, sp, IdentifierNonAsciiChar);
if check_uncommon_codepoints
&& !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed)
{
cx.emit_spanned_lint(UNCOMMON_CODEPOINTS, sp, IdentifierUncommonCodepoints);
let codepoints: Vec<_> = symbol_str
.chars()
.filter(|c| !GeneralSecurityProfile::identifier_allowed(*c))
.collect();
let codepoints_len = codepoints.len();
cx.emit_span_lint(
UNCOMMON_CODEPOINTS,
sp,
IdentifierUncommonCodepoints { codepoints, codepoints_len },
);
}
}
@ -218,7 +228,7 @@ impl EarlyLintPass for NonAsciiIdents {
.entry(skeleton_sym)
.and_modify(|(existing_symbol, existing_span, existing_is_ascii)| {
if !*existing_is_ascii || !is_ascii {
cx.emit_spanned_lint(
cx.emit_span_lint(
CONFUSABLE_IDENTS,
sp,
ConfusableIdentifierPair {
@ -339,7 +349,7 @@ impl EarlyLintPass for NonAsciiIdents {
let char_info = format!("'{}' (U+{:04X})", ch, ch as u32);
includes += &char_info;
}
cx.emit_spanned_lint(
cx.emit_span_lint(
MIXED_SCRIPT_CONFUSABLES,
sp,
MixedScriptConfusables { set: script_set.to_string(), includes },

View file

@ -121,7 +121,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
}
#[allow(rustc::diagnostic_outside_of_impl)]
cx.struct_span_lint(NON_FMT_PANICS, arg_span, fluent::lint_non_fmt_panic, |lint| {
cx.span_lint(NON_FMT_PANICS, arg_span, fluent::lint_non_fmt_panic, |lint| {
lint.arg("name", symbol);
lint.note(fluent::lint_note);
lint.note(fluent::lint_more_info_note);
@ -251,7 +251,7 @@ fn check_panic_str<'tcx>(
.map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end)))
.collect(),
};
cx.emit_spanned_lint(
cx.emit_span_lint(
NON_FMT_PANICS,
arg_spans,
NonFmtPanicUnused {
@ -268,7 +268,7 @@ fn check_panic_str<'tcx>(
.collect()
});
let count = brace_spans.as_ref().map(|v| v.len()).unwrap_or(/* any number >1 */ 2);
cx.emit_spanned_lint(
cx.emit_span_lint(
NON_FMT_PANICS,
brace_spans.unwrap_or_else(|| vec![span]),
NonFmtPanicBraces {

View file

@ -150,7 +150,7 @@ impl NonCamelCaseTypes {
} else {
NonCamelCaseTypeSub::Label { span: ident.span }
};
cx.emit_spanned_lint(
cx.emit_span_lint(
NON_CAMEL_CASE_TYPES,
ident.span,
NonCamelCaseType { sort, name, sub },
@ -320,7 +320,7 @@ impl NonSnakeCase {
} else {
NonSnakeCaseDiagSub::Label { span }
};
cx.emit_spanned_lint(NON_SNAKE_CASE, span, NonSnakeCaseDiag { sort, name, sc, sub });
cx.emit_span_lint(NON_SNAKE_CASE, span, NonSnakeCaseDiag { sort, name, sc, sub });
}
}
}
@ -481,7 +481,7 @@ impl NonUpperCaseGlobals {
} else {
NonUpperCaseGlobalSub::Label { span: ident.span }
};
cx.emit_spanned_lint(
cx.emit_span_lint(
NON_UPPER_CASE_GLOBALS,
ident.span,
NonUpperCaseGlobal { sort, name, sub },

View file

@ -121,7 +121,7 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
let orig_ty = expr_ty.peel_refs();
if receiver_ty == expr_ty {
cx.emit_spanned_lint(
cx.emit_span_lint(
NOOP_METHOD_CALL,
span,
NoopMethodCallDiag { method: call.ident.name, orig_ty, trait_, label: span },
@ -131,12 +131,12 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
// If `type_of(x) == T` and `x.borrow()` is used to get `&T`,
// then that should be allowed
sym::noop_method_borrow => return,
sym::noop_method_clone => cx.emit_spanned_lint(
sym::noop_method_clone => cx.emit_span_lint(
SUSPICIOUS_DOUBLE_REF_OP,
span,
SuspiciousDoubleRefCloneDiag { ty: expr_ty },
),
sym::noop_method_deref => cx.emit_spanned_lint(
sym::noop_method_deref => cx.emit_span_lint(
SUSPICIOUS_DOUBLE_REF_OP,
span,
SuspiciousDoubleRefDerefDiag { ty: expr_ty },

View file

@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
}),
_ => None,
};
cx.emit_spanned_lint(
cx.emit_span_lint(
OPAQUE_HIDDEN_INFERRED_BOUND,
pred_span,
OpaqueHiddenInferredBoundLint {

View file

@ -29,7 +29,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
}
}
if let Some(t) = path_for_pass_by_value(cx, inner_ty) {
cx.emit_spanned_lint(
cx.emit_span_lint(
PASS_BY_VALUE,
ty.span,
PassByValueDiag { ty: t, suggestion: ty.span },

View file

@ -97,7 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
)
&& let Some(diag) = incorrect_check(cx, arg) =>
{
cx.emit_spanned_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
}
// Catching:
@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
)
&& let Some(diag) = incorrect_check(cx, receiver) =>
{
cx.emit_spanned_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
}
ExprKind::Binary(op, left, right) if matches!(op.node, BinOpKind::Eq) => {
@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
&& let LitKind::Int(v, _) = spanned.node
&& v == 0 =>
{
cx.emit_spanned_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
}
// Catching:
@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
&& let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
&& (diag_item == sym::ptr_null || diag_item == sym::ptr_null_mut) =>
{
cx.emit_spanned_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
}
_ => {}

View file

@ -47,7 +47,7 @@ fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, boo
return;
}
cx.emit_spanned_lint(
cx.emit_span_lint(
REDUNDANT_SEMICOLONS,
span,
RedundantSemicolonsDiag { multiple, suggestion: span },

View file

@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
let orig_cast = if init.span != e.span { Some(init.span) } else { None };
let ty_has_interior_mutability = ty_has_interior_mutability.then_some(());
cx.emit_spanned_lint(
cx.emit_span_lint(
INVALID_REFERENCE_CASTING,
expr.span,
if pat == PatternKind::Assign {

View file

@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
continue;
}
let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return };
cx.emit_spanned_lint(
cx.emit_span_lint(
DROP_BOUNDS,
span,
DropTraitConstraintsDiag { predicate, tcx: cx.tcx, def_id },
@ -116,7 +116,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
let def_id = bound.trait_ref.trait_def_id();
if cx.tcx.lang_items().drop_trait() == def_id {
let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return };
cx.emit_spanned_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id });
cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id });
}
}
}

View file

@ -254,7 +254,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
}
};
cx.emit_spanned_lint(
cx.emit_span_lint(
OVERFLOWING_LITERALS,
struct_expr.span,
RangeEndpointOutOfRange { ty, sub: sub_sugg },
@ -371,7 +371,7 @@ fn report_bin_hex_error(
})
.flatten();
cx.emit_spanned_lint(
cx.emit_span_lint(
OVERFLOWING_LITERALS,
expr.span,
OverflowingBinHex {
@ -473,7 +473,7 @@ fn lint_int_literal<'tcx>(
let help = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
.map(|suggestion_ty| OverflowingIntHelp { suggestion_ty });
cx.emit_spanned_lint(
cx.emit_span_lint(
OVERFLOWING_LITERALS,
span,
OverflowingInt { ty: t.name_str(), lit, min, max, help },
@ -492,7 +492,7 @@ fn lint_uint_literal<'tcx>(
let lit_val: u128 = match lit.node {
// _v is u8, within range by definition
ast::LitKind::Byte(_v) => return,
ast::LitKind::Int(v, _) => v,
ast::LitKind::Int(v, _) => v.get(),
_ => bug!(),
};
if lit_val < min || lit_val > max {
@ -501,7 +501,7 @@ fn lint_uint_literal<'tcx>(
match par_e.kind {
hir::ExprKind::Cast(..) => {
if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
cx.emit_spanned_lint(
cx.emit_span_lint(
OVERFLOWING_LITERALS,
par_e.span,
OnlyCastu8ToChar { span: par_e.span, literal: lit_val },
@ -528,7 +528,7 @@ fn lint_uint_literal<'tcx>(
);
return;
}
cx.emit_spanned_lint(
cx.emit_span_lint(
OVERFLOWING_LITERALS,
e.span,
OverflowingUInt {
@ -555,7 +555,7 @@ fn lint_literal<'tcx>(
ty::Int(t) => {
match lit.node {
ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => {
lint_int_literal(cx, type_limits, e, lit, t, v)
lint_int_literal(cx, type_limits, e, lit, t, v.get())
}
_ => bug!(),
};
@ -570,7 +570,7 @@ fn lint_literal<'tcx>(
_ => bug!(),
};
if is_infinite == Ok(true) {
cx.emit_spanned_lint(
cx.emit_span_lint(
OVERFLOWING_LITERALS,
e.span,
OverflowingLiteral {
@ -654,7 +654,7 @@ fn lint_nan<'tcx>(
_ => return,
};
cx.emit_spanned_lint(INVALID_NAN_COMPARISONS, e.span, lint);
cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint);
}
fn lint_wide_pointer<'tcx>(
@ -700,7 +700,7 @@ fn lint_wide_pointer<'tcx>(
let (Some(l_span), Some(r_span)) =
(l.span.find_ancestor_inside(e.span), r.span.find_ancestor_inside(e.span))
else {
return cx.emit_spanned_lint(
return cx.emit_span_lint(
AMBIGUOUS_WIDE_POINTER_COMPARISONS,
e.span,
AmbiguousWidePointerComparisons::Spanless,
@ -718,7 +718,7 @@ fn lint_wide_pointer<'tcx>(
let deref_left = &*"*".repeat(l_ty_refs);
let deref_right = &*"*".repeat(r_ty_refs);
cx.emit_spanned_lint(
cx.emit_span_lint(
AMBIGUOUS_WIDE_POINTER_COMPARISONS,
e.span,
AmbiguousWidePointerComparisons::Spanful {
@ -770,7 +770,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
hir::ExprKind::Binary(binop, ref l, ref r) => {
if is_comparison(binop) {
if !check_limits(cx, binop, l, r) {
cx.emit_spanned_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons);
cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons);
} else {
lint_nan(cx, e, binop, l, r);
lint_wide_pointer(cx, e, binop.node, l, r);
@ -842,7 +842,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
ast::LitKind::Int(
v,
ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed,
) => v as i128,
) => v.get() as i128,
_ => return true,
},
_ => bug!(),
@ -853,7 +853,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
let (min, max): (u128, u128) = uint_ty_range(uint_ty);
let lit_val: u128 = match lit.kind {
hir::ExprKind::Lit(li) => match li.node {
ast::LitKind::Int(v, _) => v,
ast::LitKind::Int(v, _) => v.get(),
_ => return true,
},
_ => bug!(),
@ -1464,7 +1464,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
} else {
None
};
self.cx.emit_spanned_lint(
self.cx.emit_span_lint(
lint,
sp,
ImproperCTypes { ty, desc, label: sp, help, note, span_note },
@ -1792,7 +1792,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
// We only warn if the largest variant is at least thrice as large as
// the second-largest.
if largest > slargest * 3 && slargest > 0 {
cx.emit_spanned_lint(
cx.emit_span_lint(
VARIANT_SIZE_DIFFERENCES,
enum_definition.variants[largest_index].span,
VariantSizeDifferencesDiag { largest },
@ -1913,17 +1913,9 @@ impl InvalidAtomicOrdering {
&& (ordering == invalid_ordering || ordering == sym::AcqRel)
{
if method == sym::load {
cx.emit_spanned_lint(
INVALID_ATOMIC_ORDERING,
ordering_arg.span,
AtomicOrderingLoad,
);
cx.emit_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, AtomicOrderingLoad);
} else {
cx.emit_spanned_lint(
INVALID_ATOMIC_ORDERING,
ordering_arg.span,
AtomicOrderingStore,
);
cx.emit_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, AtomicOrderingStore);
};
}
}
@ -1935,7 +1927,7 @@ impl InvalidAtomicOrdering {
&& matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::fence | sym::compiler_fence))
&& Self::match_ordering(cx, &args[0]) == Some(sym::Relaxed)
{
cx.emit_spanned_lint(INVALID_ATOMIC_ORDERING, args[0].span, AtomicOrderingFence);
cx.emit_span_lint(INVALID_ATOMIC_ORDERING, args[0].span, AtomicOrderingFence);
}
}
@ -1957,7 +1949,7 @@ impl InvalidAtomicOrdering {
let Some(fail_ordering) = Self::match_ordering(cx, fail_order_arg) else { return };
if matches!(fail_ordering, sym::Release | sym::AcqRel) {
cx.emit_spanned_lint(
cx.emit_span_lint(
INVALID_ATOMIC_ORDERING,
fail_order_arg.span,
InvalidAtomicOrderingDiag { method, fail_order_arg_span: fail_order_arg.span },

View file

@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for UnitBindings {
&& !matches!(init.kind, hir::ExprKind::Tup([]))
&& !matches!(local.pat.kind, hir::PatKind::Tuple([], ..))
{
cx.emit_spanned_lint(
cx.emit_span_lint(
UNIT_BINDINGS,
local.span,
UnitBindingsDiag { label: local.pat.span },

View file

@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
let mut op_warned = false;
if let Some(must_use_op) = must_use_op {
cx.emit_spanned_lint(
cx.emit_span_lint(
UNUSED_MUST_USE,
expr.span,
UnusedOp {
@ -202,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
}
if !(type_lint_emitted_or_suppressed || fn_warned || op_warned) {
cx.emit_spanned_lint(UNUSED_RESULTS, s.span, UnusedResult { ty });
cx.emit_span_lint(UNUSED_RESULTS, s.span, UnusedResult { ty });
}
fn check_fn_must_use(
@ -494,21 +494,21 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
);
}
MustUsePath::Closure(span) => {
cx.emit_spanned_lint(
cx.emit_span_lint(
UNUSED_MUST_USE,
*span,
UnusedClosure { count: plural_len, pre: descr_pre, post: descr_post },
);
}
MustUsePath::Coroutine(span) => {
cx.emit_spanned_lint(
cx.emit_span_lint(
UNUSED_MUST_USE,
*span,
UnusedCoroutine { count: plural_len, pre: descr_pre, post: descr_post },
);
}
MustUsePath::Def(span, def_id, reason) => {
cx.emit_spanned_lint(
cx.emit_span_lint(
UNUSED_MUST_USE,
*span,
UnusedDef {
@ -568,9 +568,9 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements {
} else {
PathStatementDropSub::Help { span: s.span }
};
cx.emit_spanned_lint(PATH_STATEMENTS, s.span, PathStatementDrop { sub })
cx.emit_span_lint(PATH_STATEMENTS, s.span, PathStatementDrop { sub })
} else {
cx.emit_spanned_lint(PATH_STATEMENTS, s.span, PathStatementNoEffect);
cx.emit_span_lint(PATH_STATEMENTS, s.span, PathStatementNoEffect);
}
}
}
@ -824,7 +824,7 @@ trait UnusedDelimLint {
end_replace: hi_replace,
}
});
cx.emit_spanned_lint(
cx.emit_span_lint(
self.lint(),
primary_span,
UnusedDelim { delim: Self::DELIM_STR, item: msg, suggestion },
@ -1507,7 +1507,7 @@ impl UnusedImportBraces {
ast::UseTreeKind::Nested(_) => return,
};
cx.emit_spanned_lint(
cx.emit_span_lint(
UNUSED_IMPORT_BRACES,
item.span,
UnusedImportBracesDiag { node: node_name },
@ -1564,10 +1564,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation {
if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind {
match m {
adjustment::AutoBorrowMutability::Not => {
cx.emit_spanned_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationDiag);
cx.emit_span_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationDiag);
}
adjustment::AutoBorrowMutability::Mut { .. } => {
cx.emit_spanned_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationMutDiag);
cx.emit_span_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationMutDiag);
}
};
}

View file

@ -2755,6 +2755,11 @@ declare_lint! {
pub UNSAFE_OP_IN_UNSAFE_FN,
Allow,
"unsafe operations in unsafe functions without an explicit unsafe block are deprecated",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "issue #71668 <https://github.com/rust-lang/rust/issues/71668>",
explain_reason: false
};
@edition Edition2024 => Warn;
}
@ -4604,3 +4609,50 @@ declare_lint! {
reference: "issue #X <https://github.com/rust-lang/rust/issues/X>",
};
}
declare_lint! {
/// The `private_macro_use` lint detects private macros that are imported
/// with `#[macro_use]`.
///
/// ### Example
///
/// ```rust,ignore (needs extern crate)
/// // extern_macro.rs
/// macro_rules! foo_ { () => {}; }
/// use foo_ as foo;
///
/// // code.rs
///
/// #![deny(private_macro_use)]
///
/// #[macro_use]
/// extern crate extern_macro;
///
/// fn main() {
/// foo!();
/// }
/// ```
///
/// This will produce:
///
/// ```text
/// error: cannot find macro `foo` in this scope
/// ```
///
/// ### Explanation
///
/// This lint arises from overlooking visibility checks for macros
/// in an external crate.
///
/// This is a [future-incompatible] lint to transition this to a
/// hard error in the future.
///
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub PRIVATE_MACRO_USE,
Warn,
"detects certain macro bindings that should not be re-exported",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
reference: "issue #120192 <https://github.com/rust-lang/rust/issues/120192>",
};
}

View file

@ -90,7 +90,7 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// Then, later, to emit the error:
///
/// ```ignore (rust)
/// cx.struct_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint {
/// cx.span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint {
/// method,
/// success_ordering,
/// fail_ordering,

View file

@ -49,6 +49,7 @@
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
#![feature(control_flow_enum)]
#![cfg_attr(not(bootstrap), feature(trait_upcasting))]
#![feature(trusted_step)]
#![feature(try_blocks)]
#![feature(try_reserve_kind)]

View file

@ -247,18 +247,18 @@ pub fn explain_lint_level_source(
///
/// If you are looking to implement a lint, look for higher level functions,
/// for example:
/// - [`TyCtxt::emit_spanned_lint`]
/// - [`TyCtxt::struct_span_lint_hir`]
/// - [`TyCtxt::emit_lint`]
/// - [`TyCtxt::struct_lint_node`]
/// - `LintContext::lookup`
/// - [`TyCtxt::emit_node_span_lint`]
/// - [`TyCtxt::node_span_lint`]
/// - [`TyCtxt::emit_node_lint`]
/// - [`TyCtxt::node_lint`]
/// - `LintContext::opt_span_lint`
///
/// ## `decorate`
///
/// It is not intended to call `emit`/`cancel` on the `DiagnosticBuilder` passed
/// in the `decorate` callback.
#[track_caller]
pub fn struct_lint_level(
pub fn lint_level(
sess: &Session,
lint: &'static Lint,
level: Level,
@ -270,7 +270,7 @@ pub fn struct_lint_level(
// Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
// the "real" work.
#[track_caller]
fn struct_lint_level_impl(
fn lint_level_impl(
sess: &Session,
lint: &'static Lint,
level: Level,
@ -399,7 +399,7 @@ pub fn struct_lint_level(
explain_lint_level_source(lint, level, src, &mut *err);
err.emit()
}
struct_lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate))
lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate))
}
/// Returns whether `span` originates in a foreign crate's external macro.

View file

@ -217,7 +217,7 @@ fn late_report_deprecation(
return;
}
let method_span = method_span.unwrap_or(span);
tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| {
tcx.node_span_lint(lint, hir_id, method_span, message, |diag| {
if let hir::Node::Expr(_) = tcx.hir_node(hir_id) {
let kind = tcx.def_descr(def_id);
deprecation_suggestion(diag, kind, suggestion, method_span);
@ -585,7 +585,7 @@ impl<'tcx> TyCtxt<'tcx> {
unmarked: impl FnOnce(Span, DefId),
) -> bool {
let soft_handler = |lint, span, msg: String| {
self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {})
self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {})
};
let eval_result =
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);

View file

@ -195,7 +195,7 @@ impl<'tcx> ConstValue<'tcx> {
/// Constants
#[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable, Debug)]
#[derive(TypeFoldable, TypeVisitable)]
#[derive(TypeFoldable, TypeVisitable, Lift)]
pub enum Const<'tcx> {
/// This constant came from the type system.
///
@ -456,7 +456,7 @@ impl<'tcx> Const<'tcx> {
/// An unevaluated (potentially generic) constant used in MIR.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct UnevaluatedConst<'tcx> {
pub def: DefId,
pub args: GenericArgsRef<'tcx>,

View file

@ -108,7 +108,7 @@ impl<'tcx> TyCtxt<'tcx> {
let mir_body = self.mir_for_ctfe(instance.def_id());
if mir_body.is_polymorphic {
let Some(local_def_id) = ct.def.as_local() else { return };
self.struct_span_lint_hir(
self.node_span_lint(
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
self.local_def_id_to_hir_id(local_def_id),
self.def_span(ct.def),

View file

@ -1672,19 +1672,13 @@ mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// tidy-alphabetical-start
// This can be removed after i128:128 is in the bootstrap compiler's target.
#[cfg(not(bootstrap))]
static_assert_size!(BasicBlockData<'_>, 144);
static_assert_size!(BasicBlockData<'_>, 136);
static_assert_size!(LocalDecl<'_>, 40);
static_assert_size!(SourceScopeData<'_>, 72);
static_assert_size!(Statement<'_>, 32);
static_assert_size!(StatementKind<'_>, 16);
// This can be removed after i128:128 is in the bootstrap compiler's target.
#[cfg(not(bootstrap))]
static_assert_size!(Terminator<'_>, 112);
// This can be removed after i128:128 is in the bootstrap compiler's target.
#[cfg(not(bootstrap))]
static_assert_size!(TerminatorKind<'_>, 96);
static_assert_size!(Terminator<'_>, 104);
static_assert_size!(TerminatorKind<'_>, 88);
static_assert_size!(VarDebugInfo<'_>, 88);
// tidy-alphabetical-end
}

Some files were not shown because too many files have changed in this diff Show more