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

Point at explicit 'static obligations on a trait #129070

Merged
merged 1 commit into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ fn region_known_to_outlive<'tcx>(
region_b: ty::Region<'tcx>,
) -> bool {
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
infcx.sub_regions(infer::RelateRegionParamBound(DUMMY_SP), region_b, region_a);
infcx.sub_regions(infer::RelateRegionParamBound(DUMMY_SP, None), region_b, region_a);
})
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
}

fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) {
self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup)
self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None), sub, sup)
}

fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) {
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ pub enum SubregionOrigin<'tcx> {

/// The given region parameter was instantiated with a region
/// that must outlive some other region.
RelateRegionParamBound(Span),
RelateRegionParamBound(Span, Option<Ty<'tcx>>),

/// Creating a pointer `b` to contents of another reference.
Reborrow(Span),
Expand Down Expand Up @@ -859,7 +859,7 @@ impl<'tcx> InferCtxt<'tcx> {
) {
self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
let origin = SubregionOrigin::from_obligation_cause(cause, || {
RelateRegionParamBound(cause.span)
RelateRegionParamBound(cause.span, None)
});
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
})
Expand Down Expand Up @@ -1685,7 +1685,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
Subtype(ref a) => a.span(),
RelateObjectBound(a) => a,
RelateParamBound(a, ..) => a,
RelateRegionParamBound(a) => a,
RelateRegionParamBound(a, _) => a,
Reborrow(a) => a,
ReferenceOutlivesReferent(_, a) => a,
CompareImplItemObligation { span, .. } => span,
Expand Down Expand Up @@ -1726,6 +1726,10 @@ impl<'tcx> SubregionOrigin<'tcx> {
SubregionOrigin::AscribeUserTypeProvePredicate(span)
}

traits::ObligationCauseCode::ObjectTypeBound(ty, _reg) => {
SubregionOrigin::RelateRegionParamBound(cause.span, Some(ty))
}

_ => default(),
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
pub(super) fn try_report_placeholder_relation(&self) -> Option<Diag<'tcx>> {
match &self.error {
Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::RelateRegionParamBound(span),
SubregionOrigin::RelateRegionParamBound(span, _),
Region(Interned(
RePlaceholder(ty::Placeholder {
bound: ty::BoundRegion { kind: sub_name, .. },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
.add_to_diag(err);
}
}
infer::RelateRegionParamBound(span) => {
infer::RelateRegionParamBound(span, _) => {
RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
.add_to_diag(err);
}
Expand Down Expand Up @@ -199,7 +199,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
note,
})
}
infer::RelateRegionParamBound(span) => {
infer::RelateRegionParamBound(span, _) => {
let param_instantiated = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
Expand Down
26 changes: 23 additions & 3 deletions compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
.add_to_diag(err);
}
}
infer::RelateRegionParamBound(span) => {
infer::RelateRegionParamBound(span, _) => {
RegionOriginNote::Plain {
span,
msg: fluent::trait_selection_relate_region_param_bound,
Expand Down Expand Up @@ -410,7 +410,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
note,
})
}
infer::RelateRegionParamBound(span) => {
infer::RelateRegionParamBound(span, ty) => {
let param_instantiated = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
Expand All @@ -419,11 +419,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
note_and_explain::PrefixKind::LfParamInstantiatedWith,
note_and_explain::SuffixKind::Empty,
);
let mut alt_span = None;
if let Some(ty) = ty
&& sub.is_static()
&& let ty::Dynamic(preds, _, ty::DynKind::Dyn) = ty.kind()
&& let Some(def_id) = preds.principal_def_id()
{
for (clause, span) in
self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
{
if let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) =
clause.kind().skip_binder()
&& let ty::Param(param) = a.kind()
&& param.name == kw::SelfUpper
&& b.is_static()
{
// Point at explicit `'static` bound on the trait (`trait T: 'static`).
alt_span = Some(span);
}
}
}
let param_must_outlive = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sub,
None,
alt_span,
note_and_explain::PrefixKind::LfParamMustOutlive,
note_and_explain::SuffixKind::Empty,
);
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/regions/explicit-static-bound-on-trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
struct Hello<'a> {
value: Box<dyn std::any::Any + 'a>,
//~^ ERROR lifetime bound not satisfied
}

impl<'a> Hello<'a> {
fn new<T: 'a>(value: T) -> Self {
Self { value: Box::new(value) }
//~^ ERROR the parameter type `T` may not live long enough
}
}

fn main() {}
32 changes: 32 additions & 0 deletions tests/ui/regions/explicit-static-bound-on-trait.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
error[E0478]: lifetime bound not satisfied
--> $DIR/explicit-static-bound-on-trait.rs:2:12
|
LL | value: Box<dyn std::any::Any + 'a>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
--> $DIR/explicit-static-bound-on-trait.rs:1:14
|
LL | struct Hello<'a> {
| ^^
note: but lifetime parameter must outlive the static lifetime
--> $SRC_DIR/core/src/any.rs:LL:COL
Comment on lines +12 to +13
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Locally this actually show the right span, not sure why the stderr doesn't show it correctly.

Copy link
Member

@compiler-errors compiler-errors Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably has to do with the sorting of the entries. Try to put the Option<Ty> first?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no, because we strip standard library sources in UI tests.


error[E0310]: the parameter type `T` may not live long enough
--> $DIR/explicit-static-bound-on-trait.rs:8:23
|
LL | Self { value: Box::new(value) }
| ^^^^^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
LL | fn new<T: 'a + 'static>(value: T) -> Self {
| +++++++++
Comment on lines +15 to +27
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actual error that we should add context for in order to also support traits that are implicitly 'static because of the trait.


error: aborting due to 2 previous errors

Some errors have detailed explanations: E0310, E0478.
For more information about an error, try `rustc --explain E0310`.
Loading