Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #123725

Merged
merged 29 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1512d06
Add support to intrinsics fallback body
celinval Apr 5, 2024
03c901f
Add redundant_lifetime_args lint
compiler-errors Nov 27, 2023
8940949
Actually, just reuse the UNUSED_LIFETIMES lint
compiler-errors Nov 27, 2023
535151e
Add comments
compiler-errors Nov 27, 2023
ceff692
Fix stage 2
compiler-errors Nov 27, 2023
2d81354
Move check to wfcheck
compiler-errors Nov 29, 2023
ee78eab
Lint redundant lifetimes in impl header
compiler-errors Dec 5, 2023
a9e262a
Split back out unused_lifetimes -> redundant_lifetimes
compiler-errors Dec 16, 2023
da2b714
Clarifying comment
compiler-errors Mar 27, 2024
a2bdb99
Add const generics failing test for pattern types
spastorino Apr 9, 2024
5f84f4b
rustdoc: clean up type alias code
notriddle Mar 30, 2024
30c546a
Handle const generic pattern types
spastorino Feb 20, 2024
b48e7e5
Add const UTF-8 to UTF-16 conversion macros
ChrisDenton Apr 6, 2024
952d432
Windows: set main thread name without reencoding
ChrisDenton Apr 6, 2024
19f04a7
Add comment on UTF-16 surrogates
ChrisDenton Apr 8, 2024
0c3f5cc
Further cleanup cfgs in the UI test suite
Urgau Apr 9, 2024
dac788f
rustdoc: reduce size of `<head>` with preload loop
notriddle Apr 9, 2024
13235dc
rustdoc: load icons from css instead of inline
notriddle Apr 10, 2024
87faa21
rustdoc: remove unused 16x16 favicon
notriddle Apr 10, 2024
3a007db
rustdoc: update test cases
notriddle Apr 10, 2024
1cbe927
Only avoid anon consts during instantiation
oli-obk Apr 10, 2024
69b690f
Only assert for child/parent projection compatibility AFTER checking …
compiler-errors Apr 9, 2024
fa696a3
Rollup merge of #118391 - compiler-errors:lifetimes-eq, r=lcnr
GuillaumeGomez Apr 10, 2024
38af5f9
Rollup merge of #123534 - ChrisDenton:name, r=workingjubilee
GuillaumeGomez Apr 10, 2024
2b4c581
Rollup merge of #123659 - celinval:smir-fix-intrinsic, r=oli-obk
GuillaumeGomez Apr 10, 2024
3f7ae68
Rollup merge of #123689 - spastorino:pattern_types_const_generics, r=…
GuillaumeGomez Apr 10, 2024
1002c65
Rollup merge of #123701 - compiler-errors:only-assert-after-checking,…
GuillaumeGomez Apr 10, 2024
7a29d39
Rollup merge of #123702 - Urgau:prep-work-for-compiletest-check-cfg-2…
GuillaumeGomez Apr 10, 2024
96628f4
Rollup merge of #123706 - notriddle:notriddle/html-cleanup, r=Guillau…
GuillaumeGomez Apr 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T {
}
}

#[macro_export]
macro_rules! into_diag_arg_using_display {
($( $ty:ty ),+ $(,)?) => {
$(
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,9 @@ hir_analysis_pattern_type_wild_pat = "wildcard patterns are not permitted for pa
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
.label = not allowed in type signatures

hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
.note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`

hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}`

hir_analysis_return_type_notation_equality_bound =
Expand Down
135 changes: 135 additions & 0 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::ItemKind;
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_macros::LintDiagnostic;
use rustc_middle::query::Providers;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::trait_def::TraitSpecializationKind;
Expand Down Expand Up @@ -136,6 +138,8 @@ where
infcx.implied_bounds_tys_compat(param_env, body_def_id, &assumed_wf_types, false);
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);

lint_redundant_lifetimes(tcx, body_def_id, &outlives_env);

let errors = infcx.resolve_regions(&outlives_env);
if errors.is_empty() {
return Ok(());
Expand Down Expand Up @@ -2010,6 +2014,137 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
res
}

fn lint_redundant_lifetimes<'tcx>(
tcx: TyCtxt<'tcx>,
owner_id: LocalDefId,
outlives_env: &OutlivesEnvironment<'tcx>,
) {
let def_kind = tcx.def_kind(owner_id);
match def_kind {
DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::Trait
| DefKind::TraitAlias
| DefKind::Fn
| DefKind::Const
| DefKind::Impl { of_trait: _ } => {
// Proceed
}
DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
let parent_def_id = tcx.local_parent(owner_id);
if matches!(tcx.def_kind(parent_def_id), DefKind::Impl { of_trait: true }) {
// Don't check for redundant lifetimes for associated items of trait
// implementations, since the signature is required to be compatible
// with the trait, even if the implementation implies some lifetimes
// are redundant.
return;
}
}
DefKind::Mod
| DefKind::Variant
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TyParam
| DefKind::ConstParam
| DefKind::Static { .. }
| DefKind::Ctor(_, _)
| DefKind::Macro(_)
| DefKind::ExternCrate
| DefKind::Use
| DefKind::ForeignMod
| DefKind::AnonConst
| DefKind::InlineConst
| DefKind::OpaqueTy
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Closure => return,
}

// The ordering of this lifetime map is a bit subtle.
//
// Specifically, we want to find a "candidate" lifetime that precedes a "victim" lifetime,
// where we can prove that `'candidate = 'victim`.
//
// `'static` must come first in this list because we can never replace `'static` with
// something else, but if we find some lifetime `'a` where `'a = 'static`, we want to
// suggest replacing `'a` with `'static`.
let mut lifetimes = vec![tcx.lifetimes.re_static];
lifetimes.extend(
ty::GenericArgs::identity_for_item(tcx, owner_id).iter().filter_map(|arg| arg.as_region()),
);
// If we are in a function, add its late-bound lifetimes too.
if matches!(def_kind, DefKind::Fn | DefKind::AssocFn) {
for var in tcx.fn_sig(owner_id).instantiate_identity().bound_vars() {
let ty::BoundVariableKind::Region(kind) = var else { continue };
lifetimes.push(ty::Region::new_late_param(tcx, owner_id.to_def_id(), kind));
}
}
lifetimes.retain(|candidate| candidate.has_name());

// Keep track of lifetimes which have already been replaced with other lifetimes.
// This makes sure that if `'a = 'b = 'c`, we don't say `'c` should be replaced by
// both `'a` and `'b`.
let mut shadowed = FxHashSet::default();

for (idx, &candidate) in lifetimes.iter().enumerate() {
// Don't suggest removing a lifetime twice. We only need to check this
// here and not up in the `victim` loop because equality is transitive,
// so if A = C and B = C, then A must = B, so it'll be shadowed too in
// A's victim loop.
if shadowed.contains(&candidate) {
continue;
}

for &victim in &lifetimes[(idx + 1)..] {
// We should only have late-bound lifetimes of the `BrNamed` variety,
// since we get these signatures straight from `hir_lowering`. And any
// other regions (ReError/ReStatic/etc.) shouldn't matter, since we
// can't really suggest to remove them.
let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
| ty::ReLateParam(ty::LateParamRegion {
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
..
})) = victim.kind()
else {
continue;
};

// Do not rename lifetimes not local to this item since they'll overlap
// with the lint running on the parent. We still want to consider parent
// lifetimes which make child lifetimes redundant, otherwise we would
// have truncated the `identity_for_item` args above.
if tcx.parent(def_id) != owner_id.to_def_id() {
continue;
}

// If `candidate <: victim` and `victim <: candidate`, then they're equal.
if outlives_env.free_region_map().sub_free_regions(tcx, candidate, victim)
&& outlives_env.free_region_map().sub_free_regions(tcx, victim, candidate)
{
shadowed.insert(victim);
tcx.emit_node_span_lint(
rustc_lint_defs::builtin::REDUNDANT_LIFETIMES,
tcx.local_def_id_to_hir_id(def_id.expect_local()),
tcx.def_span(def_id),
RedundantLifetimeArgsLint { candidate, victim },
);
}
}
}
}

#[derive(LintDiagnostic)]
#[diag(hir_analysis_redundant_lifetime_args)]
#[note]
struct RedundantLifetimeArgsLint<'tcx> {
/// The lifetime we have found to be redundant.
victim: ty::Region<'tcx>,
// The lifetime we can replace the victim with.
candidate: ty::Region<'tcx>,
}

pub fn provide(providers: &mut Providers) {
*providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
}
26 changes: 0 additions & 26 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::*;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_session::lint;
use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
Expand Down Expand Up @@ -867,31 +866,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}) => {
self.visit_lifetime(lifetime);
walk_list!(self, visit_param_bound, bounds);

if lifetime.res != hir::LifetimeName::Static {
for bound in bounds {
let hir::GenericBound::Outlives(lt) = bound else {
continue;
};
if lt.res != hir::LifetimeName::Static {
continue;
}
self.insert_lifetime(lt, ResolvedArg::StaticLifetime);
self.tcx.node_span_lint(
lint::builtin::UNUSED_LIFETIMES,
lifetime.hir_id,
lifetime.ident.span,
format!("unnecessary lifetime parameter `{}`", lifetime.ident),
|lint| {
let help = format!(
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime.ident,
);
lint.help(help);
},
);
}
}
}
&hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
self.visit_ty(lhs_ty);
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2223,6 +2223,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Err(LitToConstError::TypeError) => todo!(),
}
}

hir::ExprKind::Path(hir::QPath::Resolved(
_,
&hir::Path {
res: Res::Def(DefKind::ConstParam, def_id), ..
},
)) => {
let ty = tcx
.type_of(def_id)
.no_bound_vars()
.expect("const parameter types cannot be generic");
let item_def_id = tcx.parent(def_id);
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id];
let name = tcx.item_name(def_id);
ty::Const::new_param(tcx, ty::ParamConst::new(index, name), ty)
}

_ => {
let err = tcx
.dcx()
Expand Down
28 changes: 28 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ declare_lint_pass! {
PROC_MACRO_BACK_COMPAT,
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
REDUNDANT_LIFETIMES,
REFINING_IMPL_TRAIT_INTERNAL,
REFINING_IMPL_TRAIT_REACHABLE,
RENAMED_AND_REMOVED_LINTS,
Expand Down Expand Up @@ -1707,6 +1708,33 @@ declare_lint! {
"detects lifetime parameters that are never used"
}

declare_lint! {
/// The `redundant_lifetimes` lint detects lifetime parameters that are
/// redundant because they are equal to another named lifetime.
///
/// ### Example
///
/// ```rust,compile_fail
/// #[deny(redundant_lifetimes)]
///
/// // `'a = 'static`, so all usages of `'a` can be replaced with `'static`
/// pub fn bar<'a: 'static>() {}
///
/// // `'a = 'b`, so all usages of `'b` can be replaced with `'a`
/// pub fn bar<'a: 'b, 'b: 'a>() {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Unused lifetime parameters may signal a mistake or unfinished code.
/// Consider removing the parameter.
pub REDUNDANT_LIFETIMES,
Allow,
"detects lifetime parameters that are redundant because they are equal to some other named lifetime"
}

declare_lint! {
/// The `tyvar_behind_raw_pointer` lint detects raw pointer to an
/// inference variable.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ pub struct GlobalCtxt<'tcx> {
impl<'tcx> GlobalCtxt<'tcx> {
/// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
/// `f`.
pub fn enter<'a: 'tcx, F, R>(&'a self, f: F) -> R
pub fn enter<F, R>(&'tcx self, f: F) -> R
where
F: FnOnce(TyCtxt<'tcx>) -> R,
{
Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_middle/src/ty/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@ use std::fmt::Write;
use std::ops::ControlFlow;

use crate::ty::{
AliasTy, Const, ConstKind, FallibleTypeFolder, InferConst, InferTy, Opaque, PolyTraitPredicate,
Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitor,
self, AliasTy, Const, ConstKind, FallibleTypeFolder, InferConst, InferTy, Opaque,
PolyTraitPredicate, Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
TypeSuperVisitable, TypeVisitable, TypeVisitor,
};

use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, Diag, DiagArgValue, IntoDiagArg};
use rustc_errors::{into_diag_arg_using_display, Applicability, Diag, DiagArgValue, IntoDiagArg};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{PredicateOrigin, WherePredicate};
use rustc_span::{BytePos, Span};
use rustc_type_ir::TyKind::*;

impl<'tcx> IntoDiagArg for Ty<'tcx> {
fn into_diag_arg(self) -> DiagArgValue {
self.to_string().into_diag_arg()
}
into_diag_arg_using_display! {
Ty<'_>,
ty::Region<'_>,
}

impl<'tcx> Ty<'tcx> {
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
}) {
let (child_field_idx, child_capture) = child_captures.next().unwrap();

// This analysis only makes sense if the parent capture is a
// prefix of the child capture.
assert!(
child_capture.place.projections.len() >= parent_capture.place.projections.len(),
"parent capture ({parent_capture:#?}) expected to be prefix of \
child capture ({child_capture:#?})"
);

// Store this set of additional projections (fields and derefs).
// We need to re-apply them later.
let child_precise_captures =
Expand Down Expand Up @@ -244,7 +252,6 @@ fn child_prefix_matches_parent_projections(
bug!("expected capture to be an upvar");
};

assert!(child_capture.place.projections.len() >= parent_capture.place.projections.len());
parent_base.var_path.hir_id == child_base.var_path.hir_id
&& std::iter::zip(&child_capture.place.projections, &parent_capture.place.projections)
.all(|(child, parent)| child.kind == parent.kind)
Expand Down
Loading
Loading