Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d83df84
test(parser): capture current behavior for fields in traits
raushan728 Aug 27, 2026
6b9210c
fix(parser): emit targeted diagnostic for fields inside traits
raushan728 Aug 31, 2026
0d1e323
When trying to recover from `for<…> dyn …` don't unconditionally trea…
fmease Sep 5, 2026
c98b786
Handle reflexive solver region constraints
Dnreikronos Aug 29, 2026
f88e474
Discharge region constraints entailed by assumptions
Dnreikronos Aug 30, 2026
5cbee6e
Include implied regions in outlives assumptions
Dnreikronos Aug 30, 2026
fdc2acb
Evaluate reflexive region constraints at the root
Dnreikronos Aug 30, 2026
4b73b07
Keep reflexive constraint handling self-contained
Dnreikronos Sep 3, 2026
ca6e6f0
Drop trivially true region constraints when canonicalizing
Dnreikronos Sep 7, 2026
b532a13
Note that OR canonicalization could drop superset ANDs
Dnreikronos Sep 8, 2026
ebff12b
Add regression test for first token source file from TokenStream FromStr
zakrad Sep 14, 2026
e478abb
Point at `'static` obligations from an fn being called
estebank Sep 21, 2026
931b8bb
Point at `'static` receiver
estebank Sep 21, 2026
ffa9001
Point at `impl dyn Trait` `'static` obligation
estebank Sep 22, 2026
7840dfe
Use better spans on local `impl dyn Trait` when pointing at `'static`…
estebank Sep 22, 2026
94dc6dd
Fix test
estebank Sep 22, 2026
fc83fc8
avoid ICEs when recovering malformed function parameters
TaKO8Ki Sep 8, 2026
a91d256
Update comment
estebank Sep 22, 2026
693bf50
Update deprecated rustc_hir imports
mejrs Sep 23, 2026
6cc4e7e
Add `inline` attribute to `NonZero::from_str`
sorairolake Sep 23, 2026
9f208cb
std::thread::available_parallelism merging linux/android/freebsd version
devnexen Feb 2, 2024
e2160bd
convert the malformed function parameter crash test to a UI test
TaKO8Ki Sep 23, 2026
5e2db49
revert "don't calculate dtors if the self ty has impossible bounds"
sjwang05 Sep 22, 2026
9d3cc46
Rollup merge of #161988 - Dnreikronos:trait_solver/reflexive_region_c…
jhpratt Sep 23, 2026
547f9aa
Rollup merge of #162498 - TaKO8Ki:fix/parser-arg-recovery-ice, r=fee1…
jhpratt Sep 23, 2026
8dbbcaa
Rollup merge of #163181 - sjwang05:revert-162715, r=oli-obk
jhpratt Sep 23, 2026
b8cf7cf
Rollup merge of #163207 - mejrs:hir_imports2, r=BoxyUwU
jhpratt Sep 23, 2026
8f3a9a1
Rollup merge of #163216 - sorairolake:inline-nonzero-from-str, r=Dark…
jhpratt Sep 23, 2026
0a4206a
Rollup merge of #120589 - devnexen:cpuaff_fbsd_upd, r=clarfonthey
jhpratt Sep 23, 2026
11682a4
Rollup merge of #162103 - raushan728:issues/161815, r=davidtwco
jhpratt Sep 23, 2026
8e5e2cc
Rollup merge of #162340 - fmease:fix-for-dyn-recovery, r=davidtwco
jhpratt Sep 23, 2026
ea4ccf9
Rollup merge of #163094 - zakrad:regr-test-48944, r=davidtwco
jhpratt Sep 23, 2026
81781bc
Rollup merge of #163115 - estebank:static-obligations-in-call, r=davi…
jhpratt Sep 23, 2026
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
10 changes: 9 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3872,6 +3872,7 @@ dependencies = [
"rustc_abi",
"rustc_apfloat",
"rustc_ast",
"rustc_attr_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_hir",
Expand Down Expand Up @@ -4129,6 +4130,7 @@ dependencies = [
"rustc_abi",
"rustc_arena",
"rustc_ast",
"rustc_attr_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
Expand Down Expand Up @@ -4204,6 +4206,7 @@ name = "rustc_incremental"
version = "0.0.0"
dependencies = [
"rand 0.9.3",
"rustc_attr_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_fs_util",
Expand Down Expand Up @@ -4325,6 +4328,7 @@ dependencies = [
"rustc_apfloat",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_ir",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
Expand Down Expand Up @@ -4403,6 +4407,7 @@ dependencies = [
"odht",
"rustc_abi",
"rustc_ast",
"rustc_attr_ir",
"rustc_attr_parsing",
"rustc_crate_store",
"rustc_data_structures",
Expand Down Expand Up @@ -4493,10 +4498,10 @@ dependencies = [
"polonius-engine",
"regex",
"rustc_abi",
"rustc_attr_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_graphviz",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_middle",
Expand Down Expand Up @@ -4539,6 +4544,7 @@ version = "0.0.0"
dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_attr_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_hir",
Expand Down Expand Up @@ -4656,6 +4662,7 @@ name = "rustc_privacy"
version = "0.0.0"
dependencies = [
"rustc_ast",
"rustc_attr_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_hir",
Expand Down Expand Up @@ -4913,6 +4920,7 @@ dependencies = [
"itertools",
"rustc_abi",
"rustc_ast",
"rustc_attr_ir",
"rustc_crate_store",
"rustc_data_structures",
"rustc_errors",
Expand Down
166 changes: 165 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! Error reporting machinery for lifetime errors.

use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, msg};
use rustc_hir as hir;
use rustc_hir::GenericBound::Trait;
use rustc_hir::QPath::Resolved;
use rustc_hir::WherePredicateKind::BoundPredicate;
use rustc_hir::def::DefKind;
use rustc_hir::def::Res::Def;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
Expand Down Expand Up @@ -391,6 +392,165 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> {
outlives_suggestion.add_suggestion(self);
}

/// Point at `'static` obligations from the item being called.
///
/// ```text
/// error[E0521]: borrowed data escapes outside of function
/// --> $DIR/static-impl-obligation.rs:163:9
/// |
/// LL | fn bar<'a>(x: &'a &'a u32) {
/// | -- - `x` is only valid in the function body
/// | |
/// | lifetime `'a` defined here
/// LL | let y: &dyn Foo = x;
/// LL | y.hello();
/// | ^^^^^^^^^
/// | |
/// | `x` escapes the function body here
/// | argument requires that `'a` must outlive `'static`
/// |
/// note: `'static` lifetime requirement from `<(dyn o::Foo + 'static)>::hello` introduced here
/// --> $DIR/static-impl-obligation.rs:158:20
/// |
/// LL | impl dyn Foo + 'static where Self: 'static {
/// | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here
/// | |
/// | lifetime requirement introduced here
/// LL | fn hello(&'static self) where Self: 'static {}
/// | ^^^^^^^^^^^^^ ^^^^^^^ lifetime requirement introduced here
/// | |
/// | lifetime requirement introduced here
/// ```
fn explain_impl_static_obligation(
&self,
diag: &mut Diag<'_>,
ty: Ty<'tcx>,
outlived_fr: RegionVid,
) {
let tcx = self.infcx.tcx;
if self.regioncx.to_error_region(outlived_fr) != Some(tcx.lifetimes.re_static) {
return;
}
let ty::FnDef(def_id, args) = ty.kind() else {
return;
};
let typing_env = self.infcx.typing_env(self.infcx.param_env);
let Ok(Some(instance)) = ty::Instance::try_resolve(
tcx,
typing_env,
*def_id,
self.infcx.deeply_resolve_ignoring_regions(args.no_bound_vars().unwrap()),
) else {
return;
};
let def_id = instance.def_id();
let mut bounds =
tcx.clauses_of(def_id)
.instantiate(tcx, instance.args)
.into_iter()
.map(|(c, sp)| (c.skip_norm_wip().as_predicate(), sp))
.filter(|(pred, _)| match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
ty::OutlivesClause(_, lt),
))
| ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
ty::OutlivesClause(_, lt),
)) if lt.is_static() => true,
_ => false,
})
.map(|(_, sp)| sp)
.collect::<Vec<Span>>();

let mut labels = FxHashMap::default();

let parent = tcx.parent(def_id);
if let Some(rcvr) =
tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().inputs().skip_binder().get(0)
{
// Look at the receiver for `&'static self`, which introduces a `'static` obligation.
// ```
// impl Foo {
// fn foo(&'static self) {}
// ^^^^^^^^^^^^^
// ```
if let ty::Ref(region, _, _) = rcvr.kind()
&& *region == tcx.lifetimes.re_static
&& let Some(assoc) = tcx.opt_associated_item(def_id)
&& assoc.is_method()
{
let def_span = tcx.def_span(def_id);
// We have a `&'static self` receiver.
if let Some(def_id) = def_id.as_local()
&& let owner = tcx.expect_hir_owner_node(def_id)
&& let Some(decl) = owner.fn_decl()
&& let Some(ty) = decl.inputs.get(0)
{
// Point at the `&'static self` receiver.
bounds.push(ty.span);
} else if !bounds.iter().any(|sp| sp.overlaps(def_span)) {
// The method is not defined on the local crate, point at the signature instead of
// just the receiver as an approximation. We don't add it if there are already
// other spans with overlap with the def `Span`, as the other will be more specific.
bounds.push(def_span)
}
}

if let DefKind::Impl { .. } = tcx.def_kind(parent)
&& let ty = tcx.type_of(parent).instantiate_identity().skip_norm_wip()
&& let ty::Dynamic(_, region) = ty.kind()
&& *region == tcx.lifetimes.re_static
{
// We have a call into a method of either `impl dyn Trait {}` or
// `impl dyn Trait + 'static {}`.
if let Some(def_id) = parent.as_local()
&& let hir::OwnerNode::Item(item) = tcx.expect_hir_owner_node(def_id)
&& let hir::ItemKind::Impl(impl_) = item.kind
&& let hir::TyKind::TraitObject(_, tagged_ref) = impl_.self_ty.kind
{
if tagged_ref.is_static() {
// impl dyn Trait + 'static {
// ^^^^^^^ lifetime requirement introduced here
bounds.push(tagged_ref.pointer().ident.span);
} else if tagged_ref.is_implicit() {
// impl dyn Trait {
// ^^^^^^^^^ `dyn Trait` introduces an...
bounds.push(impl_.self_ty.span);
labels.insert(
impl_.self_ty.span,
"`dyn Trait` introduces an implicit `'static` lifetime requirement",
);
}
} else {
// Non-local `impl`, we don't have a way to differentiate between `+ 'static`
// and bare `dyn Trait`. We point at the whole def `Span` for now.
let def_span = tcx.def_span(parent);
if !bounds.iter().any(|sp| sp.overlaps(def_span)) {
bounds.push(def_span);
}
}
}
}

if !bounds.is_empty() {
let mut multispan: MultiSpan = bounds.clone().into();
for span in bounds {
let label = labels.get(&span).unwrap_or(&"lifetime requirement introduced here");
multispan.push_span_label(span, *label);
}
multispan.push_span_context(tcx.def_span(def_id).shrink_to_lo());
if let DefKind::Impl { .. } | DefKind::Trait = tcx.def_kind(parent) {
multispan.push_span_context(tcx.def_span(parent).shrink_to_lo());
}
diag.span_note(
multispan,
format!(
"`'static` lifetime requirement from `{}` introduced here",
tcx.def_path_str(def_id)
),
);
}
}

/// Report that `longer_fr: error_vid`, which doesn't hold,
/// where `longer_fr` is a placeholder.
fn report_erroneous_rvid_reaches_placeholder(
Expand Down Expand Up @@ -503,6 +663,10 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> {
}
};

if let ConstraintCategory::CallArgument(Some(ty)) = category {
self.explain_impl_static_obligation(&mut diag, ty, outlived_fr);
}

match variance_info {
ty::VarianceDiagInfo::None => {}
ty::VarianceDiagInfo::Invariant { ty, param_index } => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ either = "1"
rustc_abi = { path = "../rustc_abi" }
rustc_apfloat = "0.2.0"
rustc_ast = { path = "../rustc_ast" }
rustc_attr_ir = { path = "../rustc_attr_ir" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_hir = { path = "../rustc_hir" }
Expand Down
20 changes: 9 additions & 11 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ use std::num::NonZero;
use std::ops::Deref;
use std::{assert_matches, mem};

use rustc_attr_ir::lang_items::LangItem;
use rustc_attr_ir::{ConstStability, StabilityLevel, find_attr};
use rustc_errors::{Diag, ErrorGuaranteed};
use rustc_hir::attrs::lang_items::LangItem;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, find_attr};
use rustc_index::bit_set::DenseBitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::visit::Visitor;
Expand Down Expand Up @@ -427,7 +428,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
/// Check the const stability of the given item (fn or trait).
fn check_callee_stability(&mut self, def_id: DefId) {
match self.tcx.lookup_const_stability(def_id) {
Some(hir::ConstStability { level: hir::StabilityLevel::Stable { .. }, .. }) => {
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
// All good.
}
None => {
Expand All @@ -443,8 +444,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
});
}
}
Some(hir::ConstStability {
level: hir::StabilityLevel::Unstable { implied_by: implied_feature, issue, .. },
Some(ConstStability {
level: StabilityLevel::Unstable { implied_by: implied_feature, issue, .. },
feature,
..
}) => {
Expand Down Expand Up @@ -858,8 +859,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
});
}
}
Some(hir::ConstStability {
level: hir::StabilityLevel::Unstable { .. },
Some(ConstStability {
level: StabilityLevel::Unstable { .. },
feature,
..
}) => {
Expand All @@ -878,10 +879,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
const_stable_indirect,
});
}
Some(hir::ConstStability {
level: hir::StabilityLevel::Stable { .. },
..
}) => {
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
// All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it
// can be *directly* invoked from stable const code) does not always
// have the `#[rustc_intrinsic_const_stable_indirect]` attribute (which controls
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/check_consts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
//! has interior mutability or needs to be dropped, as well as the visitor that emits errors when
//! it finds operations that are invalid in a certain context.

use rustc_attr_ir::find_attr;
use rustc_errors::DiagCtxtHandle;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, find_attr};
use rustc_middle::mir;
use rustc_middle::ty::{self, PolyFnSig, TyCtxt};
use rustc_span::{Symbol, bug};
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//! Concrete error types for all operations which may be invalid in a certain const context.

use hir::ConstContext;
use rustc_attr_ir::lang_items::LangItem;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, MultiSpan, msg};
use rustc_hir as hir;
use rustc_hir::attrs::lang_items::LangItem;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rustc_hir::find_attr;
use rustc_attr_ir::find_attr;
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, BasicBlock, Location};
use rustc_middle::ty::TyCtxt;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// FIXME(const_trait_impl): This API should be really reworked. It's dangerously general for
// having basically only two use-cases that act in different ways.

use rustc_attr_ir::lang_items::LangItem;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::attrs::lang_items::LangItem;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir;
use rustc_middle::mir::*;
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use rustc_attr_ir::find_attr;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{
Constness, ExprKind, ForeignItemKind, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind,
Node, TraitItem, TraitItemKind, VariantData, find_attr,
Node, TraitItem, TraitItemKind, VariantData,
};
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
Expand Down
Loading
Loading