-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Report a specialized error when a 'static
obligation comes from an impl dyn Trait
#121274
base: master
Are you sure you want to change the base?
Changes from all commits
66db972
8949695
afa5995
aebcb29
cbf4781
b870786
edb3338
d89dba1
6fde87c
2d573b6
6d8c08a
b27b9fd
551e89e
1c5993f
fefce2f
a539a0e
64b8cc9
014daaa
8766658
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ use crate::infer::outlives::components::{push_outlives_components, Component}; | |
use crate::traits::{self, Obligation, PredicateObligation}; | ||
use rustc_data_structures::fx::FxHashSet; | ||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; | ||
use rustc_span::def_id::DefId; | ||
use rustc_span::symbol::Ident; | ||
use rustc_span::Span; | ||
|
||
|
@@ -235,6 +236,37 @@ pub fn elaborate<'tcx, O: Elaboratable<'tcx>>( | |
elaborator | ||
} | ||
|
||
pub fn elaborate_predicates_of<'tcx>( | ||
tcx: TyCtxt<'tcx>, | ||
def_id: DefId, | ||
) -> Elaborator<'tcx, (ty::Predicate<'tcx>, Span)> { | ||
elaborate( | ||
tcx, | ||
tcx.predicates_of(def_id).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)), | ||
) | ||
} | ||
|
||
pub fn filter_predicates<'tcx>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this function should get moved closer to the error reporting. It doesn't seem useful to me other than for making some Also, like, what's up with the name? Also, the fact that it only filters |
||
region: ty::Region<'tcx>, | ||
check_ty: impl Fn(Ty<'tcx>) -> bool, | ||
) -> impl Fn((ty::Predicate<'tcx>, Span)) -> Option<Span> { | ||
move |(pred, span)| { | ||
let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder() else { | ||
return None; | ||
}; | ||
match clause { | ||
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r)) | ||
if r == region && check_ty(pred_ty) => | ||
{ | ||
Some(span) | ||
} | ||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(_, r)) if r == region => { | ||
Some(span) | ||
} | ||
_ => None, | ||
} | ||
} | ||
} | ||
impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { | ||
fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = O>) { | ||
// Only keep those bounds that we haven't already seen. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -451,6 +451,9 @@ pub enum ObligationCauseCode<'tcx> { | |
|
||
/// Obligations emitted during the normalization of a weak type alias. | ||
TypeAlias(InternedObligationCauseCode<'tcx>, Span, DefId), | ||
|
||
/// During borrowck we've found a method call that could have introduced a lifetime requirement. | ||
MethodCallConstraint(Ty<'tcx>, Span), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please rename this to make it clear that it's a constraint that only ever results from a region constraint category. |
||
} | ||
|
||
/// Whether a value can be extracted into a const. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// originally from rustc ./tests/ui/regions/issue-78262.rs | ||
// ICE: to get the signature of a closure, use args.as_closure().sig() not fn_sig() | ||
#![allow(clippy::upper_case_acronyms)] | ||
|
||
trait TT {} | ||
|
||
impl dyn TT + '_ { | ||
fn func(&self) {} | ||
} | ||
|
||
#[rustfmt::skip] | ||
fn main() { | ||
let f = |x: &dyn TT| x.func(); | ||
//~^ ERROR: borrowed data escapes outside of closure | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this only guaranteed to be called on a trait? Never a trait item? If not, using this function is a hazard because it only computes the predicates of the item and not its parents. I would prefer if you remove it and inline it into its callsites like:
Though if this is intended to be called on non-top-level-items, you need to use:
(and a
.map(|(clause, sp)| (clause.as_predicate(), sp))
if necessary, but you can likely rework the call-sites to operate solely onClause
s and notPredicate
s.)