Skip to content

Don't check unnecessarily that impl trait is RPIT #114301

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

Merged
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
9 changes: 5 additions & 4 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,8 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
for (region_a, region_a_idx) in &regions {
// Ignore `'static` lifetimes for the purpose of this lint: it's
// because we know it outlives everything and so doesn't give meaningful
// clues
if let ty::ReStatic = **region_a {
// clues. Also ignore `ReError`, to avoid knock-down errors.
if let ty::ReStatic | ty::ReError(_) = **region_a {
Copy link
Member

@spastorino spastorino Aug 1, 2023

Choose a reason for hiding this comment

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

I think you want to fix the comments above, to reflect that we also ignore ReError.

continue;
}
// For each region argument (e.g., `'a` in our example), check for a
Expand Down Expand Up @@ -596,8 +596,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
// on the GAT itself.
for (region_b, region_b_idx) in &regions {
// Again, skip `'static` because it outlives everything. Also, we trivially
// know that a region outlives itself.
if ty::ReStatic == **region_b || region_a == region_b {
// know that a region outlives itself. Also ignore `ReError`, to avoid
// knock-down errors.
if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b {
continue;
}
if region_known_to_outlive(
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2567,15 +2567,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
None,
);
if let Some(infer::RelateParamBound(_, t, _)) = origin {
let return_impl_trait =
self.tcx.return_type_impl_trait(generic_param_scope).is_some();
let t = self.resolve_vars_if_possible(t);
match t.kind() {
// We've got:
// fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
// suggest:
// fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
ty::Closure(..) | ty::Alias(ty::Opaque, ..) if return_impl_trait => {
ty::Closure(..) | ty::Alias(ty::Opaque, ..) => {
new_binding_suggestion(&mut err, type_param_span);
}
_ => {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
generic_ty: Ty<'tcx>,
min: ty::Region<'tcx>,
) -> bool {
if let ty::ReError(_) = *min {
return true;
}

match bound {
VerifyBound::IfEq(verify_if_eq_b) => {
let verify_if_eq_b = var_values.normalize(self.region_rels.tcx, *verify_if_eq_b);
Expand Down
29 changes: 1 addition & 28 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::definitions::Definitions;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{
Constness, ExprKind, HirId, ImplItemKind, ItemKind, Node, TraitCandidate, TraitItemKind,
};
use rustc_hir::{Constness, HirId, Node, TraitCandidate};
use rustc_index::IndexVec;
use rustc_macros::HashStable;
use rustc_query_system::dep_graph::DepNodeIndex;
Expand Down Expand Up @@ -1077,31 +1075,6 @@ impl<'tcx> TyCtxt<'tcx> {
return None;
}

pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
// `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures.
match self.hir().get_by_def_id(scope_def_id) {
Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {}
Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {}
Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {}
Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {}
_ => return None,
}

let ret_ty = self.type_of(scope_def_id).instantiate_identity();
match ret_ty.kind() {
ty::FnDef(_, _) => {
let sig = ret_ty.fn_sig(self);
let output = self.erase_late_bound_regions(sig.output());
output.is_impl_trait().then(|| {
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
(output, fn_decl.output.span())
})
}
_ => None,
}
}

/// Checks if the bound region is in Impl Item.
pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
let container_id = self.parent(suitable_region_binding_scope.to_def_id());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(return_position_impl_trait_in_trait)]

trait Iterable {
type Item<'a>
where
Self: 'a;

fn iter(&self) -> impl Iterator<Item = Self::Item<'missing>>;
//~^ ERROR use of undeclared lifetime name `'missing`
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0261]: use of undeclared lifetime name `'missing`
--> $DIR/missing-lt-outlives-in-rpitit-114274.rs:8:55
|
LL | fn iter(&self) -> impl Iterator<Item = Self::Item<'missing>>;
| ^^^^^^^^ undeclared lifetime
|
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
help: consider making the bound lifetime-generic with a new `'missing` lifetime
|
LL | fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>>;
| +++++++++++++
help: consider introducing lifetime `'missing` here
|
LL | fn iter<'missing>(&self) -> impl Iterator<Item = Self::Item<'missing>>;
| ++++++++++
help: consider introducing lifetime `'missing` here
|
LL | trait Iterable<'missing> {
| ++++++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0261`.