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 12 pull requests #131948

Merged
merged 25 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7ff71e5
Remove invalid help diagnostics for const pointer
chenyukang Jul 13, 2024
e9cf280
warn less about non-exhaustive in ffi
workingjubilee Oct 17, 2023
99d5f3b
Stop inverting expectation in normalization errors
compiler-errors Oct 16, 2024
6d88158
Remove TODO in proc_macro now `const_refs_to_static` is stable
GnomedDev Oct 16, 2024
62aa8f0
compiler: Embed consensus in `lint::types::improper_ctypes`
workingjubilee Sep 19, 2024
aa299a9
Add codegen test for branchy bool match
clubby789 Oct 19, 2024
d841146
replace STATX_ALL with (STATX_BASIC_STATS | STATX_BTIME) as former is…
klensy Oct 19, 2024
d82a21f
Warn on redundant `--cfg` directive when revisions are used
clubby789 Oct 19, 2024
fa47823
use tracked_path in rustc_fluent_macro
usamoi Oct 19, 2024
ad2a649
Remove unnecessary constness
compiler-errors Oct 19, 2024
d1fa49b
feat(rustdoc-json-types): introduce rustc-hash feature
jalil-salame Oct 19, 2024
9989b1b
Use PredicateFilter instead of OnlySelfBounds
compiler-errors Oct 19, 2024
70746d0
Make sure that outer opaques capture inner opaques's lifetimes even w…
compiler-errors Oct 16, 2024
b2d132f
Rollup merge of #116863 - workingjubilee:non-exhaustive-is-not-ffi-un…
matthiaskrgr Oct 19, 2024
268fa31
Rollup merge of #127675 - chenyukang:yukang-fix-127562-addr, r=petroc…
matthiaskrgr Oct 19, 2024
e0b8e78
Rollup merge of #131772 - GnomedDev:remove-proc_macro-todo, r=petroch…
matthiaskrgr Oct 19, 2024
bc22740
Rollup merge of #131789 - compiler-errors:capture-more, r=fmease
matthiaskrgr Oct 19, 2024
559f8ce
Rollup merge of #131795 - compiler-errors:expectation, r=Nadrieril
matthiaskrgr Oct 19, 2024
91e4684
Rollup merge of #131920 - clubby789:108395-test, r=jieyouxu
matthiaskrgr Oct 19, 2024
d881cc6
Rollup merge of #131921 - klensy:statx_all, r=ChrisDenton
matthiaskrgr Oct 19, 2024
efd940d
Rollup merge of #131925 - clubby789:redundant-revision-cfg, r=jieyouxu
matthiaskrgr Oct 19, 2024
426e906
Rollup merge of #131931 - compiler-errors:constness-valid, r=fmease
matthiaskrgr Oct 19, 2024
d077d9b
Rollup merge of #131932 - usamoi:tracked-path, r=Nadrieril
matthiaskrgr Oct 19, 2024
ab7e0d0
Rollup merge of #131936 - jalil-salame:rustdoc-types-rustc-hash, r=aD…
matthiaskrgr Oct 19, 2024
2ecfdba
Rollup merge of #131939 - compiler-errors:predicate-filter, r=fmease
matthiaskrgr Oct 19, 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
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
.collect();

// Introduce extra lifetimes if late resolution tells us to.
let extra_lifetimes = self.resolver.take_extra_lifetime_params(parent_node_id);
let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id);
params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
self.lifetime_res_to_generic_param(
ident,
Expand Down
79 changes: 21 additions & 58 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ impl ResolverAstLowering {
///
/// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
/// should appear at the enclosing `PolyTraitRef`.
fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
self.extra_lifetime_params_map.remove(&id).unwrap_or_default()
fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default()
}
}

Expand Down Expand Up @@ -885,7 +885,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let mut generic_params: Vec<_> = self
.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
.collect();
let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder);
let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
debug!(?extra_lifetimes);
generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
Expand Down Expand Up @@ -1495,62 +1495,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);

let captured_lifetimes_to_duplicate = if let Some(args) =
// We only look for one `use<...>` syntax since we syntactially reject more than one.
bounds.iter().find_map(
|bound| match bound {
ast::GenericBound::Use(a, _) => Some(a),
_ => None,
},
) {
// We'll actually validate these later on; all we need is the list of
// lifetimes to duplicate during this portion of lowering.
args.iter()
.filter_map(|arg| match arg {
PreciseCapturingArg::Lifetime(lt) => Some(*lt),
PreciseCapturingArg::Arg(..) => None,
})
// Add in all the lifetimes mentioned in the bounds. We will error
// them out later, but capturing them here is important to make sure
// they actually get resolved in resolve_bound_vars.
.chain(lifetime_collector::lifetimes_in_bounds(self.resolver, bounds))
.collect()
} else {
match origin {
hir::OpaqueTyOrigin::TyAlias { .. } => {
// type alias impl trait and associated type position impl trait were
// decided to capture all in-scope lifetimes, which we collect for
// all opaques during resolution.
self.resolver
.take_extra_lifetime_params(opaque_ty_node_id)
.into_iter()
.map(|(ident, id, _)| Lifetime { id, ident })
.collect()
}
hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => {
if in_trait_or_impl.is_some()
|| self.tcx.features().lifetime_capture_rules_2024
|| span.at_least_rust_2024()
{
// return-position impl trait in trait was decided to capture all
// in-scope lifetimes, which we collect for all opaques during resolution.
self.resolver
.take_extra_lifetime_params(opaque_ty_node_id)
.into_iter()
.map(|(ident, id, _)| Lifetime { id, ident })
.collect()
} else {
// in fn return position, like the `fn test<'a>() -> impl Debug + 'a`
// example, we only need to duplicate lifetimes that appear in the
// bounds, since those are the only ones that are captured by the opaque.
lifetime_collector::lifetimes_in_bounds(self.resolver, bounds)
}
}
hir::OpaqueTyOrigin::AsyncFn { .. } => {
unreachable!("should be using `lower_async_fn_ret_ty`")
}
// Whether this opaque always captures lifetimes in scope.
// Right now, this is all RPITIT and TAITs, and when `lifetime_capture_rules_2024`
// is enabled. We don't check the span of the edition, since this is done
// on a per-opaque basis to account for nested opaques.
let always_capture_in_scope = match origin {
_ if self.tcx.features().lifetime_capture_rules_2024 => true,
hir::OpaqueTyOrigin::TyAlias { .. } => true,
hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => in_trait_or_impl.is_some(),
hir::OpaqueTyOrigin::AsyncFn { .. } => {
unreachable!("should be using `lower_coroutine_fn_ret_ty`")
}
};
let captured_lifetimes_to_duplicate = lifetime_collector::lifetimes_for_opaque(
self.resolver,
always_capture_in_scope,
opaque_ty_node_id,
bounds,
span,
);
debug!(?captured_lifetimes_to_duplicate);

// Feature gate for RPITIT + use<..>
Expand Down Expand Up @@ -1920,7 +1883,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

let captured_lifetimes = self
.resolver
.take_extra_lifetime_params(opaque_ty_node_id)
.extra_lifetime_params(opaque_ty_node_id)
.into_iter()
.map(|(ident, id, _)| Lifetime { id, ident })
.collect();
Expand Down
53 changes: 43 additions & 10 deletions compiler/rustc_ast_lowering/src/lifetime_collector.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor};
use rustc_ast::{GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind};
use rustc_ast::{
GenericBound, GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind,
};
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir::def::{DefKind, LifetimeRes, Res};
use rustc_middle::span_bug;
Expand All @@ -10,14 +12,41 @@ use rustc_span::symbol::{Ident, kw};
use super::ResolverAstLoweringExt;

struct LifetimeCollectVisitor<'ast> {
resolver: &'ast ResolverAstLowering,
resolver: &'ast mut ResolverAstLowering,
always_capture_in_scope: bool,
current_binders: Vec<NodeId>,
collected_lifetimes: FxIndexSet<Lifetime>,
}

impl<'ast> LifetimeCollectVisitor<'ast> {
fn new(resolver: &'ast ResolverAstLowering) -> Self {
Self { resolver, current_binders: Vec::new(), collected_lifetimes: FxIndexSet::default() }
fn new(resolver: &'ast mut ResolverAstLowering, always_capture_in_scope: bool) -> Self {
Self {
resolver,
always_capture_in_scope,
current_binders: Vec::new(),
collected_lifetimes: FxIndexSet::default(),
}
}

fn visit_opaque(&mut self, opaque_ty_node_id: NodeId, bounds: &'ast GenericBounds, span: Span) {
// If we're edition 2024 or within a TAIT or RPITIT, *and* there is no
// `use<>` statement to override the default capture behavior, then
// capture all of the in-scope lifetimes.
if (self.always_capture_in_scope || span.at_least_rust_2024())
&& bounds.iter().all(|bound| !matches!(bound, GenericBound::Use(..)))
{
for (ident, id, _) in self.resolver.extra_lifetime_params(opaque_ty_node_id) {
self.record_lifetime_use(Lifetime { id, ident });
}
}

// We also recurse on the bounds to make sure we capture all the lifetimes
// mentioned in the bounds. These may disagree with the `use<>` list, in which
// case we will error on these later. We will also recurse to visit any
// nested opaques, which may *implicitly* capture lifetimes.
for bound in bounds {
self.visit_param_bound(bound, BoundKind::Bound);
}
}

fn record_lifetime_use(&mut self, lifetime: Lifetime) {
Expand Down Expand Up @@ -99,20 +128,24 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
self.record_elided_anchor(t.id, t.span);
visit::walk_ty(self, t);
}
TyKind::ImplTrait(opaque_ty_node_id, bounds) => {
self.visit_opaque(*opaque_ty_node_id, bounds, t.span)
}
_ => {
visit::walk_ty(self, t);
}
}
}
}

pub(crate) fn lifetimes_in_bounds(
resolver: &ResolverAstLowering,
pub(crate) fn lifetimes_for_opaque(
resolver: &mut ResolverAstLowering,
always_capture_in_scope: bool,
opaque_ty_node_id: NodeId,
bounds: &GenericBounds,
span: Span,
) -> FxIndexSet<Lifetime> {
let mut visitor = LifetimeCollectVisitor::new(resolver);
for bound in bounds {
visitor.visit_param_bound(bound, BoundKind::Bound);
}
let mut visitor = LifetimeCollectVisitor::new(resolver, always_capture_in_scope);
visitor.visit_opaque(opaque_ty_node_id, bounds, span);
visitor.collected_lifetimes
}
33 changes: 21 additions & 12 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}
// don't create labels for compiler-generated spans
Some(_) => None,
// don't create labels for the span not from user's code
None if opt_assignment_rhs_span
.is_some_and(|span| self.infcx.tcx.sess.source_map().is_imported(span)) =>
{
None
}
None => {
let (has_sugg, decl_span, sugg) = if name != kw::SelfLower {
suggest_ampmut(
Expand Down Expand Up @@ -1198,18 +1204,21 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
sugg.push(s);
}

err.multipart_suggestion_verbose(
format!(
"consider changing this to be a mutable {pointer_desc}{}",
if is_trait_sig {
" in the `impl` method and the `trait` definition"
} else {
""
}
),
sugg,
Applicability::MachineApplicable,
);
if sugg.iter().all(|(span, _)| !self.infcx.tcx.sess.source_map().is_imported(*span))
{
err.multipart_suggestion_verbose(
format!(
"consider changing this to be a mutable {pointer_desc}{}",
if is_trait_sig {
" in the `impl` method and the `trait` definition"
} else {
""
}
),
sugg,
Applicability::MachineApplicable,
);
}
}
Some((false, err_label_span, message, _)) => {
let def_id = self.body.source.def_id();
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_fluent_macro/src/fluent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use fluent_syntax::ast::{
Attribute, Entry, Expression, Identifier, InlineExpression, Message, Pattern, PatternElement,
};
use fluent_syntax::parser::ParserError;
use proc_macro::tracked_path::path;
use proc_macro::{Diagnostic, Level, Span};
use proc_macro2::TokenStream;
use quote::quote;
Expand Down Expand Up @@ -99,8 +100,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok

let crate_name = Ident::new(&crate_name, resource_str.span());

// As this macro also outputs an `include_str!` for this file, the macro will always be
// re-executed when the file changes.
path(absolute_ftl_path.to_str().unwrap());
let resource_contents = match read_to_string(absolute_ftl_path) {
Ok(resource_contents) => resource_contents,
Err(e) => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_fluent_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_span)]
#![feature(rustdoc_internals)]
#![feature(track_path)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end

Expand Down
15 changes: 12 additions & 3 deletions compiler/rustc_hir_analysis/src/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
use rustc_span::Span;
use rustc_span::def_id::DefId;

use crate::hir_ty_lowering::OnlySelfBounds;
use crate::hir_ty_lowering::PredicateFilter;

/// Collects together a list of type bounds. These lists of bounds occur in many places
/// in Rust's syntax:
Expand Down Expand Up @@ -52,7 +52,7 @@ impl<'tcx> Bounds<'tcx> {
span: Span,
polarity: ty::PredicatePolarity,
constness: ty::BoundConstness,
only_self_bounds: OnlySelfBounds,
predicate_filter: PredicateFilter,
) {
let clause = (
bound_trait_ref
Expand All @@ -72,9 +72,18 @@ impl<'tcx> Bounds<'tcx> {
// FIXME(effects): Lift this out of `push_trait_bound`, and move it somewhere else.
// Perhaps moving this into `lower_poly_trait_ref`, just like we lower associated
// type bounds.
if !tcx.features().effects || only_self_bounds.0 {
if !tcx.features().effects {
return;
}
match predicate_filter {
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
return;
}
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
// Ok.
}
}

// For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the
// associated type of `<T as Tr>` and make sure that the effect is compatible.
let compat_val = match (tcx.def_kind(defining_def_id), constness) {
Expand Down
40 changes: 4 additions & 36 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::bounds::Bounds;
use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp;
use crate::delegation::inherit_predicates_for_delegation_item;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason};
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter, RegionInferReason};

/// Returns a list of all type predicates (explicit and implicit) for the definition with
/// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
Expand Down Expand Up @@ -270,7 +270,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
bound_pred.bounds.iter(),
&mut bounds,
bound_vars,
OnlySelfBounds(false),
PredicateFilter::All,
);
predicates.extend(bounds.clauses(tcx));
effects_min_tys.extend(bounds.effects_min_tys());
Expand Down Expand Up @@ -825,20 +825,6 @@ impl<'tcx> ItemCtxt<'tcx> {
continue;
};

// Subtle: If we're collecting `SelfAndAssociatedTypeBounds`, then we
// want to only consider predicates with `Self: ...`, but we don't want
// `OnlySelfBounds(true)` since we want to collect the nested associated
// type bound as well.
let (only_self_bounds, assoc_name) = match filter {
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
(OnlySelfBounds(false), None)
}
PredicateFilter::SelfOnly => (OnlySelfBounds(true), None),
PredicateFilter::SelfThatDefines(assoc_name) => {
(OnlySelfBounds(true), Some(assoc_name))
}
};

let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
ty
} else if matches!(filter, PredicateFilter::All) {
Expand All @@ -850,31 +836,13 @@ impl<'tcx> ItemCtxt<'tcx> {
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
self.lowerer().lower_poly_bounds(
bound_ty,
predicate.bounds.iter().filter(|bound| {
assoc_name
.map_or(true, |assoc_name| self.bound_defines_assoc_item(bound, assoc_name))
}),
predicate.bounds.iter(),
&mut bounds,
bound_vars,
only_self_bounds,
filter,
);
}

bounds.clauses(self.tcx).collect()
}

#[instrument(level = "trace", skip(self))]
fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
match b {
hir::GenericBound::Trait(poly_trait_ref) => {
let trait_ref = &poly_trait_ref.trait_ref;
if let Some(trait_did) = trait_ref.trait_def_id() {
self.tcx.trait_may_define_assoc_item(trait_did, assoc_name)
} else {
false
}
}
_ => false,
}
}
}
Loading
Loading