Auto merge of #129244 - cjgillot:opaque-hir, r=compiler-errors

Make opaque types regular HIR nodes

Having opaque types as HIR owner introduces all sorts of complications. This PR proposes to make them regular HIR nodes instead.

I haven't gone through all the test changes yet, so there may be a few surprises.

Many thanks to `@camelid` for the first draft.
Fixes https://github.com/rust-lang/rust/issues/129023

Fixes #129099
Fixes #125843
Fixes #119716
Fixes #121422
This commit is contained in:
bors 2024-10-05 06:19:35 +00:00
commit 5a4ee43c38
105 changed files with 1056 additions and 1112 deletions

View File

@ -226,6 +226,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
fn visit_opaque_ty(&mut self, opaq: &'hir OpaqueTy<'hir>) {
self.insert(opaq.span, opaq.hir_id, Node::OpaqueTy(opaq));
self.with_parent(opaq.hir_id, |this| {
intravisit::walk_opaque_ty(this, opaq);
});
}
fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
// FIXME: use real span?
self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant));

View File

@ -1603,7 +1603,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
) -> hir::TyKind<'hir> {
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
debug!(?opaque_ty_def_id);
let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
// Map from captured (old) lifetime to synthetic (new) lifetime.
// Used to resolve lifetimes in the bounds of the opaque.
@ -1676,7 +1677,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
self.with_hir_id_owner(opaque_ty_node_id, |this| {
let opaque_ty_def = self.with_def_id_parent(opaque_ty_def_id, |this| {
// Install the remapping from old to new (if any). This makes sure that
// any lifetimes that would have resolved to the def-id of captured
// lifetimes are remapped to the new *synthetic* lifetimes of the opaque.
@ -1714,7 +1715,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let lifetime_mapping = self.arena.alloc_slice(&synthesized_lifetime_args);
let opaque_ty_item = hir::OpaqueTy {
trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
let opaque_ty_def = hir::OpaqueTy {
hir_id: opaque_ty_hir_id,
def_id: opaque_ty_def_id,
generics: this.arena.alloc(hir::Generics {
params: generic_params,
predicates: &[],
@ -1725,19 +1729,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds,
origin,
lifetime_mapping,
};
// Generate an `type Foo = impl Trait;` declaration.
trace!("registering opaque type with id {:#?}", opaque_ty_def_id);
let opaque_ty_item = hir::Item {
owner_id: hir::OwnerId { def_id: opaque_ty_def_id },
ident: Ident::empty(),
kind: hir::ItemKind::OpaqueTy(this.arena.alloc(opaque_ty_item)),
vis_span: this.lower_span(span.shrink_to_lo()),
span: this.lower_span(opaque_ty_span),
};
hir::OwnerNode::Item(this.arena.alloc(opaque_ty_item))
this.arena.alloc(opaque_ty_def)
});
let generic_args = self.arena.alloc_from_iter(
@ -1750,10 +1744,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Foo = impl Trait` is, internally, created as a child of the
// async fn, so the *type parameters* are inherited. It's
// only the lifetime parameters that we must supply.
hir::TyKind::OpaqueDef(
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
generic_args,
)
hir::TyKind::OpaqueDef(opaque_ty_def, generic_args)
}
fn lower_precise_capturing_args(

View File

@ -830,20 +830,14 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
///
/// [`OpaqueDef`]: hir::TyKind::OpaqueDef
fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
let hir = self.infcx.tcx.hir();
let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind else {
let hir::TyKind::OpaqueDef(opaque_ty, _) = hir_ty.kind else {
span_bug!(
hir_ty.span,
"lowered return type of async fn is not OpaqueDef: {:?}",
hir_ty
);
};
let opaque_ty = hir.item(id);
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
bounds: [hir::GenericBound::Trait(trait_ref, _)],
..
}) = opaque_ty.kind
if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref, _)], .. } = opaque_ty
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
&& let Some(args) = segment.args
&& let [constraint] = args.constraints

View File

@ -329,8 +329,8 @@ fn check_opaque_type_well_formed<'tcx>(
) -> Result<Ty<'tcx>, ErrorGuaranteed> {
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
// on stable and we'd break that.
let opaque_ty_hir = tcx.hir().expect_item(def_id);
let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.expect_opaque_ty().origin else {
let opaque_ty_hir = tcx.hir().expect_opaque_ty(def_id);
let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.origin else {
return Ok(definition_ty);
};
let param_env = tcx.param_env(def_id);

View File

@ -2749,6 +2749,8 @@ pub struct BareFnTy<'hir> {
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct OpaqueTy<'hir> {
pub hir_id: HirId,
pub def_id: LocalDefId,
pub generics: &'hir Generics<'hir>,
pub bounds: GenericBounds<'hir>,
pub origin: OpaqueTyOrigin,
@ -2762,6 +2764,7 @@ pub struct OpaqueTy<'hir> {
/// This mapping associated a captured lifetime (first parameter) with the new
/// early-bound lifetime that was generated for the opaque.
pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)],
pub span: Span,
}
#[derive(Debug, Clone, Copy, HashStable_Generic)]
@ -2868,7 +2871,7 @@ pub enum TyKind<'hir> {
/// possibly parameters) that are actually bound on the `impl Trait`.
///
/// The last parameter specifies whether this opaque appears in a trait definition.
OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
TraitObject(
@ -3337,8 +3340,6 @@ impl<'hir> Item<'hir> {
expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
ItemKind::TyAlias(ty, generics), (ty, generics);
expect_opaque_ty, &OpaqueTy<'hir>, ItemKind::OpaqueTy(ty), ty;
expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics);
expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>),
@ -3451,8 +3452,6 @@ pub enum ItemKind<'hir> {
GlobalAsm(&'hir InlineAsm<'hir>),
/// A type alias, e.g., `type Foo = Bar<u8>`.
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
OpaqueTy(&'hir OpaqueTy<'hir>),
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
Enum(EnumDef<'hir>, &'hir Generics<'hir>),
/// A struct definition, e.g., `struct Foo<A> {x: A}`.
@ -3496,7 +3495,6 @@ impl ItemKind<'_> {
ItemKind::Fn(_, ref generics, _)
| ItemKind::TyAlias(_, ref generics)
| ItemKind::Const(_, ref generics, _)
| ItemKind::OpaqueTy(OpaqueTy { ref generics, .. })
| ItemKind::Enum(_, ref generics)
| ItemKind::Struct(_, ref generics)
| ItemKind::Union(_, ref generics)
@ -3519,7 +3517,6 @@ impl ItemKind<'_> {
ItemKind::ForeignMod { .. } => "extern block",
ItemKind::GlobalAsm(..) => "global asm item",
ItemKind::TyAlias(..) => "type alias",
ItemKind::OpaqueTy(..) => "opaque type",
ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union",
@ -3806,6 +3803,7 @@ pub enum Node<'hir> {
Ty(&'hir Ty<'hir>),
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
TraitRef(&'hir TraitRef<'hir>),
OpaqueTy(&'hir OpaqueTy<'hir>),
Pat(&'hir Pat<'hir>),
PatField(&'hir PatField<'hir>),
Arm(&'hir Arm<'hir>),
@ -3871,6 +3869,7 @@ impl<'hir> Node<'hir> {
| Node::Crate(..)
| Node::Ty(..)
| Node::TraitRef(..)
| Node::OpaqueTy(..)
| Node::Infer(..)
| Node::WhereBoundPredicate(..)
| Node::ArrayLenInfer(..)
@ -3996,6 +3995,7 @@ impl<'hir> Node<'hir> {
| Node::TraitItem(TraitItem { generics, .. })
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
Node::Item(item) => item.kind.generics(),
Node::OpaqueTy(opaque) => Some(opaque.generics),
_ => None,
}
}
@ -4055,6 +4055,7 @@ impl<'hir> Node<'hir> {
expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
expect_opaque_ty, &'hir OpaqueTy<'hir>, Node::OpaqueTy(n), n;
expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;

View File

@ -111,6 +111,7 @@ impl<'a> FnKind<'a> {
pub trait Map<'hir> {
/// Retrieves the `Node` corresponding to `id`.
fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
fn hir_node_by_def_id(&self, def_id: LocalDefId) -> Node<'hir>;
fn body(&self, id: BodyId) -> &'hir Body<'hir>;
fn item(&self, id: ItemId) -> &'hir Item<'hir>;
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
@ -123,6 +124,9 @@ impl<'hir> Map<'hir> for ! {
fn hir_node(&self, _: HirId) -> Node<'hir> {
*self;
}
fn hir_node_by_def_id(&self, _: LocalDefId) -> Node<'hir> {
*self;
}
fn body(&self, _: BodyId) -> &'hir Body<'hir> {
*self;
}
@ -423,6 +427,9 @@ pub trait Visitor<'v>: Sized {
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>) -> Self::Result {
walk_poly_trait_ref(self, t)
}
fn visit_opaque_ty(&mut self, opaque: &'v OpaqueTy<'v>) -> Self::Result {
walk_opaque_ty(self, opaque)
}
fn visit_variant_data(&mut self, s: &'v VariantData<'v>) -> Self::Result {
walk_struct_def(self, s)
}
@ -536,11 +543,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
try_visit!(visitor.visit_ty(ty));
try_visit!(visitor.visit_generics(generics));
}
ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, .. }) => {
try_visit!(visitor.visit_id(item.hir_id()));
try_visit!(walk_generics(visitor, generics));
walk_list!(visitor, visit_param_bound, bounds);
}
ItemKind::Enum(ref enum_definition, ref generics) => {
try_visit!(visitor.visit_generics(generics));
// `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
@ -894,8 +896,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
TyKind::Path(ref qpath) => {
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
}
TyKind::OpaqueDef(item_id, lifetimes) => {
try_visit!(visitor.visit_nested_item(item_id));
TyKind::OpaqueDef(opaque, lifetimes) => {
try_visit!(visitor.visit_opaque_ty(opaque));
walk_list!(visitor, visit_generic_arg, lifetimes);
}
TyKind::Array(ref ty, ref length) => {
@ -1185,6 +1187,15 @@ pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(
visitor.visit_trait_ref(&trait_ref.trait_ref)
}
pub fn walk_opaque_ty<'v, V: Visitor<'v>>(visitor: &mut V, opaque: &'v OpaqueTy<'v>) -> V::Result {
let &OpaqueTy { hir_id, def_id: _, generics, bounds, origin: _, lifetime_mapping: _, span: _ } =
opaque;
try_visit!(visitor.visit_id(hir_id));
try_visit!(walk_generics(visitor, generics));
walk_list!(visitor, visit_param_bound, bounds);
V::Result::output()
}
pub fn walk_struct_def<'v, V: Visitor<'v>>(
visitor: &mut V,
struct_definition: &'v VariantData<'v>,

View File

@ -34,7 +34,6 @@ pub enum Target {
ForeignMod,
GlobalAsm,
TyAlias,
OpaqueTy,
Enum,
Variant,
Struct,
@ -79,7 +78,6 @@ impl Target {
| Target::ForeignMod
| Target::GlobalAsm
| Target::TyAlias
| Target::OpaqueTy
| Target::Enum
| Target::Variant
| Target::Struct
@ -114,7 +112,6 @@ impl Target {
ItemKind::ForeignMod { .. } => Target::ForeignMod,
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
ItemKind::TyAlias(..) => Target::TyAlias,
ItemKind::OpaqueTy(..) => Target::OpaqueTy,
ItemKind::Enum(..) => Target::Enum,
ItemKind::Struct(..) => Target::Struct,
ItemKind::Union(..) => Target::Union,
@ -137,7 +134,6 @@ impl Target {
DefKind::ForeignMod => Target::ForeignMod,
DefKind::GlobalAsm => Target::GlobalAsm,
DefKind::TyAlias => Target::TyAlias,
DefKind::OpaqueTy => Target::OpaqueTy,
DefKind::Enum => Target::Enum,
DefKind::Struct => Target::Struct,
DefKind::Union => Target::Union,
@ -191,7 +187,6 @@ impl Target {
Target::ForeignMod => "foreign module",
Target::GlobalAsm => "global asm",
Target::TyAlias => "type alias",
Target::OpaqueTy => "opaque type",
Target::Enum => "enum",
Target::Variant => "enum variant",
Target::Struct => "struct",

View File

@ -252,10 +252,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
/// projections that would result in "inheriting lifetimes".
fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let item = tcx.hir().expect_item(def_id);
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
tcx.dcx().span_bug(item.span, "expected opaque item");
};
let hir::OpaqueTy { origin, .. } = tcx.hir().expect_opaque_ty(def_id);
// HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
// `async-std` (and `pub async fn` in general).
@ -265,16 +262,16 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
return;
}
let span = tcx.def_span(item.owner_id.def_id);
let span = tcx.def_span(def_id);
if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
if tcx.type_of(def_id).instantiate_identity().references_error() {
return;
}
if check_opaque_for_cycles(tcx, item.owner_id.def_id, span).is_err() {
if check_opaque_for_cycles(tcx, def_id, span).is_err() {
return;
}
let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, origin);
let _ = check_opaque_meets_bounds(tcx, def_id, span, origin);
}
/// Checks that an opaque type does not contain cycles.
@ -481,8 +478,7 @@ fn sanity_check_found_hidden_type<'tcx>(
/// 2. Checking that all lifetimes that are implicitly captured are mentioned.
/// 3. Asserting that all parameters mentioned in the captures list are invariant.
fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) {
let hir::OpaqueTy { bounds, .. } =
*tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
let hir::OpaqueTy { bounds, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
let Some(precise_capturing_args) = bounds.iter().find_map(|bound| match *bound {
hir::GenericBound::Use(bounds, ..) => Some(bounds),
_ => None,

View File

@ -93,7 +93,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
// it's a refinement to a TAIT.
if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| {
matches!(
node.expect_item().expect_opaque_ty().origin,
node.expect_opaque_ty().origin,
hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. }
if parent == impl_m.def_id.expect_local()
)

View File

@ -185,15 +185,16 @@ where
}
}
fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorGuaranteed> {
let node = tcx.hir_owner_node(def_id);
fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
let node = tcx.hir_node_by_def_id(def_id);
let mut res = match node {
hir::OwnerNode::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
hir::OwnerNode::Item(item) => check_item(tcx, item),
hir::OwnerNode::TraitItem(item) => check_trait_item(tcx, item),
hir::OwnerNode::ImplItem(item) => check_impl_item(tcx, item),
hir::OwnerNode::ForeignItem(item) => check_foreign_item(tcx, item),
hir::OwnerNode::Synthetic => unreachable!(),
hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
hir::Node::Item(item) => check_item(tcx, item),
hir::Node::TraitItem(item) => check_trait_item(tcx, item),
hir::Node::ImplItem(item) => check_impl_item(tcx, item),
hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
hir::Node::OpaqueTy(_) => Ok(crate::check::check::check_item_type(tcx, def_id)),
_ => unreachable!(),
};
if let Some(generics) = node.generics() {
@ -201,6 +202,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorG
res = res.and(check_param_wf(tcx, param));
}
}
res
}
@ -2172,10 +2174,14 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
let items = tcx.hir_module_items(module);
let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id));
res = res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
res = res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
res = res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id));
res =
res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
res =
res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
res = res
.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
res = res.and(items.par_opaques(|item| tcx.ensure().check_well_formed(item)));
if module == LocalModDefId::CRATE_DEF_ID {
super::entry::check_for_entry_fn(tcx);
}

View File

@ -260,8 +260,7 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
| hir::ItemKind::Trait(_, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. })
| hir::ItemKind::Struct(_, generics) => (generics, true),
hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. })
| hir::ItemKind::TyAlias(_, generics) => (generics, false),
hir::ItemKind::TyAlias(_, generics) => (generics, false),
// `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
_ => return,
};
@ -328,6 +327,19 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
intravisit::walk_expr(self, expr);
}
/// Don't call `type_of` on opaque types, since that depends on type checking function bodies.
/// `check_item_type` ensures that it's called instead.
fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) {
let def_id = opaque.def_id;
self.tcx.ensure().generics_of(def_id);
self.tcx.ensure().predicates_of(def_id);
self.tcx.ensure().explicit_item_bounds(def_id);
self.tcx.ensure().explicit_item_super_predicates(def_id);
self.tcx.ensure().item_bounds(def_id);
self.tcx.ensure().item_super_predicates(def_id);
intravisit::walk_opaque_ty(self, opaque);
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
lower_trait_item(self.tcx, trait_item.trait_item_id());
intravisit::walk_trait_item(self, trait_item);
@ -731,18 +743,6 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
}
}
// Don't call `type_of` on opaque types, since that depends on type
// checking function bodies. `check_item_type` ensures that it's called
// instead.
hir::ItemKind::OpaqueTy(..) => {
tcx.ensure().generics_of(def_id);
tcx.ensure().predicates_of(def_id);
tcx.ensure().explicit_item_bounds(def_id);
tcx.ensure().explicit_item_super_predicates(def_id);
tcx.ensure().item_bounds(def_id);
tcx.ensure().item_super_predicates(def_id);
}
hir::ItemKind::TyAlias(..) => {
tcx.ensure().generics_of(def_id);
tcx.ensure().type_of(def_id);
@ -1852,12 +1852,8 @@ fn coroutine_for_closure(tcx: TyCtxt<'_>, def_id: LocalDefId) -> DefId {
}
fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
match tcx.hir_node_by_def_id(def_id) {
Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => {
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
}
_ => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id),
}
let opaque = tcx.hir().expect_opaque_ty(def_id);
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
}
fn rendered_precise_capturing_args<'tcx>(
@ -1870,12 +1866,10 @@ fn rendered_precise_capturing_args<'tcx>(
return tcx.rendered_precise_capturing_args(opaque_def_id);
}
tcx.hir_node_by_def_id(def_id).expect_item().expect_opaque_ty().bounds.iter().find_map(
|bound| match bound {
hir::GenericBound::Use(args, ..) => {
Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name())))
}
_ => None,
},
)
tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound {
hir::GenericBound::Use(args, ..) => {
Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name())))
}
_ => None,
})
}

View File

@ -1,4 +1,3 @@
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::intravisit;
use rustc_middle::hir::nested_filter::OnlyBodies;
@ -10,12 +9,10 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
return;
}
for id in tcx.hir().items() {
let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
let ty = tcx.type_of(id.owner_id).instantiate_identity();
tcx.dcx().emit_err(crate::errors::TypeOf { span: tcx.def_span(id.owner_id), ty });
for id in tcx.hir_crate_items(()).opaques() {
let ty = tcx.type_of(id).instantiate_identity();
let span = tcx.def_span(id);
tcx.dcx().emit_err(crate::errors::TypeOf { span, ty });
}
}

View File

@ -24,6 +24,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
tcx.opt_rpitit_info(def_id.to_def_id())
{
debug!("RPITIT fn_def_id={fn_def_id:?} opaque_def_id={opaque_def_id:?}");
let trait_def_id = tcx.parent(fn_def_id);
let opaque_ty_generics = tcx.generics_of(opaque_def_id);
let opaque_ty_parent_count = opaque_ty_generics.parent_count;
@ -207,36 +208,33 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
| Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
Some(tcx.typeck_root_def_id(def_id.to_def_id()))
}
Node::Item(item) => match item.kind {
ItemKind::OpaqueTy(&hir::OpaqueTy {
origin:
hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
..
}) => {
if in_trait_or_impl.is_some() {
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
} else {
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
}
Some(fn_def_id.to_def_id())
Node::OpaqueTy(&hir::OpaqueTy {
origin:
hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
..
}) => {
if in_trait_or_impl.is_some() {
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
} else {
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
}
ItemKind::OpaqueTy(&hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty },
..
}) => {
if in_assoc_ty {
assert_matches!(tcx.def_kind(parent), DefKind::AssocTy);
} else {
assert_matches!(tcx.def_kind(parent), DefKind::TyAlias);
}
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent);
// Opaque types are always nested within another item, and
// inherit the generics of the item.
Some(parent.to_def_id())
Some(fn_def_id.to_def_id())
}
Node::OpaqueTy(&hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty },
..
}) => {
if in_assoc_ty {
assert_matches!(tcx.def_kind(parent), DefKind::AssocTy);
} else {
assert_matches!(tcx.def_kind(parent), DefKind::TyAlias);
}
_ => None,
},
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent);
// Opaque types are always nested within another item, and
// inherit the generics of the item.
Some(parent.to_def_id())
}
_ => None,
};
@ -272,13 +270,14 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
ItemKind::TyAlias(..)
| ItemKind::Enum(..)
| ItemKind::Struct(..)
| ItemKind::OpaqueTy(..)
| ItemKind::Union(..) => (None, Defaults::Allowed),
ItemKind::Const(..) => (None, Defaults::Deny),
_ => (None, Defaults::FutureCompatDisallowed),
}
}
Node::OpaqueTy(..) => (None, Defaults::Allowed),
// GATs
Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => {
(None, Defaults::Deny)

View File

@ -335,8 +335,7 @@ pub(super) fn explicit_item_bounds_with_filter(
// RPITIT's bounds are the same as opaque type bounds, but with
// a projection self type.
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
let opaque_ty = item.expect_opaque_ty();
let opaque_ty = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_opaque_ty();
let item_ty = Ty::new_projection_from_args(
tcx,
def_id.to_def_id(),
@ -347,7 +346,7 @@ pub(super) fn explicit_item_bounds_with_filter(
opaque_def_id.expect_local(),
opaque_ty.bounds,
item_ty,
item.span,
opaque_ty.span,
filter,
);
assert_only_contains_predicates_from(filter, bounds, item_ty);
@ -369,11 +368,7 @@ pub(super) fn explicit_item_bounds_with_filter(
span,
..
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, origin, .. }),
span,
..
}) => match origin {
hir::Node::OpaqueTy(hir::OpaqueTy { bounds, origin, span, .. }) => match origin {
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`,
// when we're asking for the item bounds of the *opaques* in a trait's default
// method signature, we need to map these projections back to opaques.
@ -412,7 +407,7 @@ pub(super) fn explicit_item_bounds_with_filter(
}
},
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
_ => bug!("item_bounds called on {:?}", def_id),
node => bug!("item_bounds called on {def_id:?} => {node:?}"),
};
ty::EarlyBinder::bind(bounds)

View File

@ -330,7 +330,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// Opaque types duplicate some of their generic parameters.
// We create bi-directional Outlives predicates between the original
// and the duplicated parameter, to ensure that they do not get out of sync.
if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
if let Node::OpaqueTy(..) = node {
let opaque_ty_node = tcx.parent_hir_node(hir_id);
let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes), .. }) = opaque_ty_node
else {

View File

@ -11,10 +11,13 @@ use std::fmt;
use rustc_ast::visit::walk_list;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirId, HirIdMap, LifetimeName, Node};
use rustc_hir::{
GenericArg, GenericParam, GenericParamKind, HirId, ItemLocalMap, LifetimeName, Node,
};
use rustc_macros::extension;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::*;
@ -74,7 +77,7 @@ impl ResolvedArg {
struct NamedVarMap {
// maps from every use of a named (not anonymous) bound var to a
// `ResolvedArg` describing how that variable is bound
defs: HirIdMap<ResolvedArg>,
defs: ItemLocalMap<ResolvedArg>,
// Maps relevant hir items to the bound vars on them. These include:
// - function defs
@ -82,7 +85,7 @@ struct NamedVarMap {
// - closures
// - trait refs
// - bound types (like `T` in `for<'a> T<'a>: Foo`)
late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>,
late_bound_vars: ItemLocalMap<Vec<ty::BoundVariableKind>>,
}
struct BoundVarContext<'a, 'tcx> {
@ -225,10 +228,10 @@ pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
resolve_bound_vars,
named_variable_map: |tcx, id| tcx.resolve_bound_vars(id).defs.get(&id),
named_variable_map: |tcx, id| &tcx.resolve_bound_vars(id).defs,
is_late_bound_map,
object_lifetime_default,
late_bound_vars_map: |tcx, id| tcx.resolve_bound_vars(id).late_bound_vars.get(&id),
late_bound_vars_map: |tcx, id| &tcx.resolve_bound_vars(id).late_bound_vars,
..*providers
};
@ -265,16 +268,12 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
hir::OwnerNode::Synthetic => unreachable!(),
}
let mut rl = ResolveBoundVars::default();
for (hir_id, v) in named_variable_map.defs {
let map = rl.defs.entry(hir_id.owner).or_default();
map.insert(hir_id.local_id, v);
}
for (hir_id, v) in named_variable_map.late_bound_vars {
let map = rl.late_bound_vars.entry(hir_id.owner).or_default();
map.insert(hir_id.local_id, v);
}
let defs = named_variable_map.defs.into_sorted_stable_ord();
let late_bound_vars = named_variable_map.late_bound_vars.into_sorted_stable_ord();
let rl = ResolveBoundVars {
defs: SortedMap::from_presorted_elements(defs),
late_bound_vars: SortedMap::from_presorted_elements(late_bound_vars),
};
debug!(?rl.defs);
debug!(?rl.late_bound_vars);
@ -340,7 +339,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
Scope::Binder { hir_id, .. } => {
// Nested poly trait refs have the binders concatenated
let mut full_binders =
self.map.late_bound_vars.entry(*hir_id).or_default().clone();
self.map.late_bound_vars.entry(hir_id.local_id).or_default().clone();
full_binders.extend(supertrait_bound_vars);
break (full_binders, BinderScopeType::Concatenating);
}
@ -486,6 +485,31 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}
}
#[instrument(level = "debug", skip(self))]
fn visit_opaque_ty(&mut self, opaque: &'tcx rustc_hir::OpaqueTy<'tcx>) {
// We want to start our early-bound indices at the end of the parent scope,
// not including any parent `impl Trait`s.
let mut bound_vars = FxIndexMap::default();
debug!(?opaque.generics.params);
for param in opaque.generics.params {
let (def_id, reg) = ResolvedArg::early(param);
bound_vars.insert(def_id, reg);
}
let hir_id = self.tcx.local_def_id_to_hir_id(opaque.def_id);
let scope = Scope::Binder {
hir_id,
bound_vars,
s: self.scope,
scope_type: BinderScopeType::Normal,
where_bound_origin: None,
};
self.with(scope, |this| {
let scope = Scope::TraitRefBoundary { s: this.scope };
this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
})
}
#[instrument(level = "debug", skip(self))]
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
match &item.kind {
@ -513,38 +537,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
// These sorts of items have no lifetime parameters at all.
intravisit::walk_item(self, item);
}
hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
origin:
hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
| hir::OpaqueTyOrigin::TyAlias { parent, .. },
generics,
..
}) => {
// We want to start our early-bound indices at the end of the parent scope,
// not including any parent `impl Trait`s.
let mut bound_vars = FxIndexMap::default();
debug!(?generics.params);
for param in generics.params {
let (def_id, reg) = ResolvedArg::early(param);
bound_vars.insert(def_id, reg);
}
let scope = Scope::Root { opt_parent_item: Some(parent) };
self.with(scope, |this| {
let scope = Scope::Binder {
hir_id: item.hir_id(),
bound_vars,
s: this.scope,
scope_type: BinderScopeType::Normal,
where_bound_origin: None,
};
this.with(scope, |this| {
let scope = Scope::TraitRefBoundary { s: this.scope };
this.with(scope, |this| intravisit::walk_item(this, item))
});
})
}
hir::ItemKind::TyAlias(_, generics)
| hir::ItemKind::Const(_, generics, _)
| hir::ItemKind::Enum(_, generics)
@ -684,22 +676,19 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
hir::TyKind::Ref(lifetime_ref, ref mt) => {
self.visit_lifetime(lifetime_ref);
let scope = Scope::ObjectLifetimeDefault {
lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
lifetime: self.map.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
s: self.scope,
};
self.with(scope, |this| this.visit_ty(mt.ty));
}
hir::TyKind::OpaqueDef(item_id, lifetimes) => {
hir::TyKind::OpaqueDef(opaque_ty, lifetimes) => {
self.visit_opaque_ty(opaque_ty);
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
// ^ ^ this gets resolved in the scope of
// the opaque_ty generics
let opaque_ty = self.tcx.hir().item(item_id);
match &opaque_ty.kind {
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: _, .. }) => {}
i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
};
// Resolve the lifetimes that are applied to the opaque type.
// These are resolved in the current scope.
@ -714,7 +703,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
// and ban them. Type variables instantiated inside binders aren't
// well-supported at the moment, so this doesn't work.
// In the future, this should be fixed and this error should be removed.
let def = self.map.defs.get(&lifetime.hir_id).copied();
let def = self.map.defs.get(&lifetime.hir_id.local_id).copied();
let Some(ResolvedArg::LateBound(_, _, lifetime_def_id)) = def else { continue };
let lifetime_hir_id = self.tcx.local_def_id_to_hir_id(lifetime_def_id);
@ -722,9 +711,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
{
// Opaques do not declare their own lifetimes, so if a lifetime comes from an opaque
// it must be a reified late-bound lifetime from a trait goal.
hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy { .. }, ..
}) => "higher-ranked lifetime from outer `impl Trait`",
hir::Node::OpaqueTy(_) => "higher-ranked lifetime from outer `impl Trait`",
// Other items are fine.
hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => {
continue;
@ -740,8 +727,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
let (span, label) = if lifetime.ident.span == self.tcx.def_span(lifetime_def_id)
{
let opaque_span = self.tcx.def_span(item_id.owner_id);
(opaque_span, Some(opaque_span))
(opaque_ty.span, Some(opaque_ty.span))
} else {
(lifetime.ident.span, None)
};
@ -854,7 +840,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
let bound_vars: Vec<_> =
self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect();
let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
self.map.late_bound_vars.insert(hir_id, bound_vars);
self.map.late_bound_vars.insert(hir_id.local_id, bound_vars);
}
self.visit_fn_like_elision(fd.inputs, output, matches!(fk, intravisit::FnKind::Closure));
intravisit::walk_fn_kind(self, fk);
@ -1032,10 +1018,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
}
fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec<ty::BoundVariableKind>) {
if let Some(old) = self.map.late_bound_vars.insert(hir_id, binder) {
if let Some(old) = self.map.late_bound_vars.insert(hir_id.local_id, binder) {
bug!(
"overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}",
self.map.late_bound_vars[&hir_id]
self.map.late_bound_vars[&hir_id.local_id]
)
}
}
@ -1394,9 +1380,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
kind.descr(param_def_id.to_def_id())
),
};
self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
} else {
self.map.defs.insert(hir_id, def);
self.map.defs.insert(hir_id.local_id, def);
}
return;
}
@ -1429,7 +1415,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
bug!("unexpected def-kind: {}", kind.descr(param_def_id.to_def_id()))
}
});
self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
return;
}
Scope::Root { .. } => break,
@ -1539,7 +1525,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
// This index can be used with `generic_args` since `parent_count == 0`.
let index = generics.param_def_id_to_index[&param_def_id] as usize;
generic_args.args.get(index).and_then(|arg| match arg {
GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id).copied(),
GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id.local_id).copied(),
_ => None,
})
}
@ -1829,7 +1815,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: ResolvedArg) {
debug!(span = ?lifetime_ref.ident.span);
self.map.defs.insert(lifetime_ref.hir_id, def);
self.map.defs.insert(lifetime_ref.hir_id.local_id, def);
}
/// Sometimes we resolve a lifetime, but later find that it is an
@ -1840,8 +1826,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
lifetime_ref: &'tcx hir::Lifetime,
bad_def: ResolvedArg,
) {
// FIXME(#120456) - is `swap_remove` correct?
let old_value = self.map.defs.swap_remove(&lifetime_ref.hir_id);
let old_value = self.map.defs.remove(&lifetime_ref.hir_id.local_id);
assert_eq!(old_value, Some(bad_def));
}
@ -2011,7 +1996,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
// See where these vars are used in `HirTyLowerer::lower_ty_maybe_return_type_notation`.
// And this is exercised in:
// `tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs`.
let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id).unwrap();
let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id.local_id).unwrap();
let existing_bound_vars_saved = existing_bound_vars.clone();
existing_bound_vars.extend(bound_vars);
self.record_late_bound_vars(item_segment.hir_id, existing_bound_vars_saved);

View File

@ -529,10 +529,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_adt(tcx, def, args)
}
ItemKind::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
|CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
|ty| ty.instantiate_identity(),
),
ItemKind::Trait(..)
| ItemKind::TraitAlias(..)
| ItemKind::Macro(..)
@ -545,6 +541,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
}
},
Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
|CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
|ty| ty.instantiate_identity(),
),
Node::ForeignItem(foreign_item) => match foreign_item.kind {
ForeignItemKind::Fn(..) => {
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
@ -603,42 +604,25 @@ pub(super) fn type_of_opaque(
def_id: DefId,
) -> Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
if let Some(def_id) = def_id.as_local() {
use rustc_hir::*;
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
Node::Item(item) => match item.kind {
ItemKind::OpaqueTy(OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. },
..
}) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
ItemKind::OpaqueTy(OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. },
..
}) => opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id),
// Opaque types desugared from `impl Trait`.
ItemKind::OpaqueTy(&OpaqueTy {
origin:
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
| hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl },
..
}) => {
if in_trait_or_impl == Some(hir::RpitContext::Trait)
&& !tcx.defaultness(owner).has_value()
{
span_bug!(
tcx.def_span(def_id),
"tried to get type of this RPITIT with no definition"
);
}
opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
opaque::find_opaque_ty_constraints_for_tait(tcx, def_id)
}
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => {
opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id)
}
// Opaque types desugared from `impl Trait`.
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
| hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl } => {
if in_trait_or_impl == Some(hir::RpitContext::Trait)
&& !tcx.defaultness(owner).has_value()
{
span_bug!(
tcx.def_span(def_id),
"tried to get type of this RPITIT with no definition"
);
}
_ => {
span_bug!(item.span, "type_of_opaque: unexpected item type: {:?}", item.kind);
}
},
x => {
bug!("unexpected sort of node in type_of_opaque(): {:?}", x);
opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
}
}))
} else {

View File

@ -2087,43 +2087,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
self.lower_path(opt_self_ty, path, hir_ty.hir_id, false)
}
&hir::TyKind::OpaqueDef(item_id, lifetimes) => {
let opaque_ty = tcx.hir().item(item_id);
&hir::TyKind::OpaqueDef(opaque_ty, lifetimes) => {
let local_def_id = opaque_ty.def_id;
match opaque_ty.kind {
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
let local_def_id = item_id.owner_id.def_id;
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
// generate the def_id of an associated type for the trait and return as
// type a projection.
match origin {
hir::OpaqueTyOrigin::FnReturn {
in_trait_or_impl: Some(hir::RpitContext::Trait),
..
}
| hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: Some(hir::RpitContext::Trait),
..
} => self.lower_opaque_ty(
tcx.associated_type_for_impl_trait_in_trait(local_def_id)
.to_def_id(),
lifetimes,
true,
),
hir::OpaqueTyOrigin::FnReturn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::TyAlias { .. } => {
self.lower_opaque_ty(local_def_id.to_def_id(), lifetimes, false)
}
}
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
// generate the def_id of an associated type for the trait and return as
// type a projection.
match opaque_ty.origin {
hir::OpaqueTyOrigin::FnReturn {
in_trait_or_impl: Some(hir::RpitContext::Trait),
..
}
| hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: Some(hir::RpitContext::Trait),
..
} => self.lower_opaque_ty(
tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id(),
lifetimes,
true,
),
hir::OpaqueTyOrigin::FnReturn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::TyAlias { .. } => {
self.lower_opaque_ty(local_def_id.to_def_id(), lifetimes, false)
}
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
}
}
// If we encounter a type relative path with RTN generics, then it must have
@ -2289,7 +2282,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
span_bug!(
tcx.def_span(param.def_id),
"only expected lifetime for opaque's own generics, got {:?}",
param.kind
param
);
};
let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else {

View File

@ -1,6 +1,5 @@
use std::fmt::Write;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_middle::ty::{GenericArgs, TyCtxt};
use rustc_span::symbol::sym;
@ -24,18 +23,18 @@ fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
}
pub(crate) fn variances(tcx: TyCtxt<'_>) {
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
for id in tcx.hir().items() {
let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
let crate_items = tcx.hir_crate_items(());
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
for id in crate_items.opaques() {
tcx.dcx().emit_err(crate::errors::VariancesOf {
span: tcx.def_span(id.owner_id),
variances: format_variances(tcx, id.owner_id.def_id),
span: tcx.def_span(id),
variances: format_variances(tcx, id),
});
}
}
for id in tcx.hir().items() {
for id in crate_items.free_items() {
if !tcx.has_attr(id.owner_id, sym::rustc_variance) {
continue;
}

View File

@ -96,6 +96,7 @@ impl<'a> State<'a> {
Node::Ty(a) => self.print_type(a),
Node::AssocItemConstraint(a) => self.print_assoc_item_constraint(a),
Node::TraitRef(a) => self.print_trait_ref(a),
Node::OpaqueTy(o) => self.print_opaque_ty(o),
Node::Pat(a) => self.print_pat(a),
Node::PatField(a) => self.print_patfield(a),
Node::Arm(a) => self.print_arm(a),
@ -568,11 +569,6 @@ impl<'a> State<'a> {
state.print_type(ty);
});
}
hir::ItemKind::OpaqueTy(opaque_ty) => {
self.print_item_type(item, opaque_ty.generics, |state| {
state.print_bounds("= impl", opaque_ty.bounds)
});
}
hir::ItemKind::Enum(ref enum_definition, params) => {
self.print_enum_def(enum_definition, params, item.ident.name, item.span);
}
@ -665,6 +661,15 @@ impl<'a> State<'a> {
self.print_path(t.path, false);
}
fn print_opaque_ty(&mut self, o: &hir::OpaqueTy<'_>) {
self.head("opaque");
self.print_generic_params(o.generics.params);
self.print_where_clause(o.generics);
self.word("{");
self.print_bounds("impl", o.bounds);
self.word("}");
}
fn print_formal_generic_params(&mut self, generic_params: &[hir::GenericParam<'_>]) {
if !generic_params.is_empty() {
self.word("for");

View File

@ -847,11 +847,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return true;
}
hir::FnRetTy::Return(hir_ty) => {
if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind
// FIXME: account for RPITIT.
&& let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(op_ty), ..
}) = self.tcx.hir_node(item_id.hir_id())
&& let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
&& let Some(hir::PathSegment { args: Some(generic_args), .. }) =
trait_ref.trait_ref.path.segments.last()

View File

@ -104,8 +104,9 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait {
return;
}
let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(def, ..), .. }) =
sig.decl.output
let hir::FnRetTy::Return(hir::Ty {
kind: hir::TyKind::OpaqueDef(opaq_def, ..), ..
}) = sig.decl.output
else {
// This should never happen, but let's not ICE.
return;
@ -114,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait {
cx.tcx,
sig,
body,
def.owner_id.def_id,
opaq_def.def_id,
" + Send",
);
cx.tcx.emit_node_span_lint(

View File

@ -258,7 +258,7 @@ where
&& self.seen.insert(opaque_def_id)
// If it's owned by this function
&& let opaque =
self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty()
self.tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty()
&& let hir::OpaqueTyOrigin::FnReturn { parent, .. } = opaque.origin
&& parent == self.parent_def_id
{

View File

@ -68,8 +68,8 @@ declare_lint! {
declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]);
impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
let hir::ItemKind::OpaqueTy(opaque) = &item.kind else {
fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx>) {
let hir::TyKind::OpaqueDef(opaque, _) = &ty.kind else {
return;
};
@ -84,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
return;
}
let def_id = item.owner_id.def_id.to_def_id();
let def_id = opaque.def_id.to_def_id();
let infcx = &cx.tcx.infer_ctxt().build();
// For every projection predicate in the opaque type's explicit bounds,
// check that the type that we're assigning actually satisfies the bounds

View File

@ -1419,7 +1419,6 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
hir::ItemKind::Impl(..)
| hir::ItemKind::TraitAlias(..)
| hir::ItemKind::Trait(..)
| hir::ItemKind::OpaqueTy(..)
| hir::ItemKind::GlobalAsm(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::Mod(..)

View File

@ -732,6 +732,19 @@ impl<'hir> Map<'hir> {
}
}
#[track_caller]
pub fn expect_opaque_ty(self, id: LocalDefId) -> &'hir OpaqueTy<'hir> {
match self.tcx.hir_node_by_def_id(id) {
Node::OpaqueTy(opaq) => opaq,
_ => {
bug!(
"expected opaque type definition, found {}",
self.node_to_string(self.tcx.local_def_id_to_hir_id(id))
)
}
}
}
pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
match self.tcx.hir_node(id) {
Node::Expr(expr) => expr,
@ -923,6 +936,7 @@ impl<'hir> Map<'hir> {
Node::Ty(ty) => ty.span,
Node::AssocItemConstraint(constraint) => constraint.span,
Node::TraitRef(tr) => tr.path.span,
Node::OpaqueTy(op) => op.span,
Node::Pat(pat) => pat.span,
Node::PatField(field) => field.span,
Node::Arm(arm) => arm.span,
@ -1006,6 +1020,10 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
self.tcx.hir_node(hir_id)
}
fn hir_node_by_def_id(&self, def_id: LocalDefId) -> Node<'hir> {
self.tcx.hir_node_by_def_id(def_id)
}
fn body(&self, id: BodyId) -> &'hir Body<'hir> {
(*self).body(id)
}
@ -1139,7 +1157,6 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
ItemKind::ForeignMod { .. } => "foreign mod",
ItemKind::GlobalAsm(..) => "global asm",
ItemKind::TyAlias(..) => "ty",
ItemKind::OpaqueTy(..) => "opaque type",
ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union",
@ -1191,6 +1208,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
Node::Ty(_) => node_str("type"),
Node::AssocItemConstraint(_) => node_str("assoc item constraint"),
Node::TraitRef(_) => node_str("trait ref"),
Node::OpaqueTy(_) => node_str("opaque type"),
Node::Pat(_) => node_str("pat"),
Node::PatField(_) => node_str("pattern field"),
Node::Param(_) => node_str("param"),
@ -1228,6 +1246,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
impl_items,
foreign_items,
body_owners,
opaques,
..
} = collector;
ModuleItems {
@ -1237,6 +1256,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
impl_items: impl_items.into_boxed_slice(),
foreign_items: foreign_items.into_boxed_slice(),
body_owners: body_owners.into_boxed_slice(),
opaques: opaques.into_boxed_slice(),
}
}
@ -1256,6 +1276,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
impl_items,
foreign_items,
body_owners,
opaques,
..
} = collector;
@ -1266,6 +1287,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
impl_items: impl_items.into_boxed_slice(),
foreign_items: foreign_items.into_boxed_slice(),
body_owners: body_owners.into_boxed_slice(),
opaques: opaques.into_boxed_slice(),
}
}
@ -1280,6 +1302,7 @@ struct ItemCollector<'tcx> {
impl_items: Vec<ImplItemId>,
foreign_items: Vec<ForeignItemId>,
body_owners: Vec<LocalDefId>,
opaques: Vec<LocalDefId>,
}
impl<'tcx> ItemCollector<'tcx> {
@ -1293,6 +1316,7 @@ impl<'tcx> ItemCollector<'tcx> {
impl_items: Vec::default(),
foreign_items: Vec::default(),
body_owners: Vec::default(),
opaques: Vec::default(),
}
}
}
@ -1338,6 +1362,11 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
intravisit::walk_inline_const(self, c)
}
fn visit_opaque_ty(&mut self, o: &'hir OpaqueTy<'hir>) {
self.opaques.push(o.def_id);
intravisit::walk_opaque_ty(self, o)
}
fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
if let ExprKind::Closure(closure) = ex.kind {
self.body_owners.push(closure.def_id);

View File

@ -28,6 +28,7 @@ pub struct ModuleItems {
trait_items: Box<[TraitItemId]>,
impl_items: Box<[ImplItemId]>,
foreign_items: Box<[ForeignItemId]>,
opaques: Box<[LocalDefId]>,
body_owners: Box<[LocalDefId]>,
}
@ -65,6 +66,10 @@ impl ModuleItems {
.chain(self.foreign_items.iter().map(|id| id.owner_id))
}
pub fn opaques(&self) -> impl Iterator<Item = LocalDefId> + '_ {
self.opaques.iter().copied()
}
pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ {
self.owners().map(|id| id.def_id)
}
@ -96,6 +101,13 @@ impl ModuleItems {
) -> Result<(), ErrorGuaranteed> {
try_par_for_each_in(&self.foreign_items[..], |&id| f(id))
}
pub fn par_opaques(
&self,
f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
) -> Result<(), ErrorGuaranteed> {
try_par_for_each_in(&self.opaques[..], |&id| f(id))
}
}
impl<'tcx> TyCtxt<'tcx> {

View File

@ -1,9 +1,9 @@
//! Name resolution for lifetimes and late-bound type and const variables: type declarations.
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::ItemLocalId;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{ItemLocalId, OwnerId};
use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable};
use crate::ty;
@ -47,11 +47,11 @@ pub enum ObjectLifetimeDefault {
/// Maps the id of each lifetime reference to the lifetime decl
/// that it corresponds to.
#[derive(Default, HashStable, Debug)]
#[derive(HashStable, Debug)]
pub struct ResolveBoundVars {
/// Maps from every use of a named (not anonymous) lifetime to a
/// `Region` describing how that region is bound
pub defs: FxIndexMap<OwnerId, FxIndexMap<ItemLocalId, ResolvedArg>>,
pub defs: SortedMap<ItemLocalId, ResolvedArg>,
pub late_bound_vars: FxIndexMap<OwnerId, FxIndexMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
pub late_bound_vars: SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>>,
}

View File

@ -16,6 +16,7 @@ use rustc_ast::expand::StrippedCfgItem;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
@ -1552,7 +1553,7 @@ rustc_queries! {
feedable
}
query check_well_formed(key: hir::OwnerId) -> Result<(), ErrorGuaranteed> {
query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) }
ensure_forwards_result_if_red
}
@ -1738,29 +1739,28 @@ rustc_queries! {
/// Does lifetime resolution on items. Importantly, we can't resolve
/// lifetimes directly on things like trait methods, because of trait params.
/// See `rustc_resolve::late::lifetimes` for details.
query resolve_bound_vars(_: hir::OwnerId) -> &'tcx ResolveBoundVars {
query resolve_bound_vars(owner_id: hir::OwnerId) -> &'tcx ResolveBoundVars {
arena_cache
desc { "resolving lifetimes" }
desc { |tcx| "resolving lifetimes for `{}`", tcx.def_path_str(owner_id) }
}
query named_variable_map(_: hir::OwnerId) ->
Option<&'tcx FxIndexMap<ItemLocalId, ResolvedArg>> {
desc { "looking up a named region" }
query named_variable_map(owner_id: hir::OwnerId) -> &'tcx SortedMap<ItemLocalId, ResolvedArg> {
desc { |tcx| "looking up a named region inside `{}`", tcx.def_path_str(owner_id) }
}
query is_late_bound_map(_: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> {
desc { "testing if a region is late bound" }
query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> {
desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) }
}
/// For a given item's generic parameter, gets the default lifetimes to be used
/// for each parameter if a trait object were to be passed for that parameter.
/// For example, for `T` in `struct Foo<'a, T>`, this would be `'static`.
/// For `T` in `struct Foo<'a, T: 'a>`, this would instead be `'a`.
/// This query will panic if passed something that is not a type parameter.
query object_lifetime_default(key: DefId) -> ObjectLifetimeDefault {
desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(key) }
query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault {
desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
query late_bound_vars_map(_: hir::OwnerId)
-> Option<&'tcx FxIndexMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {
desc { "looking up late bound vars" }
query late_bound_vars_map(owner_id: hir::OwnerId)
-> &'tcx SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>> {
desc { |tcx| "looking up late bound vars inside `{}`", tcx.def_path_str(owner_id) }
}
/// Computes the visibility of the provided `def_id`.

View File

@ -56,7 +56,7 @@ use rustc_type_ir::lang_items::TraitSolverLangItem;
pub use rustc_type_ir::lift::Lift;
use rustc_type_ir::solve::SolverMode;
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags, WithCachedTypeInfo, search_graph};
use tracing::{debug, instrument};
use tracing::{debug, trace};
use crate::arena::Arena;
use crate::dep_graph::{DepGraph, DepKindStruct};
@ -2073,9 +2073,11 @@ impl<'tcx> TyCtxt<'tcx> {
}
/// Returns the origin of the opaque type `def_id`.
#[instrument(skip(self), level = "trace", ret)]
#[track_caller]
pub fn opaque_type_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin {
self.hir().expect_item(def_id).expect_opaque_ty().origin
let origin = self.hir().expect_opaque_ty(def_id).origin;
trace!("opaque_type_origin({def_id:?}) => {origin:?}");
origin
}
}
@ -2994,7 +2996,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
debug!(?id, "named_region");
self.named_variable_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
self.named_variable_map(id.owner).get(&id.local_id).cloned()
}
pub fn is_late_bound(self, id: HirId) -> bool {
@ -3003,12 +3005,9 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
self.mk_bound_variable_kinds(
&self
.late_bound_vars_map(id.owner)
.and_then(|map| map.get(&id.local_id).cloned())
.unwrap_or_else(|| {
bug!("No bound vars found for {}", self.hir().node_to_string(id))
}),
&self.late_bound_vars_map(id.owner).get(&id.local_id).cloned().unwrap_or_else(|| {
bug!("No bound vars found for {}", self.hir().node_to_string(id))
}),
)
}
@ -3031,8 +3030,7 @@ impl<'tcx> TyCtxt<'tcx> {
loop {
let parent = self.local_parent(opaque_lifetime_param_def_id);
let hir::OpaqueTy { lifetime_mapping, .. } =
self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
let hir::OpaqueTy { lifetime_mapping, .. } = self.hir().expect_opaque_ty(parent);
let Some((lifetime, _)) = lifetime_mapping
.iter()

View File

@ -507,14 +507,8 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
..
},
_,
) => {
self.0.push(ty);
}
hir::TyKind::OpaqueDef(item_id, _) => {
self.0.push(ty);
let item = self.1.item(item_id);
hir::intravisit::walk_item(self, item);
}
)
| hir::TyKind::OpaqueDef(..) => self.0.push(ty),
_ => {}
}
hir::intravisit::walk_ty(self, ty);

View File

@ -21,6 +21,7 @@ use rustc_target::spec::abi;
use rustc_type_ir::TyKind::*;
use rustc_type_ir::visit::TypeVisitableExt;
use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind};
use tracing::instrument;
use ty::util::{AsyncDropGlueMorphology, IntTypeExt};
use super::GenericParamDefKind;
@ -500,6 +501,7 @@ impl<'tcx> Ty<'tcx> {
}
#[inline]
#[instrument(level = "debug", skip(tcx))]
pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
Ty::new_alias(tcx, ty::Opaque, AliasTy::new_from_args(tcx, def_id, args))
}

View File

@ -814,7 +814,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| Target::Mod
| Target::GlobalAsm
| Target::TyAlias
| Target::OpaqueTy
| Target::Enum
| Target::Variant
| Target::Struct
@ -1328,7 +1327,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
) {
let article = match target {
Target::ExternCrate
| Target::OpaqueTy
| Target::Enum
| Target::Impl
| Target::Expression

View File

@ -41,6 +41,7 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
| Node::TraitItem(..)
| Node::Variant(..)
| Node::AnonConst(..)
| Node::OpaqueTy(..)
)
}
@ -494,6 +495,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
Node::ForeignItem(foreign_item) => {
intravisit::walk_foreign_item(self, foreign_item);
}
Node::OpaqueTy(opaq) => intravisit::walk_opaque_ty(self, opaq),
_ => {}
}
self.repr_has_repr_simd = had_repr_simd;
@ -655,14 +657,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
intravisit::walk_path(self, path);
}
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
if let TyKind::OpaqueDef(item_id, _) = ty.kind {
let item = self.tcx.hir().item(item_id);
intravisit::walk_item(self, item);
}
intravisit::walk_ty(self, ty);
}
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
// When inline const blocks are used in pattern position, paths
// referenced by it should be considered as used.

View File

@ -230,7 +230,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
ForeignMod,
GlobalAsm,
TyAlias,
OpaqueTy,
Enum,
Struct,
Union,

View File

@ -236,7 +236,6 @@ impl<'tcx> ReachableContext<'tcx> {
// worklist, as determined by the privacy pass
hir::ItemKind::ExternCrate(_)
| hir::ItemKind::Use(..)
| hir::ItemKind::OpaqueTy(..)
| hir::ItemKind::TyAlias(..)
| hir::ItemKind::Macro(..)
| hir::ItemKind::Mod(..)
@ -287,7 +286,8 @@ impl<'tcx> ReachableContext<'tcx> {
| Node::Field(_)
| Node::Ty(_)
| Node::Crate(_)
| Node::Synthetic => {}
| Node::Synthetic
| Node::OpaqueTy(..) => {}
_ => {
bug!(
"found unexpected node kind in worklist: {} ({:?})",

View File

@ -402,8 +402,6 @@ struct EmbargoVisitor<'tcx> {
/// n::p::f()
/// }
macro_reachable: FxHashSet<(LocalModDefId, LocalModDefId)>,
/// Preliminary pass for marking all underlying types of `impl Trait`s as reachable.
impl_trait_pass: bool,
/// Has something changed in the level map?
changed: bool,
}
@ -635,48 +633,6 @@ impl<'tcx> EmbargoVisitor<'tcx> {
impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
if self.impl_trait_pass
&& let hir::ItemKind::OpaqueTy(opaque) = item.kind
{
let should_visit = match opaque.origin {
hir::OpaqueTyOrigin::FnReturn {
parent,
in_trait_or_impl: Some(hir::RpitContext::Trait),
}
| hir::OpaqueTyOrigin::AsyncFn {
parent,
in_trait_or_impl: Some(hir::RpitContext::Trait),
} => match self.tcx.hir_node_by_def_id(parent).expect_trait_item().expect_fn().1 {
hir::TraitFn::Required(_) => false,
hir::TraitFn::Provided(..) => true,
},
// Always visit RPITs in functions that have definitions,
// and all TAITs.
hir::OpaqueTyOrigin::FnReturn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::TyAlias { .. } => true,
};
if should_visit {
// FIXME: This is some serious pessimization intended to workaround deficiencies
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
// reachable if they are returned via `impl Trait`, even from private functions.
let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public);
self.reach_through_impl_trait(item.owner_id.def_id, pub_ev)
.generics()
.predicates()
.ty();
return;
}
}
// Update levels of nested things and mark all items
// in interfaces of reachable items as reachable.
let item_ev = self.get(item.owner_id.def_id);
@ -686,7 +642,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
| hir::ItemKind::ExternCrate(..)
| hir::ItemKind::GlobalAsm(..) => {}
// The interface is empty, and all nested items are processed by `visit_item`.
hir::ItemKind::Mod(..) | hir::ItemKind::OpaqueTy(..) => {}
hir::ItemKind::Mod(..) => {}
hir::ItemKind::Macro(macro_def, _) => {
if let Some(item_ev) = item_ev {
self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev);
@ -1752,19 +1708,59 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
tcx,
effective_visibilities: tcx.resolutions(()).effective_visibilities.clone(),
macro_reachable: Default::default(),
// HACK(jynelson): trying to infer the type of `impl Trait` breaks `async-std` (and
// `pub async fn` in general). Since rustdoc never needs to do codegen and doesn't
// care about link-time reachability, keep them unreachable (issue #75100).
impl_trait_pass: !tcx.sess.opts.actually_rustdoc,
changed: false,
};
visitor.effective_visibilities.check_invariants(tcx);
if visitor.impl_trait_pass {
// HACK(jynelson): trying to infer the type of `impl Trait` breaks `async-std` (and
// `pub async fn` in general). Since rustdoc never needs to do codegen and doesn't
// care about link-time reachability, keep them unreachable (issue #75100).
let impl_trait_pass = !tcx.sess.opts.actually_rustdoc;
if impl_trait_pass {
// Underlying types of `impl Trait`s are marked as reachable unconditionally,
// so this pass doesn't need to be a part of the fixed point iteration below.
tcx.hir().visit_all_item_likes_in_crate(&mut visitor);
visitor.impl_trait_pass = false;
let krate = tcx.hir_crate_items(());
for id in krate.opaques() {
let opaque = tcx.hir_node_by_def_id(id).expect_opaque_ty();
let should_visit = match opaque.origin {
hir::OpaqueTyOrigin::FnReturn {
parent,
in_trait_or_impl: Some(hir::RpitContext::Trait),
}
| hir::OpaqueTyOrigin::AsyncFn {
parent,
in_trait_or_impl: Some(hir::RpitContext::Trait),
} => match tcx.hir_node_by_def_id(parent).expect_trait_item().expect_fn().1 {
hir::TraitFn::Required(_) => false,
hir::TraitFn::Provided(..) => true,
},
// Always visit RPITs in functions that have definitions,
// and all TAITs.
hir::OpaqueTyOrigin::FnReturn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::TyAlias { .. } => true,
};
if should_visit {
// FIXME: This is some serious pessimization intended to workaround deficiencies
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
// reachable if they are returned via `impl Trait`, even from private functions.
let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public);
visitor
.reach_through_impl_trait(opaque.def_id, pub_ev)
.generics()
.predicates()
.ty();
}
}
visitor.changed = false;
}

View File

@ -284,14 +284,9 @@ pub fn suggest_new_region_bound(
}
match fn_return.kind {
// FIXME(precise_captures): Suggest adding to `use<...>` list instead.
TyKind::OpaqueDef(item_id, _) => {
let item = tcx.hir().item(item_id);
let ItemKind::OpaqueTy(opaque) = &item.kind else {
return;
};
TyKind::OpaqueDef(opaque, _) => {
// Get the identity type for this RPIT
let did = item_id.owner_id.to_def_id();
let did = opaque.def_id.to_def_id();
let ty = Ty::new_opaque(tcx, did, ty::GenericArgs::identity_for_item(tcx, did));
if let Some(span) = opaque.bounds.iter().find_map(|arg| match arg {

View File

@ -720,7 +720,7 @@ fn foo(&self) -> Self::T { String::new() }
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() {
let opaque_local_def_id = def_id.as_local();
let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id {
tcx.hir().expect_item(opaque_local_def_id).expect_opaque_ty()
tcx.hir().expect_opaque_ty(opaque_local_def_id)
} else {
return false;
};

View File

@ -842,14 +842,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
lifetime: Region<'tcx>,
add_lt_suggs: &mut Vec<(Span, String)>,
) -> String {
struct LifetimeReplaceVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
struct LifetimeReplaceVisitor<'a> {
needle: hir::LifetimeName,
new_lt: &'a str,
add_lt_suggs: &'a mut Vec<(Span, String)>,
}
impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_, 'tcx> {
impl<'hir> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_> {
fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) {
if lt.res == self.needle {
self.add_lt_suggs.push(lt.suggestion(self.new_lt));
@ -857,10 +856,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) {
let hir::TyKind::OpaqueDef(item_id, _) = ty.kind else {
let hir::TyKind::OpaqueDef(opaque_ty, _) = ty.kind else {
return hir::intravisit::walk_ty(self, ty);
};
let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty();
if let Some(&(_, b)) =
opaque_ty.lifetime_mapping.iter().find(|&(a, _)| a.res == self.needle)
{
@ -905,7 +903,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
};
let mut visitor = LifetimeReplaceVisitor {
tcx: self.tcx,
needle: hir::LifetimeName::Param(lifetime_def_id),
add_lt_suggs,
new_lt: &new_lt,
@ -1269,7 +1266,7 @@ fn suggest_precise_capturing<'tcx>(
diag: &mut Diag<'_>,
) {
let hir::OpaqueTy { bounds, origin, .. } =
tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } = *origin else {
return;

View File

@ -731,12 +731,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let exp_local_id = exp_def_id.as_local()?;
match (
&self.tcx.hir().expect_item(last_local_id).kind,
&self.tcx.hir().expect_item(exp_local_id).kind,
&self.tcx.hir().expect_opaque_ty(last_local_id),
&self.tcx.hir().expect_opaque_ty(exp_local_id),
) {
(
hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }),
hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }),
hir::OpaqueTy { bounds: last_bounds, .. },
hir::OpaqueTy { bounds: exp_bounds, .. },
) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
left, right,
) {

View File

@ -355,12 +355,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
| hir::ItemKind::Fn(_, generics, _)
| hir::ItemKind::TyAlias(_, generics)
| hir::ItemKind::Const(_, generics, _)
| hir::ItemKind::TraitAlias(generics, _)
| hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
| hir::ItemKind::TraitAlias(generics, _),
..
})
| hir::Node::TraitItem(hir::TraitItem { generics, .. })
| hir::Node::ImplItem(hir::ImplItem { generics, .. })
| hir::Node::OpaqueTy(hir::OpaqueTy { generics, .. })
if param_ty =>
{
// We skip the 0'th arg (self) because we do not want
@ -421,10 +421,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
| hir::ItemKind::Fn(_, generics, _)
| hir::ItemKind::TyAlias(_, generics)
| hir::ItemKind::Const(_, generics, _)
| hir::ItemKind::TraitAlias(generics, _)
| hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
| hir::ItemKind::TraitAlias(generics, _),
..
}) if !param_ty => {
})
| hir::Node::OpaqueTy(hir::OpaqueTy { generics, .. })
if !param_ty =>
{
// Missing generic type parameter bound.
if suggest_arbitrary_trait_bound(
self.tcx,
@ -4542,7 +4544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// ... whose signature is `async` (i.e. this is an AFIT)
let (sig, body) = item.expect_fn();
let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(def, ..), .. }) =
let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(opaq_def, ..), .. }) =
sig.decl.output
else {
// This should never happen, but let's not ICE.
@ -4551,7 +4553,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// Check that this is *not* a nested `impl Future` RPIT in an async fn
// (i.e. `async fn foo() -> impl Future`)
if def.owner_id.to_def_id() != opaque_def_id {
if opaq_def.def_id.to_def_id() != opaque_def_id {
return;
}
@ -5159,7 +5161,7 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
};
let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span);
let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
let future = tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {
// `async fn` should always lower to a single bound... but don't ICE.
return None;

View File

@ -316,19 +316,16 @@ fn associated_types_for_impl_traits_in_associated_fn(
match tcx.def_kind(parent_def_id) {
DefKind::Trait => {
struct RPITVisitor<'tcx> {
struct RPITVisitor {
rpits: FxIndexSet<LocalDefId>,
tcx: TyCtxt<'tcx>,
}
impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
impl<'tcx> Visitor<'tcx> for RPITVisitor {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
if let hir::TyKind::OpaqueDef(item_id, _) = ty.kind
&& self.rpits.insert(item_id.owner_id.def_id)
if let hir::TyKind::OpaqueDef(opaq, _) = ty.kind
&& self.rpits.insert(opaq.def_id)
{
let opaque_item =
self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty();
for bound in opaque_item.bounds {
for bound in opaq.bounds {
intravisit::walk_param_bound(self, bound);
}
}
@ -336,7 +333,7 @@ fn associated_types_for_impl_traits_in_associated_fn(
}
}
let mut visitor = RPITVisitor { tcx, rpits: FxIndexSet::default() };
let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
if let Some(output) = tcx.hir().get_fn_output(fn_def_id) {
visitor.visit_fn_ret_ty(output);

View File

@ -132,6 +132,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
TaitInBodyFinder { collector: self }.visit_expr(body);
}
#[instrument(level = "debug", skip(self))]
fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
if !self.seen.insert(alias_ty.def_id.expect_local()) {
return;

View File

@ -1828,13 +1828,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
Array(Box::new(clean_ty(ty, cx)), length.into())
}
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
TyKind::OpaqueDef(item_id, _) => {
let item = cx.tcx.hir().item(item_id);
if let hir::ItemKind::OpaqueTy(ty) = item.kind {
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
} else {
unreachable!()
}
TyKind::OpaqueDef(ty, _) => {
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
}
TyKind::Path(_) => clean_qpath(ty, cx),
TyKind::TraitObject(bounds, lifetime, _) => {
@ -2736,9 +2731,6 @@ fn clean_maybe_renamed_item<'tcx>(
type_: clean_ty(ty, cx),
kind: ConstantKind::Local { body: body_id, def_id },
})),
// clean_ty changes types which reference an OpaqueTy item to instead be
// an ImplTrait, so it's ok to return nothing here.
ItemKind::OpaqueTy(_) => return vec![],
ItemKind::TyAlias(hir_ty, generics) => {
*cx.current_type_aliases.entry(def_id).or_insert(0) += 1;
let rustdoc_ty = clean_ty(hir_ty, cx);

View File

@ -243,7 +243,6 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
| ItemKind::ExternCrate(_)
| ItemKind::ForeignMod { .. }
| ItemKind::GlobalAsm(_)
| ItemKind::OpaqueTy(_)
// We already have "visit_mod" above so no need to check it here.
| ItemKind::Mod(_) => {}
}

View File

@ -505,21 +505,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
| hir::ItemKind::Struct(..)
| hir::ItemKind::Union(..)
| hir::ItemKind::TyAlias(..)
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias { .. },
..
})
| hir::ItemKind::Static(..)
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..) => {
self.add_to_current_mod(item, renamed, import_id);
}
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::FnReturn { .. },
..
}) => {
// return-position impl traits are never nameable, and should never be documented.
}
hir::ItemKind::Const(..) => {
// Underscore constants do not correspond to a nameable item and
// so are never useful in documentation.

View File

@ -6,7 +6,7 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
use rustc_hir::{
BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
PredicateOrigin, Ty, TyKind, WherePredicate,
PredicateOrigin, Ty, WherePredicate,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::nested_filter;
@ -199,12 +199,6 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
if let Some((def_id, _)) = t.peel_refs().as_generic_param() {
self.ty_params.remove(&def_id);
} else if let TyKind::OpaqueDef(id, _) = t.kind {
// Explicitly walk OpaqueDef. Normally `walk_ty` would do the job, but it calls
// `visit_nested_item`, which checks that `Self::NestedFilter::INTER` is set. We're
// using `OnlyBodies`, so the check ends up failing and the type isn't fully walked.
let item = self.nested_visit_map().item(id);
walk_item(self, item);
} else {
walk_ty(self, t);
}

View File

@ -3,7 +3,7 @@ use clippy_utils::source::snippet;
use rustc_errors::{Applicability, SuggestionStyle};
use rustc_hir::def_id::DefId;
use rustc_hir::{
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier,
AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifier,
TyKind, WherePredicate,
};
use rustc_hir_analysis::lower_ty;
@ -342,11 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
}
}
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &rustc_hir::Ty<'_>) {
if let TyKind::OpaqueDef(item_id, ..) = ty.kind
&& let item = cx.tcx.hir().item(item_id)
&& let ItemKind::OpaqueTy(opaque_ty) = item.kind
{
fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &rustc_hir::Ty<'tcx>) {
if let TyKind::OpaqueDef(opaque_ty, ..) = ty.kind {
check(cx, opaque_ty.bounds);
}
}

View File

@ -308,11 +308,7 @@ enum LenOutput {
fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> {
if let ty::Alias(_, alias_ty) = ty.kind()
&& let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
&& let Item {
kind: ItemKind::OpaqueTy(opaque),
..
} = item
&& let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
&& let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
&& let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()

View File

@ -6,7 +6,7 @@ use rustc_errors::Applicability;
use rustc_hir::FnRetTy::Return;
use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};
use rustc_hir::intravisit::{
Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_param_bound,
walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_where_predicate,
};
use rustc_hir::{
@ -420,11 +420,9 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
match ty.kind {
TyKind::OpaqueDef(item, bounds) => {
let map = self.cx.tcx.hir();
let item = map.item(item);
TyKind::OpaqueDef(opaque, bounds) => {
let len = self.lts.len();
walk_item(self, item);
self.visit_opaque_ty(opaque);
self.lts.truncate(len);
self.lts.extend(bounds.iter().filter_map(|bound| match bound {
GenericArg::Lifetime(&l) => Some(l),

View File

@ -4,7 +4,7 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{
Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, TraitRef, Ty, TyKind,
FnRetTy, GenericArg, GenericBound, ImplItem, Item, LifetimeName, Node, TraitRef, Ty, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
@ -105,9 +105,7 @@ fn future_trait_ref<'tcx>(
cx: &LateContext<'tcx>,
ty: &'tcx Ty<'tcx>,
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
if let TyKind::OpaqueDef(item_id, bounds) = ty.kind
&& let item = cx.tcx.hir().item(item_id)
&& let ItemKind::OpaqueTy(opaque) = &item.kind
if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
if let GenericBound::Trait(poly, _) = bound {
Some(&poly.trait_ref)

View File

@ -193,8 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..)
| hir::ItemKind::TyAlias(..)
| hir::ItemKind::Union(..)
| hir::ItemKind::OpaqueTy(..) => {},
| hir::ItemKind::Union(..) => {}
hir::ItemKind::ExternCrate(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::GlobalAsm(..)

View File

@ -130,7 +130,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
| hir::ItemKind::GlobalAsm(..)
| hir::ItemKind::TyAlias(..)
| hir::ItemKind::Union(..)
| hir::ItemKind::OpaqueTy(..)
| hir::ItemKind::ExternCrate(..)
| hir::ItemKind::ForeignMod { .. }
| hir::ItemKind::Impl { .. }

View File

@ -85,10 +85,6 @@ const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";
impl<'tcx> LateLintPass<'tcx> for UseSelf {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
if matches!(item.kind, ItemKind::OpaqueTy(_)) {
// skip over `ItemKind::OpaqueTy` in order to lint `foo() -> impl <..>`
return;
}
// We push the self types of `impl`s on a stack here. Only the top type on the stack is
// relevant for linting, since this is the self type of the `impl` we're currently in. To
// avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that
@ -130,10 +126,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
self.stack.push(stack_item);
}
fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {
if !matches!(item.kind, ItemKind::OpaqueTy(_)) {
self.stack.pop();
}
fn check_item_post(&mut self, _: &LateContext<'_>, _: &Item<'_>) {
self.stack.pop();
}
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {

View File

@ -220,7 +220,7 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
ItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")),
ItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")),
ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
ItemKind::Struct(VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")),
ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),

View File

@ -1,4 +0,0 @@
//@ known-bug: #119716
#![feature(non_lifetime_binders)]
trait Trait<T> {}
fn f() -> impl for<T> Trait<impl Trait<T>> {}

View File

@ -1,4 +0,0 @@
//@ known-bug: #119716
#![feature(non_lifetime_binders)]
trait v0<v1> {}
fn kind :(v3main impl for<v4> v0<'_, v2 = impl v0<v4> + '_>) {}

View File

@ -1,8 +0,0 @@
//@ known-bug: #121422
#![feature(non_lifetime_binders)]
trait Trait<T: ?Sized> {}
fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
16
}

View File

@ -1,4 +0,0 @@
//@ known-bug: rust-lang/rust#125843
#![feature(non_lifetime_binders)]
trait v0<> {}
fn kind :(v3main impl for<v4> v0<'_, v2 = impl v0<v4> + '_>) {}

View File

@ -1,15 +0,0 @@
//@ known-bug: rust-lang/rust#129099
#![feature(type_alias_impl_trait)]
fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
loop {}
}
pub fn main() {
type Opaque = impl Sized;
fn define() -> Opaque {
let x: Opaque = dyn_hoops::<()>(0);
x
}
}

View File

@ -318,9 +318,9 @@ pub fn change_return_impl_trait() -> impl Clone {
}
#[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(cfg = "cfail2")]
#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
#[rustc_clean(cfg = "cfail5", except = "typeck")]
#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, typeck")]
#[rustc_clean(cfg = "cfail6")]
pub fn change_return_impl_trait() -> impl Copy {
0u32

View File

@ -208,17 +208,6 @@ LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0282]: type annotations needed
--> $DIR/duplicate.rs:136:5
|
LL | iter::empty()
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
|
help: consider specifying the generic argument
|
LL | iter::empty::<T>()
| +++++
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
--> $DIR/duplicate.rs:139:42
|
@ -237,17 +226,6 @@ LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0282]: type annotations needed
--> $DIR/duplicate.rs:142:5
|
LL | iter::empty()
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
|
help: consider specifying the generic argument
|
LL | iter::empty::<T>()
| +++++
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
--> $DIR/duplicate.rs:145:45
|
@ -266,17 +244,6 @@ LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0282]: type annotations needed
--> $DIR/duplicate.rs:148:5
|
LL | iter::empty()
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
|
help: consider specifying the generic argument
|
LL | iter::empty::<T>()
| +++++
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
--> $DIR/duplicate.rs:151:40
|
@ -697,6 +664,39 @@ LL | type A: Iterator<Item: 'static, Item: 'static>;
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0282]: type annotations needed
--> $DIR/duplicate.rs:136:5
|
LL | iter::empty()
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
|
help: consider specifying the generic argument
|
LL | iter::empty::<T>()
| +++++
error[E0282]: type annotations needed
--> $DIR/duplicate.rs:142:5
|
LL | iter::empty()
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
|
help: consider specifying the generic argument
|
LL | iter::empty::<T>()
| +++++
error[E0282]: type annotations needed
--> $DIR/duplicate.rs:148:5
|
LL | iter::empty()
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
|
help: consider specifying the generic argument
|
LL | iter::empty::<T>()
| +++++
error: aborting due to 81 previous errors
Some errors have detailed explanations: E0282, E0719.

View File

@ -38,16 +38,6 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= help: to use an async block, remove the `||`: `async {`
error[E0658]: use of unstable library feature 'async_closure'
--> $DIR/edition-2015.rs:1:22
|
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
| ^^^^
|
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
= help: add `#![feature(async_closure)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: use of unstable library feature 'async_closure'
--> $DIR/edition-2015.rs:1:42
|
@ -58,6 +48,16 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
= help: add `#![feature(async_closure)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: use of unstable library feature 'async_closure'
--> $DIR/edition-2015.rs:1:22
|
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
| ^^^^
|
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
= help: add `#![feature(async_closure)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,3 +1,12 @@
error[E0307]: invalid `self` parameter type: `&dyn Foo`
--> $DIR/inference_var_self_argument.rs:5:24
|
LL | async fn foo(self: &dyn Foo) {
| ^^^^^^^^
|
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/inference_var_self_argument.rs:5:5
|
@ -13,15 +22,6 @@ LL | async fn foo(self: &dyn Foo) {
| ^^^ ...because method `foo` is `async`
= help: consider moving `foo` to another trait
error[E0307]: invalid `self` parameter type: `&dyn Foo`
--> $DIR/inference_var_self_argument.rs:5:24
|
LL | async fn foo(self: &dyn Foo) {
| ^^^^^^^^
|
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0307.

View File

@ -1,9 +1,3 @@
error[E0308]: mismatched types
--> $DIR/issue-66312.rs:9:8
|
LL | if x.is_some() {
| ^^^^^^^^^^^ expected `bool`, found `()`
error[E0307]: invalid `self` parameter type: `T`
--> $DIR/issue-66312.rs:4:22
|
@ -13,6 +7,12 @@ LL | fn is_some(self: T);
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error[E0308]: mismatched types
--> $DIR/issue-66312.rs:9:8
|
LL | if x.is_some() {
| ^^^^^^^^^^^ expected `bool`, found `()`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0307, E0308.

View File

@ -1,3 +1,11 @@
error: `Foo` is forbidden as the type of a const generic parameter
--> $DIR/opaque_types.rs:7:17
|
LL | fn foo<const C: Foo>() {}
| ^^^
|
= note: the only supported types are integers, `bool`, and `char`
error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
--> $DIR/opaque_types.rs:7:4
|
@ -68,14 +76,6 @@ LL | type Foo = impl Sized;
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: `Foo` is forbidden as the type of a const generic parameter
--> $DIR/opaque_types.rs:7:17
|
LL | fn foo<const C: Foo>() {}
| ^^^
|
= note: the only supported types are integers, `bool`, and `char`
error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}`
--> $DIR/opaque_types.rs:3:12
|

View File

@ -3,22 +3,6 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
warning: this function depends on never type fallback being `()`
--> $DIR/unsupported.rs:20:9
|
LL | fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: opaque::Trait` will fail
--> $DIR/unsupported.rs:20:28
|
LL | fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^
= note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:26:5: 26:24>::{synthetic#0}`
--> $DIR/unsupported.rs:27:25
|
@ -52,6 +36,22 @@ note: in edition 2024, the requirement `!: opaque::Trait` will fail
|
LL | pub fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^
= note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
warning: this function depends on never type fallback being `()`
--> $DIR/unsupported.rs:20:9
|
LL | fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: opaque::Trait` will fail
--> $DIR/unsupported.rs:20:28
|
LL | fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:25>::{synthetic#0}`
--> $DIR/unsupported.rs:30:24

View File

@ -18,14 +18,6 @@ LL | type Bop = impl std::fmt::Debug;
= help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: unconstrained opaque type
--> $DIR/feature-gate-impl_trait_in_assoc_type.rs:6:16
|
LL | type Bar = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `Bar` must be used in combination with a concrete type within the same impl
error[E0658]: inherent associated types are unstable
--> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:5
|
@ -36,6 +28,14 @@ LL | type Bop = impl std::fmt::Debug;
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: unconstrained opaque type
--> $DIR/feature-gate-impl_trait_in_assoc_type.rs:6:16
|
LL | type Bar = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `Bar` must be used in combination with a concrete type within the same impl
error: unconstrained opaque type
--> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:16
|

View File

@ -19,7 +19,10 @@ error[E0720]: cannot resolve opaque type
--> $DIR/impl-fn-predefined-lifetimes.rs:4:35
|
LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
| ^^^^^^^^^^^^^^^ cannot resolve opaque type
| ^^^^^^^^^^^^^^^ recursive opaque type
...
LL | |x| x
| ----- returning here with type `{closure@$DIR/impl-fn-predefined-lifetimes.rs:7:5: 7:8}`
error: aborting due to 2 previous errors; 1 warning emitted

View File

@ -1,9 +1,3 @@
error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:18}` to be a future that resolves to `u8`, but it resolves to `()`
--> $DIR/issue-78722-2.rs:11:30
|
LL | fn concrete_use() -> F {
| ^ expected `()`, found `u8`
error[E0308]: mismatched types
--> $DIR/issue-78722-2.rs:16:20
|
@ -18,6 +12,12 @@ LL | let f: F = async { 1 };
= note: expected opaque type `F`
found `async` block `{async block@$DIR/issue-78722-2.rs:16:20: 16:25}`
error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:18}` to be a future that resolves to `u8`, but it resolves to `()`
--> $DIR/issue-78722-2.rs:11:30
|
LL | fn concrete_use() -> F {
| ^ expected `()`, found `u8`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0271, E0308.

View File

@ -1,24 +1,3 @@
error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
|
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
| ^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unconstrained opaque type
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same module
error[E0053]: method `eq` has an incompatible type for trait
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:30
|
@ -35,8 +14,21 @@ help: change the parameter type to match the trait
LL | fn eq(&self, _other: &(a::Bar, i32)) -> bool {
| ~~~~~~~~~~~~~~
error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
|
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
| ^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unconstrained opaque type
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -64,6 +56,14 @@ help: change the parameter type to match the trait
LL | fn eq(&self, _other: &(b::Foo, i32)) -> bool {
| ~~~~~~~~~~~~~~
error: unconstrained opaque type
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same module
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0053`.

View File

@ -342,44 +342,6 @@ LL | let _in_return_in_local_variable = || -> impl Fn() { || {} };
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
error[E0283]: type annotations needed
--> $DIR/where-allowed.rs:46:57
|
LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: Debug`
error[E0283]: type annotations needed
--> $DIR/where-allowed.rs:64:46
|
LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
= note: multiple `impl`s satisfying `_: Fn()` found in the following crates: `alloc`, `core`:
- impl<A, F> Fn<A> for &F
where A: Tuple, F: Fn<A>, F: ?Sized;
- impl<Args, F, A> Fn<Args> for Box<F, A>
where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/where-allowed.rs:238:7
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
= note: `#[deny(invalid_type_param_default)]` on by default
error[E0118]: no nominal type found for inherent implementation
--> $DIR/where-allowed.rs:238:1
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
= note: either implement a trait on it or create a newtype to wrap it instead
error[E0053]: method `in_trait_impl_return` has an incompatible type for trait
--> $DIR/where-allowed.rs:128:34
|
@ -402,14 +364,6 @@ help: change the output type to match the trait
LL | fn in_trait_impl_return() -> <() as DummyTrait>::Out { () }
| ~~~~~~~~~~~~~~~~~~~~~~~
error: unconstrained opaque type
--> $DIR/where-allowed.rs:121:16
|
LL | type Out = impl Debug;
| ^^^^^^^^^^
|
= note: `Out` must be used in combination with a concrete type within the same impl
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/where-allowed.rs:245:36
|
@ -418,12 +372,69 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
= note: `#[deny(invalid_type_param_default)]` on by default
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/where-allowed.rs:238:7
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
error[E0283]: type annotations needed
--> $DIR/where-allowed.rs:46:57
|
LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: Debug`
error[E0283]: type annotations needed
--> $DIR/where-allowed.rs:64:46
|
LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
= note: multiple `impl`s satisfying `_: Fn()` found in the following crates: `alloc`, `core`:
- impl<A, F> Fn<A> for &F
where A: Tuple, F: Fn<A>, F: ?Sized;
- impl<Args, F, A> Fn<Args> for Box<F, A>
where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
error[E0118]: no nominal type found for inherent implementation
--> $DIR/where-allowed.rs:238:1
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
= note: either implement a trait on it or create a newtype to wrap it instead
error: unconstrained opaque type
--> $DIR/where-allowed.rs:121:16
|
LL | type Out = impl Debug;
| ^^^^^^^^^^
|
= note: `Out` must be used in combination with a concrete type within the same impl
error: aborting due to 49 previous errors
Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666.
For more information about an error, try `rustc --explain E0053`.
Future incompatibility report: Future breakage diagnostic:
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/where-allowed.rs:245:36
|
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
| ^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
= note: `#[deny(invalid_type_param_default)]` on by default
Future breakage diagnostic:
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/where-allowed.rs:238:7
|
@ -434,14 +445,3 @@ LL | impl <T = impl Debug> T {}
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
= note: `#[deny(invalid_type_param_default)]` on by default
Future breakage diagnostic:
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/where-allowed.rs:245:36
|
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
| ^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
= note: `#[deny(invalid_type_param_default)]` on by default

View File

@ -26,7 +26,5 @@ type A = <m::Alias as m::Trait>::X; //~ ERROR type `Priv` is private
trait Tr2<T> {}
impl<T> Tr2<T> for u8 {}
fn g() -> impl Tr2<m::Alias> { 0 } //~ ERROR type `Priv` is private
//~| ERROR type `Priv` is private
fn g_ext() -> impl Tr2<ext::Alias> { 0 } //~ ERROR type `ext::Priv` is private
//~| ERROR type `ext::Priv` is private
fn main() {}

View File

@ -46,23 +46,11 @@ error: type `Priv` is private
LL | fn g() -> impl Tr2<m::Alias> { 0 }
| ^^^^^^^^^^^^^^^^^^ private type
error: type `Priv` is private
--> $DIR/private-type-in-interface.rs:28:11
|
LL | fn g() -> impl Tr2<m::Alias> { 0 }
| ^^^^^^^^^^^^^^^^^^ private type
error: type `ext::Priv` is private
--> $DIR/private-type-in-interface.rs:30:15
--> $DIR/private-type-in-interface.rs:29:15
|
LL | fn g_ext() -> impl Tr2<ext::Alias> { 0 }
| ^^^^^^^^^^^^^^^^^^^^ private type
error: type `ext::Priv` is private
--> $DIR/private-type-in-interface.rs:30:15
|
LL | fn g_ext() -> impl Tr2<ext::Alias> { 0 }
| ^^^^^^^^^^^^^^^^^^^^ private type
error: aborting due to 11 previous errors
error: aborting due to 9 previous errors

View File

@ -67,38 +67,6 @@ error: `~const` can only be applied to `#[const_trait]` traits
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:25:29
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:25:48
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:25:29
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:25:48
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:29:29
|
@ -155,6 +123,38 @@ LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:25:29
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:25:48
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:25:29
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:25:48
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
--> $DIR/const-impl-trait.rs:37:26
|

View File

@ -1,3 +1,12 @@
error[E0307]: invalid `self` parameter type: `Bar`
--> $DIR/arbitrary-self-opaque.rs:8:18
|
LL | fn foo(self: Bar) {}
| ^^^
|
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
--> $DIR/arbitrary-self-opaque.rs:8:8
|
@ -19,15 +28,6 @@ LL | type Bar = impl Sized;
|
= note: `Bar` must be used in combination with a concrete type within the same module
error[E0307]: invalid `self` parameter type: `Bar`
--> $DIR/arbitrary-self-opaque.rs:8:18
|
LL | fn foo(self: Bar) {}
| ^^^
|
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0307`.

View File

@ -9,8 +9,8 @@ LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &Foo { f }
| ++++ ++ ++
LL | async fn a<'a>(self: Pin<&Foo>, f: &'a Foo) -> &'a Foo { f }
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75
@ -23,8 +23,8 @@ LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ++++ ++ ++
LL | async fn c<'a>(self: Pin<&Self>, f: &'a Foo, g: &Foo) -> (Pin<&'a Foo>, &'a Foo) { (self, f) }
| ++++ ++ ++ ++
error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
@ -37,8 +37,8 @@ LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
|
help: consider reusing a named lifetime parameter and update trait if needed
|
LL | async fn bar<'a>(self: Alias<&'a Self>, arg: &'a ()) -> &() { arg }
| ++
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &'a () { arg }
| ++
error: aborting due to 3 previous errors

View File

@ -11,34 +11,34 @@ struct Struct<'a> {
impl<'a> Struct<'a> {
// Test using `&self` sugar:
async fn ref_self<'b>(&'b self, f: &'b u32) -> &u32 {
async fn ref_self<'b>(&self, f: &'b u32) -> &'b u32 {
f
//~^ ERROR lifetime may not live long enough
}
// Test using `&Self` explicitly:
async fn ref_Self<'b>(self: &'b Self, f: &'b u32) -> &u32 {
async fn ref_Self<'b>(self: &Self, f: &'b u32) -> &'b u32 {
f
//~^ ERROR lifetime may not live long enough
}
async fn box_ref_Self<'b>(self: Box<&'b Self>, f: &'b u32) -> &u32 {
async fn box_ref_Self<'b>(self: Box<&Self>, f: &'b u32) -> &'b u32 {
f
//~^ ERROR lifetime may not live long enough
}
async fn pin_ref_Self<'b>(self: Pin<&'b Self>, f: &'b u32) -> &u32 {
async fn pin_ref_Self<'b>(self: Pin<&Self>, f: &'b u32) -> &'b u32 {
f
//~^ ERROR lifetime may not live long enough
}
async fn box_box_ref_Self<'b>(self: Box<Box<&'b Self>>, f: &'b u32) -> &u32 {
async fn box_box_ref_Self<'b>(self: Box<Box<&Self>>, f: &'b u32) -> &'b u32 {
f
//~^ ERROR lifetime may not live long enough
}
async fn box_pin_Self<'b>(self: Box<Pin<&'b Self>>, f: &'b u32) -> &u32 {
async fn box_pin_Self<'b>(self: Box<Pin<&Self>>, f: &'b u32) -> &'b u32 {
f
//~^ ERROR lifetime may not live long enough
}

View File

@ -10,8 +10,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_self<'b>(&'b self, f: &'b u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_self<'b>(&self, f: &'b u32) -> &'b u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:22:9
@ -25,8 +25,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_Self<'b>(self: &'b Self, f: &'b u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_Self<'b>(self: &Self, f: &'b u32) -> &'b u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:27:9
@ -40,8 +40,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_ref_Self<'b>(self: Box<&'b Self>, f: &'b u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_ref_Self<'b>(self: Box<&Self>, f: &'b u32) -> &'b u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:32:9
@ -55,8 +55,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn pin_ref_Self<'b>(self: Pin<&'b Self>, f: &'b u32) -> &u32 {
| ++++ ++ ++
LL | async fn pin_ref_Self<'b>(self: Pin<&Self>, f: &'b u32) -> &'b u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:37:9
@ -70,8 +70,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_box_ref_Self<'b>(self: Box<Box<&'b Self>>, f: &'b u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_box_ref_Self<'b>(self: Box<Box<&Self>>, f: &'b u32) -> &'b u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:42:9
@ -85,8 +85,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_pin_Self<'b>(self: Box<Pin<&'b Self>>, f: &'b u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_pin_Self<'b>(self: Box<Pin<&Self>>, f: &'b u32) -> &'b u32 {
| ++++ ++ ++
error: aborting due to 6 previous errors

View File

@ -10,8 +10,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_AssocType<'a>(self: &'a <Struct as Trait>::AssocType, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_AssocType<'a>(self: &<Struct as Trait>::AssocType, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-assoc-async.rs:24:9
@ -25,8 +25,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_ref_AssocType<'a>(self: Box<&'a <Struct as Trait>::AssocType>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_ref_AssocType<'a>(self: Box<&<Struct as Trait>::AssocType>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-assoc-async.rs:29:9
@ -40,8 +40,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn pin_ref_AssocType<'a>(self: Pin<&'a <Struct as Trait>::AssocType>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn pin_ref_AssocType<'a>(self: Pin<&<Struct as Trait>::AssocType>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-assoc-async.rs:34:9
@ -55,8 +55,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_box_ref_AssocType<'a>(self: Box<Box<&'a <Struct as Trait>::AssocType>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_box_ref_AssocType<'a>(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-assoc-async.rs:39:9
@ -70,8 +70,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_pin_ref_AssocType<'a>(self: Box<Pin<&'a <Struct as Trait>::AssocType>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_pin_ref_AssocType<'a>(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: aborting due to 5 previous errors

View File

@ -10,8 +10,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_self<'a>(&mut self, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:20:9
@ -25,8 +25,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_Self<'a>(self: &mut Self, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:25:9
@ -40,8 +40,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_ref_Self<'a>(self: Box<&mut Self>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:30:9
@ -55,8 +55,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn pin_ref_Self<'a>(self: Pin<&mut Self>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:35:9
@ -70,8 +70,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_box_ref_Self<'a>(self: Box<Box<&mut Self>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:40:9
@ -85,8 +85,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_pin_ref_Self<'a>(self: Box<Pin<&mut Self>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: aborting due to 6 previous errors

View File

@ -10,8 +10,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_Struct<'a>(self: &mut Struct, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-struct-async.rs:18:9
@ -25,8 +25,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_ref_Struct<'a>(self: Box<&mut Struct>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-struct-async.rs:23:9
@ -40,8 +40,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn pin_ref_Struct<'a>(self: Pin<&mut Struct>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-struct-async.rs:28:9
@ -55,8 +55,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_box_ref_Struct<'a>(self: Box<Box<&'a mut Struct>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_box_ref_Struct<'a>(self: Box<Box<&mut Struct>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-mut-struct-async.rs:33:9
@ -70,8 +70,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_pin_ref_Struct<'a>(self: Box<Pin<&'a mut Struct>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_pin_ref_Struct<'a>(self: Box<Pin<&mut Struct>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: aborting due to 5 previous errors

View File

@ -10,8 +10,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_self<'a>(&self, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-self-async.rs:30:9
@ -25,8 +25,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_Self<'a>(self: &Self, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-self-async.rs:35:9
@ -40,8 +40,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_ref_Self<'a>(self: Box<&Self>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-self-async.rs:40:9
@ -55,8 +55,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn pin_ref_Self<'a>(self: Pin<&Self>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-self-async.rs:45:9
@ -70,8 +70,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_box_ref_Self<'a>(self: Box<Box<&Self>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-self-async.rs:50:9
@ -85,8 +85,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_pin_ref_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_pin_ref_Self<'a>(self: Box<Pin<&Self>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-self-async.rs:55:9
@ -100,8 +100,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 {
| ++++ ++ ++
LL | async fn wrap_ref_Self_Self<'a>(self: Wrap<&Self, Self>, f: &'a u8) -> &'a u8 {
| ++++ ++ ++
error: aborting due to 7 previous errors

View File

@ -10,8 +10,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn ref_Struct<'a>(self: &Struct, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-struct-async.rs:18:9
@ -25,8 +25,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_ref_Struct<'a>(self: Box<&Struct>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-struct-async.rs:23:9
@ -40,8 +40,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn pin_ref_Struct<'a>(self: Pin<&Struct>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-struct-async.rs:28:9
@ -55,8 +55,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_box_ref_Struct<'a>(self: Box<Box<&'a Struct>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_box_ref_Struct<'a>(self: Box<Box<&Struct>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/ref-struct-async.rs:33:9
@ -70,8 +70,8 @@ LL | f
|
help: consider introducing a named lifetime parameter and update trait if needed
|
LL | async fn box_pin_Struct<'a>(self: Box<Pin<&'a Struct>>, f: &'a u32) -> &u32 {
| ++++ ++ ++
LL | async fn box_pin_Struct<'a>(self: Box<Pin<&Struct>>, f: &'a u32) -> &'a u32 {
| ++++ ++ ++
error: aborting due to 5 previous errors

View File

@ -0,0 +1,18 @@
#![feature(type_alias_impl_trait)]
trait Captures<'a> {}
impl<T> Captures<'_> for T {}
fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
loop {}
}
pub fn main() {
//~^ ERROR item does not constrain `Opaque::{opaque#0}`, but has it in its signature
type Opaque = impl Sized;
fn define() -> Opaque {
let x: Opaque = dyn_hoops::<()>();
x
}
}

View File

@ -0,0 +1,28 @@
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
--> $DIR/bound-lifetime-through-dyn-trait.rs:6:71
|
LL | fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
| ^^
|
note: lifetime declared here
--> $DIR/bound-lifetime-through-dyn-trait.rs:6:37
|
LL | fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
| ^^
error: item does not constrain `Opaque::{opaque#0}`, but has it in its signature
--> $DIR/bound-lifetime-through-dyn-trait.rs:11:8
|
LL | pub fn main() {
| ^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/bound-lifetime-through-dyn-trait.rs:13:19
|
LL | type Opaque = impl Sized;
| ^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0657`.

View File

@ -1,3 +1,11 @@
error: `Bar` is forbidden as the type of a const generic parameter
--> $DIR/const_generic_type.rs:8:24
|
LL | async fn test<const N: crate::Bar>() {
| ^^^^^^^^^^
|
= note: the only supported types are integers, `bool`, and `char`
error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
--> $DIR/const_generic_type.rs:8:10
|
@ -39,13 +47,5 @@ LL | type Bar = impl std::fmt::Display;
|
= note: `Bar` must be used in combination with a concrete type within the same module
error: `Bar` is forbidden as the type of a const generic parameter
--> $DIR/const_generic_type.rs:8:24
|
LL | async fn test<const N: crate::Bar>() {
| ^^^^^^^^^^
|
= note: the only supported types are integers, `bool`, and `char`
error: aborting due to 4 previous errors

View File

@ -7,19 +7,6 @@ LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error: item does not constrain `lifetime_params::Ty::{opaque#0}`, but has it in its signature
--> $DIR/constrain_inputs.rs:6:8
|
LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
| ^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/constrain_inputs.rs:4:19
|
LL | type Ty<'a> = impl Sized;
| ^^^^^^^^^^
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> $DIR/constrain_inputs.rs:10:35
|
@ -38,6 +25,19 @@ LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter
error: item does not constrain `lifetime_params::Ty::{opaque#0}`, but has it in its signature
--> $DIR/constrain_inputs.rs:6:8
|
LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
| ^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/constrain_inputs.rs:4:19
|
LL | type Ty<'a> = impl Sized;
| ^^^^^^^^^^
error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> $DIR/constrain_inputs.rs:19:31
|

View File

@ -1,3 +1,19 @@
error[E0277]: the trait bound `T: Trait` is not satisfied
--> $DIR/generic_underconstrained.rs:9:31
|
LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
|
note: required by a bound on the type alias `Underconstrained`
--> $DIR/generic_underconstrained.rs:6:26
|
LL | type Underconstrained<T: Trait> = impl Send;
| ^^^^^ required by this bound
help: consider restricting type parameter `T`
|
LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
| +++++++
error[E0277]: the trait bound `T: Trait` is not satisfied
--> $DIR/generic_underconstrained.rs:9:51
|
@ -19,22 +35,6 @@ help: consider restricting type parameter `T`
LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
| +++++++
error[E0277]: the trait bound `T: Trait` is not satisfied
--> $DIR/generic_underconstrained.rs:9:31
|
LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
|
note: required by a bound on the type alias `Underconstrained`
--> $DIR/generic_underconstrained.rs:6:26
|
LL | type Underconstrained<T: Trait> = impl Send;
| ^^^^^ required by this bound
help: consider restricting type parameter `T`
|
LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
| +++++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,3 +1,35 @@
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_underconstrained2.rs:8:33
|
LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
| ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
note: required by a bound on the type alias `Underconstrained`
--> $DIR/generic_underconstrained2.rs:5:26
|
LL | type Underconstrained<T: std::fmt::Debug> = impl Send;
| ^^^^^^^^^^^^^^^ required by this bound
help: consider restricting type parameter `U`
|
LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
| +++++++++++++++++
error[E0277]: `V` doesn't implement `Debug`
--> $DIR/generic_underconstrained2.rs:17:43
|
LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
| ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
note: required by a bound on the type alias `Underconstrained2`
--> $DIR/generic_underconstrained2.rs:14:27
|
LL | type Underconstrained2<T: std::fmt::Debug> = impl Send;
| ^^^^^^^^^^^^^^^ required by this bound
help: consider restricting type parameter `V`
|
LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained2<V> {
| +++++++++++++++++
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_underconstrained2.rs:8:53
|
@ -40,38 +72,6 @@ help: consider restricting type parameter `V`
LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained2<V> {
| +++++++++++++++++
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_underconstrained2.rs:8:33
|
LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
| ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
note: required by a bound on the type alias `Underconstrained`
--> $DIR/generic_underconstrained2.rs:5:26
|
LL | type Underconstrained<T: std::fmt::Debug> = impl Send;
| ^^^^^^^^^^^^^^^ required by this bound
help: consider restricting type parameter `U`
|
LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
| +++++++++++++++++
error[E0277]: `V` doesn't implement `Debug`
--> $DIR/generic_underconstrained2.rs:17:43
|
LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
| ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
note: required by a bound on the type alias `Underconstrained2`
--> $DIR/generic_underconstrained2.rs:14:27
|
LL | type Underconstrained2<T: std::fmt::Debug> = impl Send;
| ^^^^^^^^^^^^^^^ required by this bound
help: consider restricting type parameter `V`
|
LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained2<V> {
| +++++++++++++++++
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,3 +1,9 @@
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
|
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
| ^ unconstrained type parameter
error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:28:8
|
@ -24,12 +30,6 @@ note: this opaque type is in the signature
LL | type DummyT<T> = impl F;
| ^^^^^^
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
|
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
| ^ unconstrained type parameter
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0207`.

View File

@ -1,30 +1,3 @@
error[E0391]: cycle detected when computing type of `Bar::{opaque#0}`
--> $DIR/in-where-clause.rs:5:12
|
LL | type Bar = impl Sized;
| ^^^^^^^^^^
|
note: ...which requires computing type of opaque `Bar::{opaque#0}`...
--> $DIR/in-where-clause.rs:5:12
|
LL | type Bar = impl Sized;
| ^^^^^^^^^^
note: ...which requires type-checking `foo`...
--> $DIR/in-where-clause.rs:8:1
|
LL | / fn foo() -> Bar
LL | | where
LL | | Bar: Send,
| |______________^
= note: ...which requires revealing opaque types in `[Binder { value: TraitPredicate(<Bar as core::marker::Send>, polarity:Positive), bound_vars: [] }]`...
= note: ...which again requires computing type of `Bar::{opaque#0}`, completing the cycle
note: cycle used when checking that `Bar::{opaque#0}` is well-formed
--> $DIR/in-where-clause.rs:5:12
|
LL | type Bar = impl Sized;
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error[E0283]: type annotations needed: cannot satisfy `Bar: Send`
--> $DIR/in-where-clause.rs:12:9
|
@ -41,6 +14,29 @@ LL | where
LL | Bar: Send,
| ^^^^ required by this bound in `foo`
error[E0391]: cycle detected when computing type of opaque `Bar::{opaque#0}`
--> $DIR/in-where-clause.rs:5:12
|
LL | type Bar = impl Sized;
| ^^^^^^^^^^
|
note: ...which requires type-checking `foo`...
--> $DIR/in-where-clause.rs:8:1
|
LL | / fn foo() -> Bar
LL | | where
LL | | Bar: Send,
| |______________^
= note: ...which requires revealing opaque types in `[Binder { value: TraitPredicate(<Bar as core::marker::Send>, polarity:Positive), bound_vars: [] }]`...
note: ...which requires computing type of `Bar::{opaque#0}`...
--> $DIR/in-where-clause.rs:5:12
|
LL | type Bar = impl Sized;
| ^^^^^^^^^^
= note: ...which again requires computing type of opaque `Bar::{opaque#0}`, completing the cycle
= note: cycle used when evaluating trait selection obligation `Bar: core::marker::Send`
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0283, E0391.

View File

@ -1,15 +1,14 @@
#![feature(type_alias_impl_trait)]
#![allow(dead_code)]
type Bug<T, U> = impl Fn(T) -> U + Copy; //~ ERROR cycle detected
type Bug<T, U> = impl Fn(T) -> U + Copy;
const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
//~^ ERROR: non-defining opaque type use
//~| ERROR: item does not constrain
//~| ERROR: item does not constrain
//~^ ERROR cycle detected
//~| ERROR: non-defining opaque type use
fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied
|x| x.into()
}
fn main() {

View File

@ -10,75 +10,33 @@ note: for this opaque type
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0391]: cycle detected when computing type of `Bug::{opaque#0}`
error[E0391]: cycle detected when type-checking `CONST_BUG`
--> $DIR/issue-53092-2.rs:6:1
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: ...which requires computing layout of `Bug<u8, ()>`...
= note: ...which requires normalizing `Bug<u8, ()>`...
note: ...which requires computing type of `Bug::{opaque#0}`...
--> $DIR/issue-53092-2.rs:4:18
|
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires computing type of opaque `Bug::{opaque#0}`...
--> $DIR/issue-53092-2.rs:4:18
|
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `CONST_BUG`...
= note: ...which again requires type-checking `CONST_BUG`, completing the cycle
note: cycle used when checking that `CONST_BUG` is well-formed
--> $DIR/issue-53092-2.rs:6:1
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing layout of `Bug<u8, ()>`...
= note: ...which requires normalizing `Bug<u8, ()>`...
= note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle
note: cycle used when checking that `Bug::{opaque#0}` is well-formed
--> $DIR/issue-53092-2.rs:4:18
|
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
--> $DIR/issue-53092-2.rs:6:7
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/issue-53092-2.rs:4:18
|
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
--> $DIR/issue-53092-2.rs:6:61
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/issue-53092-2.rs:4:18
|
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `U: From<T>` is not satisfied
--> $DIR/issue-53092-2.rs:12:5
|
LL | |x| x.into()
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
note: required by a bound in `make_bug`
--> $DIR/issue-53092-2.rs:11:19
|
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
| ^^^^^^^ required by this bound in `make_bug`
help: consider restricting type parameter `U`
|
LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
| +++++++++++++++++++++++
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0391, E0792.
For more information about an error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0391, E0792.
For more information about an error, try `rustc --explain E0391`.

View File

@ -1,3 +1,12 @@
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
--> $DIR/issue-84660-unsoundness.rs:29:1
|
LL | impl<In, Out> Trait<Bar, In> for Out {
| ------------------------------------ first implementation here
...
LL | impl<In, Out> Trait<(), In> for Out {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
--> $DIR/issue-84660-unsoundness.rs:22:8
|
@ -11,15 +20,6 @@ note: this opaque type is in the signature
LL | type Bar = impl Foo;
| ^^^^^^^^
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
--> $DIR/issue-84660-unsoundness.rs:29:1
|
LL | impl<In, Out> Trait<Bar, In> for Out {
| ------------------------------------ first implementation here
...
LL | impl<In, Out> Trait<(), In> for Out {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`.

View File

@ -1,3 +1,12 @@
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
--> $DIR/issue-84660-unsoundness.rs:29:1
|
LL | impl<In, Out> Trait<Bar, In> for Out {
| ------------------------------------ first implementation here
...
LL | impl<In, Out> Trait<(), In> for Out {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
error[E0284]: type annotations needed: cannot satisfy `Bar == _`
--> $DIR/issue-84660-unsoundness.rs:22:37
|
@ -9,15 +18,6 @@ LL | | unreachable!();
LL | | }
| |_____^ cannot satisfy `Bar == _`
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
--> $DIR/issue-84660-unsoundness.rs:29:1
|
LL | impl<In, Out> Trait<Bar, In> for Out {
| ------------------------------------ first implementation here
...
LL | impl<In, Out> Trait<(), In> for Out {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0119, E0284.

View File

@ -1,11 +1,3 @@
error: unconstrained opaque type
--> $DIR/nested-in-anon-const.rs:13:33
|
LL | type B<Z> = impl Sized;
| ^^^^^^^^^^
|
= note: `B` must be used in combination with a concrete type within the same item
error[E0308]: mismatched types
--> $DIR/nested-in-anon-const.rs:12:17
|
@ -15,6 +7,14 @@ LL | |
LL | | },
| |_________________^ expected `usize`, found `()`
error: unconstrained opaque type
--> $DIR/nested-in-anon-const.rs:13:33
|
LL | type B<Z> = impl Sized;
| ^^^^^^^^^^
|
= note: `B` must be used in combination with a concrete type within the same item
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,13 @@
#![allow(incomplete_features)]
#![feature(non_lifetime_binders)]
trait Trait<T: ?Sized> {}
fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
//~^ ERROR associated type `Assoc` not found for `Trait`
//~| ERROR associated type `Assoc` not found for `Trait`
//~| the trait bound `{integer}: Trait<()>` is not satisfied
16
}
fn main() {}

View File

@ -0,0 +1,30 @@
error[E0220]: associated type `Assoc` not found for `Trait`
--> $DIR/non-lifetime-binder-in-constraint.rs:6:39
|
LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
| ^^^^^ associated type `Assoc` not found
error[E0220]: associated type `Assoc` not found for `Trait`
--> $DIR/non-lifetime-binder-in-constraint.rs:6:39
|
LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
| ^^^^^ associated type `Assoc` not found
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0277]: the trait bound `{integer}: Trait<()>` is not satisfied
--> $DIR/non-lifetime-binder-in-constraint.rs:6:17
|
LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<()>` is not implemented for `{integer}`
|
help: this trait has no implementations, consider adding one
--> $DIR/non-lifetime-binder-in-constraint.rs:4:1
|
LL | trait Trait<T: ?Sized> {}
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0220, E0277.
For more information about an error, try `rustc --explain E0220`.

Some files were not shown because too many files have changed in this diff Show More