Auto merge of #131215 - matthiaskrgr:rollup-i021ef7, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #131024 (Don't give method suggestions when method probe fails due to bad implementation of `Deref`) - #131112 (TransmuteFrom: Gracefully handle unnormalized types and normalization errors) - #131176 (.gitignore files for nix) - #131183 (Refactoring to `OpaqueTyOrigin`) - #131187 (Avoid ICE in coverage builds with bad `#[coverage(..)]` attributes) - #131192 (Handle `rustc_query_impl` cases of `rustc::potential_query_instability` lint) - #131197 (Avoid emptiness check in `PeekMut::pop`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e1e3cac26d
55 changed files with 433 additions and 258 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -86,4 +86,13 @@ package.json
|
||||||
## Rustdoc GUI tests
|
## Rustdoc GUI tests
|
||||||
tests/rustdoc-gui/src/**.lock
|
tests/rustdoc-gui/src/**.lock
|
||||||
|
|
||||||
|
## direnv
|
||||||
|
.envrc
|
||||||
|
.direnv/
|
||||||
|
|
||||||
|
## nix
|
||||||
|
flake.nix
|
||||||
|
flake.lock
|
||||||
|
default.nix
|
||||||
|
|
||||||
# Before adding new lines, see the comment at the top.
|
# Before adding new lines, see the comment at the top.
|
||||||
|
|
|
@ -286,7 +286,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
parent: this.local_def_id(id),
|
parent: this.local_def_id(id),
|
||||||
in_assoc_ty: false,
|
in_assoc_ty: false,
|
||||||
},
|
},
|
||||||
fn_kind: None,
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -983,7 +982,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
parent: this.local_def_id(i.id),
|
parent: this.local_def_id(i.id),
|
||||||
in_assoc_ty: true,
|
in_assoc_ty: true,
|
||||||
},
|
},
|
||||||
fn_kind: None,
|
|
||||||
});
|
});
|
||||||
hir::ImplItemKind::Type(ty)
|
hir::ImplItemKind::Type(ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,12 +288,7 @@ enum ImplTraitContext {
|
||||||
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
|
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
|
||||||
/// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
|
/// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
|
||||||
///
|
///
|
||||||
OpaqueTy {
|
OpaqueTy { origin: hir::OpaqueTyOrigin },
|
||||||
origin: hir::OpaqueTyOrigin,
|
|
||||||
/// Only used to change the lifetime capture rules, since
|
|
||||||
/// RPITIT captures all in scope, RPIT does not.
|
|
||||||
fn_kind: Option<FnDeclKind>,
|
|
||||||
},
|
|
||||||
/// `impl Trait` is unstably accepted in this position.
|
/// `impl Trait` is unstably accepted in this position.
|
||||||
FeatureGated(ImplTraitPosition, Symbol),
|
FeatureGated(ImplTraitPosition, Symbol),
|
||||||
/// `impl Trait` is not accepted in this position.
|
/// `impl Trait` is not accepted in this position.
|
||||||
|
@ -1404,14 +1399,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
TyKind::ImplTrait(def_node_id, bounds) => {
|
TyKind::ImplTrait(def_node_id, bounds) => {
|
||||||
let span = t.span;
|
let span = t.span;
|
||||||
match itctx {
|
match itctx {
|
||||||
ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(
|
ImplTraitContext::OpaqueTy { origin } => {
|
||||||
span,
|
self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
|
||||||
origin,
|
}
|
||||||
*def_node_id,
|
|
||||||
bounds,
|
|
||||||
fn_kind,
|
|
||||||
itctx,
|
|
||||||
),
|
|
||||||
ImplTraitContext::Universal => {
|
ImplTraitContext::Universal => {
|
||||||
if let Some(span) = bounds.iter().find_map(|bound| match *bound {
|
if let Some(span) = bounds.iter().find_map(|bound| match *bound {
|
||||||
ast::GenericBound::Use(_, span) => Some(span),
|
ast::GenericBound::Use(_, span) => Some(span),
|
||||||
|
@ -1513,7 +1503,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
bounds: &GenericBounds,
|
bounds: &GenericBounds,
|
||||||
fn_kind: Option<FnDeclKind>,
|
|
||||||
itctx: ImplTraitContext,
|
itctx: ImplTraitContext,
|
||||||
) -> hir::TyKind<'hir> {
|
) -> hir::TyKind<'hir> {
|
||||||
// Make sure we know that some funky desugaring has been going on here.
|
// Make sure we know that some funky desugaring has been going on here.
|
||||||
|
@ -1555,11 +1544,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
.map(|(ident, id, _)| Lifetime { id, ident })
|
.map(|(ident, id, _)| Lifetime { id, ident })
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
hir::OpaqueTyOrigin::FnReturn(..) => {
|
hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => {
|
||||||
if matches!(
|
if in_trait_or_impl.is_some()
|
||||||
fn_kind.expect("expected RPITs to be lowered with a FnKind"),
|
|| self.tcx.features().lifetime_capture_rules_2024
|
||||||
FnDeclKind::Impl | FnDeclKind::Trait
|
|
||||||
) || self.tcx.features().lifetime_capture_rules_2024
|
|
||||||
|| span.at_least_rust_2024()
|
|| span.at_least_rust_2024()
|
||||||
{
|
{
|
||||||
// return-position impl trait in trait was decided to capture all
|
// return-position impl trait in trait was decided to capture all
|
||||||
|
@ -1576,16 +1563,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
lifetime_collector::lifetimes_in_bounds(self.resolver, bounds)
|
lifetime_collector::lifetimes_in_bounds(self.resolver, bounds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::OpaqueTyOrigin::AsyncFn(..) => {
|
hir::OpaqueTyOrigin::AsyncFn { .. } => {
|
||||||
unreachable!("should be using `lower_async_fn_ret_ty`")
|
unreachable!("should be using `lower_async_fn_ret_ty`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!(?captured_lifetimes_to_duplicate);
|
debug!(?captured_lifetimes_to_duplicate);
|
||||||
|
|
||||||
match fn_kind {
|
// Feature gate for RPITIT + use<..>
|
||||||
// Deny `use<>` on RPITIT in trait/trait-impl for now.
|
match origin {
|
||||||
Some(FnDeclKind::Trait | FnDeclKind::Impl) => {
|
rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => {
|
||||||
if let Some(span) = bounds.iter().find_map(|bound| match *bound {
|
if let Some(span) = bounds.iter().find_map(|bound| match *bound {
|
||||||
ast::GenericBound::Use(_, span) => Some(span),
|
ast::GenericBound::Use(_, span) => Some(span),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1593,20 +1580,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span });
|
self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
_ => {}
|
||||||
| Some(
|
|
||||||
FnDeclKind::Fn
|
|
||||||
| FnDeclKind::Inherent
|
|
||||||
| FnDeclKind::ExternFn
|
|
||||||
| FnDeclKind::Closure
|
|
||||||
| FnDeclKind::Pointer,
|
|
||||||
) => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.lower_opaque_inner(
|
self.lower_opaque_inner(
|
||||||
opaque_ty_node_id,
|
opaque_ty_node_id,
|
||||||
origin,
|
origin,
|
||||||
matches!(fn_kind, Some(FnDeclKind::Trait)),
|
|
||||||
captured_lifetimes_to_duplicate,
|
captured_lifetimes_to_duplicate,
|
||||||
span,
|
span,
|
||||||
opaque_ty_span,
|
opaque_ty_span,
|
||||||
|
@ -1618,7 +1597,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
&mut self,
|
&mut self,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
in_trait: bool,
|
|
||||||
captured_lifetimes_to_duplicate: FxIndexSet<Lifetime>,
|
captured_lifetimes_to_duplicate: FxIndexSet<Lifetime>,
|
||||||
span: Span,
|
span: Span,
|
||||||
opaque_ty_span: Span,
|
opaque_ty_span: Span,
|
||||||
|
@ -1747,7 +1725,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
bounds,
|
bounds,
|
||||||
origin,
|
origin,
|
||||||
lifetime_mapping,
|
lifetime_mapping,
|
||||||
in_trait,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate an `type Foo = impl Trait;` declaration.
|
// Generate an `type Foo = impl Trait;` declaration.
|
||||||
|
@ -1776,7 +1753,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
hir::TyKind::OpaqueDef(
|
hir::TyKind::OpaqueDef(
|
||||||
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
|
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
|
||||||
generic_args,
|
generic_args,
|
||||||
in_trait,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1864,12 +1840,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
None => match &decl.output {
|
None => match &decl.output {
|
||||||
FnRetTy::Ty(ty) => {
|
FnRetTy::Ty(ty) => {
|
||||||
let itctx = match kind {
|
let itctx = match kind {
|
||||||
FnDeclKind::Fn
|
FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
|
||||||
| FnDeclKind::Inherent
|
origin: hir::OpaqueTyOrigin::FnReturn {
|
||||||
| FnDeclKind::Trait
|
parent: self.local_def_id(fn_node_id),
|
||||||
| FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
|
in_trait_or_impl: None,
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)),
|
},
|
||||||
fn_kind: Some(kind),
|
},
|
||||||
|
FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::FnReturn {
|
||||||
|
parent: self.local_def_id(fn_node_id),
|
||||||
|
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::FnReturn {
|
||||||
|
parent: self.local_def_id(fn_node_id),
|
||||||
|
in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
FnDeclKind::ExternFn => {
|
FnDeclKind::ExternFn => {
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
|
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
|
||||||
|
@ -1951,10 +1938,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
.map(|(ident, id, _)| Lifetime { id, ident })
|
.map(|(ident, id, _)| Lifetime { id, ident })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let in_trait_or_impl = match fn_kind {
|
||||||
|
FnDeclKind::Trait => Some(hir::RpitContext::Trait),
|
||||||
|
FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
|
||||||
|
FnDeclKind::Fn | FnDeclKind::Inherent => None,
|
||||||
|
FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
let opaque_ty_ref = self.lower_opaque_inner(
|
let opaque_ty_ref = self.lower_opaque_inner(
|
||||||
opaque_ty_node_id,
|
opaque_ty_node_id,
|
||||||
hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
|
||||||
matches!(fn_kind, FnDeclKind::Trait),
|
|
||||||
captured_lifetimes,
|
captured_lifetimes,
|
||||||
span,
|
span,
|
||||||
opaque_ty_span,
|
opaque_ty_span,
|
||||||
|
@ -1964,8 +1957,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
coro,
|
coro,
|
||||||
opaque_ty_span,
|
opaque_ty_span,
|
||||||
ImplTraitContext::OpaqueTy {
|
ImplTraitContext::OpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
origin: hir::OpaqueTyOrigin::FnReturn {
|
||||||
fn_kind: Some(fn_kind),
|
parent: fn_def_id,
|
||||||
|
in_trait_or_impl,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
arena_vec![this; bound]
|
arena_vec![this; bound]
|
||||||
|
|
|
@ -832,7 +832,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
|
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 = self.infcx.tcx.hir();
|
||||||
|
|
||||||
let hir::TyKind::OpaqueDef(id, _, _) = hir_ty.kind else {
|
let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
hir_ty.span,
|
hir_ty.span,
|
||||||
"lowered return type of async fn is not OpaqueDef: {:?}",
|
"lowered return type of async fn is not OpaqueDef: {:?}",
|
||||||
|
|
|
@ -503,8 +503,8 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> {
|
||||||
let &Self { tcx, def_id, .. } = self;
|
let &Self { tcx, def_id, .. } = self;
|
||||||
let origin = tcx.opaque_type_origin(def_id);
|
let origin = tcx.opaque_type_origin(def_id);
|
||||||
let parent = match origin {
|
let parent = match origin {
|
||||||
hir::OpaqueTyOrigin::FnReturn(parent)
|
hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn(parent)
|
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
|
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
|
||||||
};
|
};
|
||||||
let param_env = tcx.param_env(parent);
|
let param_env = tcx.param_env(parent);
|
||||||
|
|
|
@ -2632,7 +2632,7 @@ impl<'hir> Ty<'hir> {
|
||||||
}
|
}
|
||||||
TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
|
TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
|
||||||
TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
|
TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
|
||||||
TyKind::OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args),
|
TyKind::OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
|
||||||
TyKind::Path(QPath::TypeRelative(ty, segment)) => {
|
TyKind::Path(QPath::TypeRelative(ty, segment)) => {
|
||||||
ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
|
ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
|
||||||
}
|
}
|
||||||
|
@ -2762,10 +2762,6 @@ pub struct OpaqueTy<'hir> {
|
||||||
/// This mapping associated a captured lifetime (first parameter) with the new
|
/// This mapping associated a captured lifetime (first parameter) with the new
|
||||||
/// early-bound lifetime that was generated for the opaque.
|
/// early-bound lifetime that was generated for the opaque.
|
||||||
pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)],
|
pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)],
|
||||||
/// Whether the opaque is a return-position impl trait (or async future)
|
|
||||||
/// originating from a trait method. This makes it so that the opaque is
|
|
||||||
/// lowered as an associated type.
|
|
||||||
pub in_trait: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
|
@ -2802,13 +2798,29 @@ pub struct PreciseCapturingNonLifetimeArg {
|
||||||
pub res: Res,
|
pub res: Res,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
|
||||||
|
pub enum RpitContext {
|
||||||
|
Trait,
|
||||||
|
TraitImpl,
|
||||||
|
}
|
||||||
|
|
||||||
/// From whence the opaque type came.
|
/// From whence the opaque type came.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
|
||||||
pub enum OpaqueTyOrigin {
|
pub enum OpaqueTyOrigin {
|
||||||
/// `-> impl Trait`
|
/// `-> impl Trait`
|
||||||
FnReturn(LocalDefId),
|
FnReturn {
|
||||||
|
/// The defining function.
|
||||||
|
parent: LocalDefId,
|
||||||
|
// Whether this is an RPITIT (return position impl trait in trait)
|
||||||
|
in_trait_or_impl: Option<RpitContext>,
|
||||||
|
},
|
||||||
/// `async fn`
|
/// `async fn`
|
||||||
AsyncFn(LocalDefId),
|
AsyncFn {
|
||||||
|
/// The defining function.
|
||||||
|
parent: LocalDefId,
|
||||||
|
// Whether this is an AFIT (async fn in trait)
|
||||||
|
in_trait_or_impl: Option<RpitContext>,
|
||||||
|
},
|
||||||
/// type aliases: `type Foo = impl Trait;`
|
/// type aliases: `type Foo = impl Trait;`
|
||||||
TyAlias {
|
TyAlias {
|
||||||
/// The type alias or associated type parent of the TAIT/ATPIT
|
/// The type alias or associated type parent of the TAIT/ATPIT
|
||||||
|
@ -2856,7 +2868,7 @@ pub enum TyKind<'hir> {
|
||||||
/// possibly parameters) that are actually bound on the `impl Trait`.
|
/// possibly parameters) that are actually bound on the `impl Trait`.
|
||||||
///
|
///
|
||||||
/// The last parameter specifies whether this opaque appears in a trait definition.
|
/// The last parameter specifies whether this opaque appears in a trait definition.
|
||||||
OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
|
OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
|
||||||
/// A trait object type `Bound1 + Bound2 + Bound3`
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
||||||
/// where `Bound` is a trait or a lifetime.
|
/// where `Bound` is a trait or a lifetime.
|
||||||
TraitObject(
|
TraitObject(
|
||||||
|
|
|
@ -894,7 +894,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
|
||||||
TyKind::Path(ref qpath) => {
|
TyKind::Path(ref qpath) => {
|
||||||
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
|
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
|
||||||
}
|
}
|
||||||
TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
|
TyKind::OpaqueDef(item_id, lifetimes) => {
|
||||||
try_visit!(visitor.visit_nested_item(item_id));
|
try_visit!(visitor.visit_nested_item(item_id));
|
||||||
walk_list!(visitor, visit_generic_arg, lifetimes);
|
walk_list!(visitor, visit_generic_arg, lifetimes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,9 +336,9 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
origin: &hir::OpaqueTyOrigin,
|
origin: &hir::OpaqueTyOrigin,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let defining_use_anchor = match *origin {
|
let defining_use_anchor = match *origin {
|
||||||
hir::OpaqueTyOrigin::FnReturn(did)
|
hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn(did)
|
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::TyAlias { parent: did, .. } => did,
|
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
|
||||||
};
|
};
|
||||||
let param_env = tcx.param_env(defining_use_anchor);
|
let param_env = tcx.param_env(defining_use_anchor);
|
||||||
|
|
||||||
|
@ -346,8 +346,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||||
|
|
||||||
let args = match *origin {
|
let args = match *origin {
|
||||||
hir::OpaqueTyOrigin::FnReturn(parent)
|
hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn(parent)
|
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
|
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
|
||||||
tcx, parent,
|
tcx, parent,
|
||||||
)
|
)
|
||||||
|
@ -409,7 +409,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
||||||
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
|
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
|
||||||
|
|
||||||
if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin {
|
if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } = origin {
|
||||||
// HACK: this should also fall through to the hidden type check below, but the original
|
// HACK: this should also fall through to the hidden type check below, but the original
|
||||||
// implementation had a bug where equivalent lifetimes are not identical. This caused us
|
// implementation had a bug where equivalent lifetimes are not identical. This caused us
|
||||||
// to reject existing stable code that is otherwise completely fine. The real fix is to
|
// to reject existing stable code that is otherwise completely fine. The real fix is to
|
||||||
|
@ -736,8 +736,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
check_opaque_precise_captures(tcx, def_id);
|
check_opaque_precise_captures(tcx, def_id);
|
||||||
|
|
||||||
let origin = tcx.opaque_type_origin(def_id);
|
let origin = tcx.opaque_type_origin(def_id);
|
||||||
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
|
if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
|
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } = origin
|
||||||
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
|
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
|
||||||
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
|
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
|
||||||
{
|
{
|
||||||
|
|
|
@ -94,8 +94,8 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
|
||||||
if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| {
|
if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| {
|
||||||
matches!(
|
matches!(
|
||||||
node.expect_item().expect_opaque_ty().origin,
|
node.expect_item().expect_opaque_ty().origin,
|
||||||
hir::OpaqueTyOrigin::AsyncFn(def_id) | hir::OpaqueTyOrigin::FnReturn(def_id)
|
hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||||
if def_id == impl_m.def_id.expect_local()
|
if parent == impl_m.def_id.expect_local()
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
report_mismatched_rpitit_signature(
|
report_mismatched_rpitit_signature(
|
||||||
|
|
|
@ -210,11 +210,11 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
Node::Item(item) => match item.kind {
|
Node::Item(item) => match item.kind {
|
||||||
ItemKind::OpaqueTy(&hir::OpaqueTy {
|
ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||||
origin:
|
origin:
|
||||||
hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
|
||||||
in_trait,
|
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if in_trait {
|
if in_trait_or_impl.is_some() {
|
||||||
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
|
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
|
||||||
} else {
|
} else {
|
||||||
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
|
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
|
||||||
|
|
|
@ -370,39 +370,47 @@ pub(super) fn explicit_item_bounds_with_filter(
|
||||||
..
|
..
|
||||||
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
|
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
|
||||||
hir::Node::Item(hir::Item {
|
hir::Node::Item(hir::Item {
|
||||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }),
|
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, origin, .. }),
|
||||||
span,
|
span,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => match origin {
|
||||||
let args = GenericArgs::identity_for_item(tcx, def_id);
|
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`,
|
||||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
// when we're asking for the item bounds of the *opaques* in a trait's default
|
||||||
let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter);
|
// method signature, we need to map these projections back to opaques.
|
||||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
rustc_hir::OpaqueTyOrigin::FnReturn {
|
||||||
bounds
|
parent,
|
||||||
}
|
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||||
// 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
|
| rustc_hir::OpaqueTyOrigin::AsyncFn {
|
||||||
// need to map these projections back to opaques.
|
parent,
|
||||||
hir::Node::Item(hir::Item {
|
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }),
|
} => {
|
||||||
span,
|
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||||
..
|
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||||
}) => {
|
let bounds = &*tcx.arena.alloc_slice(
|
||||||
let (hir::OpaqueTyOrigin::FnReturn(fn_def_id)
|
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
||||||
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin
|
.to_vec()
|
||||||
else {
|
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: parent.to_def_id() }),
|
||||||
span_bug!(*span, "RPITIT cannot be a TAIT, but got origin {origin:?}");
|
);
|
||||||
};
|
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||||
let args = GenericArgs::identity_for_item(tcx, def_id);
|
bounds
|
||||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
}
|
||||||
let bounds = &*tcx.arena.alloc_slice(
|
rustc_hir::OpaqueTyOrigin::FnReturn {
|
||||||
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
parent: _,
|
||||||
.to_vec()
|
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
|
||||||
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }),
|
}
|
||||||
);
|
| rustc_hir::OpaqueTyOrigin::AsyncFn {
|
||||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
parent: _,
|
||||||
bounds
|
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
|
||||||
}
|
}
|
||||||
|
| rustc_hir::OpaqueTyOrigin::TyAlias { parent: _, .. } => {
|
||||||
|
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||||
|
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||||
|
let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter);
|
||||||
|
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||||
|
bounds
|
||||||
|
}
|
||||||
|
},
|
||||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
||||||
_ => bug!("item_bounds called on {:?}", def_id),
|
_ => bug!("item_bounds called on {:?}", def_id),
|
||||||
};
|
};
|
||||||
|
|
|
@ -332,7 +332,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
// and the duplicated parameter, to ensure that they do not get out of sync.
|
// 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::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
|
||||||
let opaque_ty_node = tcx.parent_hir_node(hir_id);
|
let opaque_ty_node = tcx.parent_hir_node(hir_id);
|
||||||
let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node
|
let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes), .. }) = opaque_ty_node
|
||||||
else {
|
else {
|
||||||
bug!("unexpected {opaque_ty_node:?}")
|
bug!("unexpected {opaque_ty_node:?}")
|
||||||
};
|
};
|
||||||
|
|
|
@ -515,8 +515,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||||
origin:
|
origin:
|
||||||
hir::OpaqueTyOrigin::FnReturn(parent)
|
hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn(parent)
|
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. },
|
| hir::OpaqueTyOrigin::TyAlias { parent, .. },
|
||||||
generics,
|
generics,
|
||||||
..
|
..
|
||||||
|
@ -689,7 +689,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
self.with(scope, |this| this.visit_ty(mt.ty));
|
self.with(scope, |this| this.visit_ty(mt.ty));
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
|
hir::TyKind::OpaqueDef(item_id, lifetimes) => {
|
||||||
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
||||||
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
||||||
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
|
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
|
||||||
|
|
|
@ -618,11 +618,13 @@ pub(super) fn type_of_opaque(
|
||||||
// Opaque types desugared from `impl Trait`.
|
// Opaque types desugared from `impl Trait`.
|
||||||
ItemKind::OpaqueTy(&OpaqueTy {
|
ItemKind::OpaqueTy(&OpaqueTy {
|
||||||
origin:
|
origin:
|
||||||
hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
|
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
|
||||||
in_trait,
|
| hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl },
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if in_trait && !tcx.defaultness(owner).has_value() {
|
if in_trait_or_impl == Some(hir::RpitContext::Trait)
|
||||||
|
&& !tcx.defaultness(owner).has_value()
|
||||||
|
{
|
||||||
span_bug!(
|
span_bug!(
|
||||||
tcx.def_span(def_id),
|
tcx.def_span(def_id),
|
||||||
"tried to get type of this RPITIT with no definition"
|
"tried to get type of this RPITIT with no definition"
|
||||||
|
|
|
@ -2087,21 +2087,41 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
|
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)
|
self.lower_path(opt_self_ty, path, hir_ty.hir_id, false)
|
||||||
}
|
}
|
||||||
&hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
|
&hir::TyKind::OpaqueDef(item_id, lifetimes) => {
|
||||||
let opaque_ty = tcx.hir().item(item_id);
|
let opaque_ty = tcx.hir().item(item_id);
|
||||||
|
|
||||||
match opaque_ty.kind {
|
match opaque_ty.kind {
|
||||||
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { .. }) => {
|
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
|
||||||
let local_def_id = item_id.owner_id.def_id;
|
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
|
// 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
|
// generate the def_id of an associated type for the trait and return as
|
||||||
// type a projection.
|
// type a projection.
|
||||||
let def_id = if in_trait {
|
match origin {
|
||||||
tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id()
|
hir::OpaqueTyOrigin::FnReturn {
|
||||||
} else {
|
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||||
local_def_id.to_def_id()
|
..
|
||||||
};
|
}
|
||||||
self.lower_opaque_ty(def_id, lifetimes, in_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),
|
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
||||||
}
|
}
|
||||||
|
|
|
@ -602,7 +602,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.map(|(k, _)| (k.def_id, k.args))?,
|
.map(|(k, _)| (k.def_id, k.args))?,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = self.tcx.opaque_type_origin(def_id)
|
let hir::OpaqueTyOrigin::FnReturn { parent: parent_def_id, .. } =
|
||||||
|
self.tcx.opaque_type_origin(def_id)
|
||||||
else {
|
else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,8 +18,8 @@ use rustc_middle::ty::{
|
||||||
self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt,
|
self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt,
|
||||||
};
|
};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::Span;
|
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
|
use rustc_span::{ErrorGuaranteed, Span};
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::{self, NormalizeExt};
|
use rustc_trait_selection::traits::{self, NormalizeExt};
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
@ -46,17 +46,17 @@ pub(crate) struct MethodCallee<'tcx> {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum MethodError<'tcx> {
|
pub(crate) enum MethodError<'tcx> {
|
||||||
// Did not find an applicable method, but we did find various near-misses that may work.
|
/// Did not find an applicable method, but we did find various near-misses that may work.
|
||||||
NoMatch(NoMatchData<'tcx>),
|
NoMatch(NoMatchData<'tcx>),
|
||||||
|
|
||||||
// Multiple methods might apply.
|
/// Multiple methods might apply.
|
||||||
Ambiguity(Vec<CandidateSource>),
|
Ambiguity(Vec<CandidateSource>),
|
||||||
|
|
||||||
// Found an applicable method, but it is not visible. The third argument contains a list of
|
/// Found an applicable method, but it is not visible. The third argument contains a list of
|
||||||
// not-in-scope traits which may work.
|
/// not-in-scope traits which may work.
|
||||||
PrivateMatch(DefKind, DefId, Vec<DefId>),
|
PrivateMatch(DefKind, DefId, Vec<DefId>),
|
||||||
|
|
||||||
// Found a `Self: Sized` bound where `Self` is a trait object.
|
/// Found a `Self: Sized` bound where `Self` is a trait object.
|
||||||
IllegalSizedBound {
|
IllegalSizedBound {
|
||||||
candidates: Vec<DefId>,
|
candidates: Vec<DefId>,
|
||||||
needs_mut: bool,
|
needs_mut: bool,
|
||||||
|
@ -64,8 +64,11 @@ pub(crate) enum MethodError<'tcx> {
|
||||||
self_expr: &'tcx hir::Expr<'tcx>,
|
self_expr: &'tcx hir::Expr<'tcx>,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Found a match, but the return type is wrong
|
/// Found a match, but the return type is wrong
|
||||||
BadReturnType,
|
BadReturnType,
|
||||||
|
|
||||||
|
/// Error has already been emitted, no need to emit another one.
|
||||||
|
ErrorReported(ErrorGuaranteed),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contains a list of static methods that may apply, a list of unsatisfied trait predicates which
|
// Contains a list of static methods that may apply, a list of unsatisfied trait predicates which
|
||||||
|
@ -120,6 +123,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
Err(PrivateMatch(..)) => false,
|
Err(PrivateMatch(..)) => false,
|
||||||
Err(IllegalSizedBound { .. }) => true,
|
Err(IllegalSizedBound { .. }) => true,
|
||||||
Err(BadReturnType) => false,
|
Err(BadReturnType) => false,
|
||||||
|
Err(ErrorReported(_)) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -446,13 +446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
_ => bug!("unexpected bad final type in method autoderef"),
|
_ => bug!("unexpected bad final type in method autoderef"),
|
||||||
};
|
};
|
||||||
self.demand_eqtype(span, ty, Ty::new_error(self.tcx, guar));
|
self.demand_eqtype(span, ty, Ty::new_error(self.tcx, guar));
|
||||||
return Err(MethodError::NoMatch(NoMatchData {
|
return Err(MethodError::ErrorReported(guar));
|
||||||
static_candidates: Vec::new(),
|
|
||||||
unsatisfied_predicates: Vec::new(),
|
|
||||||
out_of_scope_traits: Vec::new(),
|
|
||||||
similar_candidate: None,
|
|
||||||
mode,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,20 +229,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match error {
|
match error {
|
||||||
MethodError::NoMatch(mut no_match_data) => {
|
MethodError::NoMatch(mut no_match_data) => self.report_no_match_method_error(
|
||||||
return self.report_no_match_method_error(
|
span,
|
||||||
span,
|
rcvr_ty,
|
||||||
rcvr_ty,
|
item_name,
|
||||||
item_name,
|
call_id,
|
||||||
call_id,
|
source,
|
||||||
source,
|
args,
|
||||||
args,
|
sugg_span,
|
||||||
sugg_span,
|
&mut no_match_data,
|
||||||
&mut no_match_data,
|
expected,
|
||||||
expected,
|
trait_missing_method,
|
||||||
trait_missing_method,
|
),
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodError::Ambiguity(mut sources) => {
|
MethodError::Ambiguity(mut sources) => {
|
||||||
let mut err = struct_span_code_err!(
|
let mut err = struct_span_code_err!(
|
||||||
|
@ -263,7 +261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&mut sources,
|
&mut sources,
|
||||||
Some(sugg_span),
|
Some(sugg_span),
|
||||||
);
|
);
|
||||||
return err.emit();
|
err.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
|
MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
|
||||||
|
@ -284,7 +282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.unwrap_or_else(|| self.tcx.def_span(def_id));
|
.unwrap_or_else(|| self.tcx.def_span(def_id));
|
||||||
err.span_label(sp, format!("private {kind} defined here"));
|
err.span_label(sp, format!("private {kind} defined here"));
|
||||||
self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true);
|
self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true);
|
||||||
return err.emit();
|
err.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
|
MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
|
||||||
|
@ -383,9 +381,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err.emit();
|
err.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MethodError::ErrorReported(guar) => guar,
|
||||||
|
|
||||||
MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
|
MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,8 +259,8 @@ where
|
||||||
// If it's owned by this function
|
// If it's owned by this function
|
||||||
&& let opaque =
|
&& 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_item().expect_opaque_ty()
|
||||||
&& let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin
|
&& let hir::OpaqueTyOrigin::FnReturn { parent, .. } = opaque.origin
|
||||||
&& parent_def_id == self.parent_def_id
|
&& parent == self.parent_def_id
|
||||||
{
|
{
|
||||||
let opaque_span = self.tcx.def_span(opaque_def_id);
|
let opaque_span = self.tcx.def_span(opaque_def_id);
|
||||||
let new_capture_rules =
|
let new_capture_rules =
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||||
// That's because although we may have an opaque type on the function,
|
// That's because although we may have an opaque type on the function,
|
||||||
// it won't have a hidden type, so proving predicates about it is
|
// it won't have a hidden type, so proving predicates about it is
|
||||||
// not really meaningful.
|
// not really meaningful.
|
||||||
if let hir::OpaqueTyOrigin::FnReturn(method_def_id) = opaque.origin
|
if let hir::OpaqueTyOrigin::FnReturn { parent: method_def_id, .. } = opaque.origin
|
||||||
&& let hir::Node::TraitItem(trait_item) = cx.tcx.hir_node_by_def_id(method_def_id)
|
&& let hir::Node::TraitItem(trait_item) = cx.tcx.hir_node_by_def_id(method_def_id)
|
||||||
&& !trait_item.defaultness.has_value()
|
&& !trait_item.defaultness.has_value()
|
||||||
{
|
{
|
||||||
|
@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||||
&& cx.tcx.parent(opaque_ty.def_id) == def_id
|
&& cx.tcx.parent(opaque_ty.def_id) == def_id
|
||||||
&& matches!(
|
&& matches!(
|
||||||
opaque.origin,
|
opaque.origin,
|
||||||
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_)
|
hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. }
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -114,8 +114,10 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||||
// return type is well-formed in traits even when `Self` isn't sized.
|
// return type is well-formed in traits even when `Self` isn't sized.
|
||||||
if let ty::Param(param_ty) = *proj_term.kind()
|
if let ty::Param(param_ty) = *proj_term.kind()
|
||||||
&& param_ty.name == kw::SelfUpper
|
&& param_ty.name == kw::SelfUpper
|
||||||
&& matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(_))
|
&& matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn {
|
||||||
&& opaque.in_trait
|
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||||
|
..
|
||||||
|
})
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1186,9 +1186,9 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
|
||||||
|
|
||||||
DefKind::OpaqueTy => {
|
DefKind::OpaqueTy => {
|
||||||
let origin = tcx.opaque_type_origin(def_id);
|
let origin = tcx.opaque_type_origin(def_id);
|
||||||
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
|
if let hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
|
| hir::OpaqueTyOrigin::AsyncFn { parent, .. } = origin
|
||||||
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
|
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(parent)
|
||||||
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
|
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
|
||||||
{
|
{
|
||||||
false
|
false
|
||||||
|
|
|
@ -1139,13 +1139,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
||||||
ItemKind::ForeignMod { .. } => "foreign mod",
|
ItemKind::ForeignMod { .. } => "foreign mod",
|
||||||
ItemKind::GlobalAsm(..) => "global asm",
|
ItemKind::GlobalAsm(..) => "global asm",
|
||||||
ItemKind::TyAlias(..) => "ty",
|
ItemKind::TyAlias(..) => "ty",
|
||||||
ItemKind::OpaqueTy(opaque) => {
|
ItemKind::OpaqueTy(..) => "opaque type",
|
||||||
if opaque.in_trait {
|
|
||||||
"opaque type in trait"
|
|
||||||
} else {
|
|
||||||
"opaque type"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ItemKind::Enum(..) => "enum",
|
ItemKind::Enum(..) => "enum",
|
||||||
ItemKind::Struct(..) => "struct",
|
ItemKind::Struct(..) => "struct",
|
||||||
ItemKind::Union(..) => "union",
|
ItemKind::Union(..) => "union",
|
||||||
|
|
|
@ -510,7 +510,7 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
|
||||||
) => {
|
) => {
|
||||||
self.0.push(ty);
|
self.0.push(ty);
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(item_id, _, _) => {
|
hir::TyKind::OpaqueDef(item_id, _) => {
|
||||||
self.0.push(ty);
|
self.0.push(ty);
|
||||||
let item = self.1.item(item_id);
|
let item = self.1.item(item_id);
|
||||||
hir::intravisit::walk_item(self, item);
|
hir::intravisit::walk_item(self, item);
|
||||||
|
|
|
@ -63,7 +63,8 @@ fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
||||||
Some([item]) if item.has_name(sym::on) => return true,
|
Some([item]) if item.has_name(sym::on) => return true,
|
||||||
Some(_) | None => {
|
Some(_) | None => {
|
||||||
// Other possibilities should have been rejected by `rustc_parse::validate_attr`.
|
// Other possibilities should have been rejected by `rustc_parse::validate_attr`.
|
||||||
tcx.dcx().span_bug(attr.span, "unexpected value of coverage attribute");
|
// Use `span_delayed_bug` to avoid an ICE in failing builds (#127880).
|
||||||
|
tcx.dcx().span_delayed_bug(attr.span, "unexpected value of coverage attribute");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -656,7 +656,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
if let TyKind::OpaqueDef(item_id, _, _) = ty.kind {
|
if let TyKind::OpaqueDef(item_id, _) = ty.kind {
|
||||||
let item = self.tcx.hir().item(item_id);
|
let item = self.tcx.hir().item(item_id);
|
||||||
intravisit::walk_item(self, item);
|
intravisit::walk_item(self, item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -637,17 +637,44 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||||
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||||
if self.impl_trait_pass
|
if self.impl_trait_pass
|
||||||
&& let hir::ItemKind::OpaqueTy(opaque) = item.kind
|
&& let hir::ItemKind::OpaqueTy(opaque) = item.kind
|
||||||
&& !opaque.in_trait
|
|
||||||
{
|
{
|
||||||
// FIXME: This is some serious pessimization intended to workaround deficiencies
|
let should_visit = match opaque.origin {
|
||||||
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
|
hir::OpaqueTyOrigin::FnReturn {
|
||||||
// reachable if they are returned via `impl Trait`, even from private functions.
|
parent,
|
||||||
let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public);
|
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||||
self.reach_through_impl_trait(item.owner_id.def_id, pub_ev)
|
}
|
||||||
.generics()
|
| hir::OpaqueTyOrigin::AsyncFn {
|
||||||
.predicates()
|
parent,
|
||||||
.ty();
|
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||||
return;
|
} => 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
|
// Update levels of nested things and mark all items
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![allow(rustc::potential_query_instability, unused_parens)]
|
#![allow(unused_parens)]
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![doc(rust_logo)]
|
#![doc(rust_logo)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
|
|
|
@ -284,7 +284,7 @@ pub fn suggest_new_region_bound(
|
||||||
}
|
}
|
||||||
match fn_return.kind {
|
match fn_return.kind {
|
||||||
// FIXME(precise_captures): Suggest adding to `use<...>` list instead.
|
// FIXME(precise_captures): Suggest adding to `use<...>` list instead.
|
||||||
TyKind::OpaqueDef(item_id, _, _) => {
|
TyKind::OpaqueDef(item_id, _) => {
|
||||||
let item = tcx.hir().item(item_id);
|
let item = tcx.hir().item(item_id);
|
||||||
let ItemKind::OpaqueTy(opaque) = &item.kind else {
|
let ItemKind::OpaqueTy(opaque) = &item.kind else {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -857,7 +857,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) {
|
fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) {
|
||||||
let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind else {
|
let hir::TyKind::OpaqueDef(item_id, _) = ty.kind else {
|
||||||
return hir::intravisit::walk_ty(self, ty);
|
return hir::intravisit::walk_ty(self, ty);
|
||||||
};
|
};
|
||||||
let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty();
|
let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty();
|
||||||
|
@ -1271,7 +1271,7 @@ fn suggest_precise_capturing<'tcx>(
|
||||||
let hir::OpaqueTy { bounds, origin, .. } =
|
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_item().expect_opaque_ty();
|
||||||
|
|
||||||
let hir::OpaqueTyOrigin::FnReturn(fn_def_id) = *origin else {
|
let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } = *origin else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
span, "silent safe transmute error"
|
span, "silent safe transmute error"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
GetSafeTransmuteErrorAndReason::Default => {
|
||||||
|
(err_msg, None)
|
||||||
|
}
|
||||||
GetSafeTransmuteErrorAndReason::Error {
|
GetSafeTransmuteErrorAndReason::Error {
|
||||||
err_msg,
|
err_msg,
|
||||||
safe_transmute_explanation,
|
safe_transmute_explanation,
|
||||||
|
@ -2226,6 +2229,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
) -> GetSafeTransmuteErrorAndReason {
|
) -> GetSafeTransmuteErrorAndReason {
|
||||||
use rustc_transmute::Answer;
|
use rustc_transmute::Answer;
|
||||||
|
|
||||||
|
// We don't assemble a transmutability candidate for types that are generic
|
||||||
|
// and we should have ambiguity for types that still have non-region infer.
|
||||||
|
if obligation.predicate.has_non_region_param() || obligation.has_non_region_infer() {
|
||||||
|
return GetSafeTransmuteErrorAndReason::Default;
|
||||||
|
}
|
||||||
|
|
||||||
// Erase regions because layout code doesn't particularly care about regions.
|
// Erase regions because layout code doesn't particularly care about regions.
|
||||||
let trait_ref =
|
let trait_ref =
|
||||||
self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref));
|
self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref));
|
||||||
|
@ -2248,6 +2257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let dst = trait_ref.args.type_at(0);
|
let dst = trait_ref.args.type_at(0);
|
||||||
let src = trait_ref.args.type_at(1);
|
let src = trait_ref.args.type_at(1);
|
||||||
|
|
||||||
let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`");
|
let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`");
|
||||||
|
|
||||||
match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
|
match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
|
||||||
|
@ -2630,7 +2640,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
let name = match self.tcx.opaque_type_origin(def_id.expect_local()) {
|
let name = match self.tcx.opaque_type_origin(def_id.expect_local()) {
|
||||||
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
|
hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } => {
|
||||||
"opaque type".to_string()
|
"opaque type".to_string()
|
||||||
}
|
}
|
||||||
hir::OpaqueTyOrigin::TyAlias { .. } => {
|
hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||||
|
|
|
@ -43,6 +43,7 @@ pub struct ImplCandidate<'tcx> {
|
||||||
|
|
||||||
enum GetSafeTransmuteErrorAndReason {
|
enum GetSafeTransmuteErrorAndReason {
|
||||||
Silent,
|
Silent,
|
||||||
|
Default,
|
||||||
Error { err_msg: String, safe_transmute_explanation: Option<String> },
|
Error { err_msg: String, safe_transmute_explanation: Option<String> },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,10 +195,11 @@ pub(crate) mod rustc {
|
||||||
impl<'tcx> From<&LayoutError<'tcx>> for Err {
|
impl<'tcx> From<&LayoutError<'tcx>> for Err {
|
||||||
fn from(err: &LayoutError<'tcx>) -> Self {
|
fn from(err: &LayoutError<'tcx>) -> Self {
|
||||||
match err {
|
match err {
|
||||||
LayoutError::Unknown(..) | LayoutError::ReferencesError(..) => Self::UnknownLayout,
|
LayoutError::Unknown(..)
|
||||||
|
| LayoutError::ReferencesError(..)
|
||||||
|
| LayoutError::NormalizationFailure(..) => Self::UnknownLayout,
|
||||||
LayoutError::SizeOverflow(..) => Self::SizeOverflow,
|
LayoutError::SizeOverflow(..) => Self::SizeOverflow,
|
||||||
LayoutError::Cycle(err) => Self::TypeError(*err),
|
LayoutError::Cycle(err) => Self::TypeError(*err),
|
||||||
err => unimplemented!("{:?}", err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,7 +323,7 @@ fn associated_types_for_impl_traits_in_associated_fn(
|
||||||
|
|
||||||
impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
|
impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
|
||||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind
|
if let hir::TyKind::OpaqueDef(item_id, _) = ty.kind
|
||||||
&& self.rpits.insert(item_id.owner_id.def_id)
|
&& self.rpits.insert(item_id.owner_id.def_id)
|
||||||
{
|
{
|
||||||
let opaque_item =
|
let opaque_item =
|
||||||
|
@ -379,7 +379,8 @@ fn associated_type_for_impl_trait_in_trait(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
opaque_ty_def_id: LocalDefId,
|
opaque_ty_def_id: LocalDefId,
|
||||||
) -> LocalDefId {
|
) -> LocalDefId {
|
||||||
let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) =
|
let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
|
||||||
|
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. }) =
|
||||||
tcx.opaque_type_origin(opaque_ty_def_id)
|
tcx.opaque_type_origin(opaque_ty_def_id)
|
||||||
else {
|
else {
|
||||||
bug!("expected opaque for {opaque_ty_def_id:?}");
|
bug!("expected opaque for {opaque_ty_def_id:?}");
|
||||||
|
|
|
@ -141,7 +141,8 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
|
||||||
let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local());
|
let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local());
|
||||||
trace!(?origin);
|
trace!(?origin);
|
||||||
match origin {
|
match origin {
|
||||||
rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
|
rustc_hir::OpaqueTyOrigin::FnReturn { .. }
|
||||||
|
| rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
|
||||||
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
|
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
|
||||||
if !in_assoc_ty && !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
|
if !in_assoc_ty && !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -374,7 +374,10 @@ impl<'a, T: Ord, A: Allocator> PeekMut<'a, T, A> {
|
||||||
// the caller could've mutated the element. It is removed from the
|
// the caller could've mutated the element. It is removed from the
|
||||||
// heap on the next line and pop() is not sensitive to its value.
|
// heap on the next line and pop() is not sensitive to its value.
|
||||||
}
|
}
|
||||||
this.heap.pop().unwrap()
|
|
||||||
|
// SAFETY: Have a `PeekMut` element proves that the associated binary heap being non-empty,
|
||||||
|
// so the `pop` operation will not fail.
|
||||||
|
unsafe { this.heap.pop().unwrap_unchecked() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1828,7 +1828,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
||||||
Array(Box::new(clean_ty(ty, cx)), length.into())
|
Array(Box::new(clean_ty(ty, cx)), length.into())
|
||||||
}
|
}
|
||||||
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
|
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
|
||||||
TyKind::OpaqueDef(item_id, _, _) => {
|
TyKind::OpaqueDef(item_id, _) => {
|
||||||
let item = cx.tcx.hir().item(item_id);
|
let item = cx.tcx.hir().item(item_id);
|
||||||
if let hir::ItemKind::OpaqueTy(ty) = item.kind {
|
if let hir::ItemKind::OpaqueTy(ty) = item.kind {
|
||||||
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
|
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
|
||||||
|
|
|
@ -515,7 +515,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
self.add_to_current_mod(item, renamed, import_id);
|
self.add_to_current_mod(item, renamed, import_id);
|
||||||
}
|
}
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn(_) | hir::OpaqueTyOrigin::FnReturn(_),
|
origin: hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::FnReturn { .. },
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
// return-position impl traits are never nameable, and should never be documented.
|
// return-position impl traits are never nameable, and should never be documented.
|
||||||
|
|
|
@ -199,7 +199,7 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
|
||||||
fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
|
fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
|
||||||
if let Some((def_id, _)) = t.peel_refs().as_generic_param() {
|
if let Some((def_id, _)) = t.peel_refs().as_generic_param() {
|
||||||
self.ty_params.remove(&def_id);
|
self.ty_params.remove(&def_id);
|
||||||
} else if let TyKind::OpaqueDef(id, _, _) = t.kind {
|
} else if let TyKind::OpaqueDef(id, _) = t.kind {
|
||||||
// Explicitly walk OpaqueDef. Normally `walk_ty` would do the job, but it calls
|
// 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
|
// `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.
|
// using `OnlyBodies`, so the check ends up failing and the type isn't fully walked.
|
||||||
|
|
|
@ -313,7 +313,7 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
|
||||||
kind: ItemKind::OpaqueTy(opaque),
|
kind: ItemKind::OpaqueTy(opaque),
|
||||||
..
|
..
|
||||||
} = item
|
} = item
|
||||||
&& let OpaqueTyOrigin::AsyncFn(_) = opaque.origin
|
&& let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
|
||||||
&& let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
|
&& let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
|
||||||
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
&& let Some(generic_args) = segment.args
|
&& let Some(generic_args) = segment.args
|
||||||
|
|
|
@ -420,7 +420,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
|
fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
TyKind::OpaqueDef(item, bounds, _) => {
|
TyKind::OpaqueDef(item, bounds) => {
|
||||||
let map = self.cx.tcx.hir();
|
let map = self.cx.tcx.hir();
|
||||||
let item = map.item(item);
|
let item = map.item(item);
|
||||||
let len = self.lts.len();
|
let len = self.lts.len();
|
||||||
|
|
|
@ -105,7 +105,7 @@ fn future_trait_ref<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
ty: &'tcx Ty<'tcx>,
|
ty: &'tcx Ty<'tcx>,
|
||||||
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
|
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
|
||||||
if let TyKind::OpaqueDef(item_id, bounds, false) = ty.kind
|
if let TyKind::OpaqueDef(item_id, bounds) = ty.kind
|
||||||
&& let item = cx.tcx.hir().item(item_id)
|
&& let item = cx.tcx.hir().item(item_id)
|
||||||
&& let ItemKind::OpaqueTy(opaque) = &item.kind
|
&& let ItemKind::OpaqueTy(opaque) = &item.kind
|
||||||
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
|
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
|
||||||
|
|
|
@ -1126,9 +1126,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TyKind::Path(ref qpath) => self.hash_qpath(qpath),
|
TyKind::Path(ref qpath) => self.hash_qpath(qpath),
|
||||||
TyKind::OpaqueDef(_, arg_list, in_trait) => {
|
TyKind::OpaqueDef(_, arg_list) => {
|
||||||
self.hash_generic_args(arg_list);
|
self.hash_generic_args(arg_list);
|
||||||
in_trait.hash(&mut self.s);
|
|
||||||
},
|
},
|
||||||
TyKind::TraitObject(_, lifetime, _) => {
|
TyKind::TraitObject(_, lifetime, _) => {
|
||||||
self.hash_lifetime(lifetime);
|
self.hash_lifetime(lifetime);
|
||||||
|
|
13
tests/codegen/binary-heap-peek-mut-pop-no-panic.rs
Normal file
13
tests/codegen/binary-heap-peek-mut-pop-no-panic.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//@ compile-flags: -O
|
||||||
|
//@ ignore-debug
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
use std::collections::binary_heap::PeekMut;
|
||||||
|
|
||||||
|
// CHECK-LABEL: @peek_mut_pop
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn peek_mut_pop(peek_mut: PeekMut<u32>) -> u32 {
|
||||||
|
// CHECK-NOT: panic
|
||||||
|
// CHECK-NOT: unwrap_failed
|
||||||
|
PeekMut::pop(peek_mut)
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
//@ known-bug: rust-lang/rust#125881
|
|
||||||
#![crate_type = "lib"]
|
|
||||||
#![feature(transmutability)]
|
|
||||||
#![feature(unboxed_closures,effects)]
|
|
||||||
|
|
||||||
const fn test() -> impl std::mem::TransmuteFrom() {
|
|
||||||
|| {}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
//@ known-bug: rust-lang/rust#126377
|
|
||||||
|
|
||||||
#![feature(effects)]
|
|
||||||
#![feature(generic_const_exprs)]
|
|
||||||
|
|
||||||
mod assert {
|
|
||||||
use std::mem::{Assume, TransmuteFrom};
|
|
||||||
|
|
||||||
pub fn is_transmutable<
|
|
||||||
Src,
|
|
||||||
Dst,
|
|
||||||
const ASSUME_ALIGNMENT: bool,
|
|
||||||
const ASSUME_LIFETIMES: bool,
|
|
||||||
const ASSUME_SAFETY: bool,
|
|
||||||
const ASSUME_VALIDITY: bool,
|
|
||||||
>()
|
|
||||||
where
|
|
||||||
Dst: TransmuteFrom<
|
|
||||||
Src,
|
|
||||||
{ }
|
|
||||||
>,
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
|
|
||||||
const fn from_options() -> Assume {
|
|
||||||
#[repr(C)] struct Src;
|
|
||||||
#[repr(C)] struct Dst;
|
|
||||||
assert::is_transmutable::<Src, Dst, {0u8}, false, false, false>();
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
//@ known-bug: #127880
|
|
||||||
//@ compile-flags: -Cinstrument-coverage
|
|
||||||
|
|
||||||
#[coverage]
|
|
||||||
fn main() {}
|
|
|
@ -1,17 +0,0 @@
|
||||||
//@ known-bug: #130413
|
|
||||||
|
|
||||||
#![feature(transmutability)]
|
|
||||||
trait Aaa {
|
|
||||||
type Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
trait Bbb {
|
|
||||||
type B: std::mem::TransmuteFrom<()>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Bbb for T
|
|
||||||
where
|
|
||||||
T: Aaa,
|
|
||||||
{
|
|
||||||
type B = T::Y;
|
|
||||||
}
|
|
15
tests/ui/coverage-attr/bad-attr-ice.feat.stderr
Normal file
15
tests/ui/coverage-attr/bad-attr-ice.feat.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error: malformed `coverage` attribute input
|
||||||
|
--> $DIR/bad-attr-ice.rs:10:1
|
||||||
|
|
|
||||||
|
LL | #[coverage]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: the following are the possible correct uses
|
||||||
|
|
|
||||||
|
LL | #[coverage(off)]
|
||||||
|
|
|
||||||
|
LL | #[coverage(on)]
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
26
tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr
Normal file
26
tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
error: malformed `coverage` attribute input
|
||||||
|
--> $DIR/bad-attr-ice.rs:10:1
|
||||||
|
|
|
||||||
|
LL | #[coverage]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: the following are the possible correct uses
|
||||||
|
|
|
||||||
|
LL | #[coverage(off)]
|
||||||
|
|
|
||||||
|
LL | #[coverage(on)]
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0658]: the `#[coverage]` attribute is an experimental feature
|
||||||
|
--> $DIR/bad-attr-ice.rs:10:1
|
||||||
|
|
|
||||||
|
LL | #[coverage]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #84605 <https://github.com/rust-lang/rust/issues/84605> for more information
|
||||||
|
= help: add `#![feature(coverage_attribute)]` 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 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
16
tests/ui/coverage-attr/bad-attr-ice.rs
Normal file
16
tests/ui/coverage-attr/bad-attr-ice.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#![cfg_attr(feat, feature(coverage_attribute))]
|
||||||
|
//@ revisions: feat nofeat
|
||||||
|
//@ compile-flags: -Cinstrument-coverage
|
||||||
|
//@ needs-profiler-support
|
||||||
|
|
||||||
|
// Malformed `#[coverage(..)]` attributes should not cause an ICE when built
|
||||||
|
// with `-Cinstrument-coverage`.
|
||||||
|
// Regression test for <https://github.com/rust-lang/rust/issues/127880>.
|
||||||
|
|
||||||
|
#[coverage]
|
||||||
|
//~^ ERROR malformed `coverage` attribute input
|
||||||
|
//[nofeat]~| the `#[coverage]` attribute is an experimental feature
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
// FIXME(#130766): When the `#[coverage(..)]` attribute is stabilized,
|
||||||
|
// get rid of the revisions and just make this a normal test.
|
13
tests/ui/methods/dont-suggest-import-on-deref-err.rs
Normal file
13
tests/ui/methods/dont-suggest-import-on-deref-err.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
use std::clone::Clone;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Foo {}
|
||||||
|
|
||||||
|
impl Deref for Foo {}
|
||||||
|
//~^ ERROR not all trait items implemented
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let f = Foo {};
|
||||||
|
let _ = f.clone();
|
||||||
|
}
|
12
tests/ui/methods/dont-suggest-import-on-deref-err.stderr
Normal file
12
tests/ui/methods/dont-suggest-import-on-deref-err.stderr
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0046]: not all trait items implemented, missing: `Target`, `deref`
|
||||||
|
--> $DIR/dont-suggest-import-on-deref-err.rs:7:1
|
||||||
|
|
|
||||||
|
LL | impl Deref for Foo {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ missing `Target`, `deref` in implementation
|
||||||
|
|
|
||||||
|
= help: implement the missing item: `type Target = /* Type */;`
|
||||||
|
= help: implement the missing item: `fn deref(&self) -> &<Self as Deref>::Target { todo!() }`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0046`.
|
25
tests/ui/transmutability/assoc-bound.rs
Normal file
25
tests/ui/transmutability/assoc-bound.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(transmutability)]
|
||||||
|
|
||||||
|
trait A {
|
||||||
|
type AssocA;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait B {
|
||||||
|
type AssocB: std::mem::TransmuteFrom<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> B for (T, u8)
|
||||||
|
where
|
||||||
|
T: A,
|
||||||
|
{
|
||||||
|
type AssocB = T::AssocA; //~ERROR: the trait bound `<T as A>::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not satisfied [E0277]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<T> B for (T, u16)
|
||||||
|
where
|
||||||
|
for<'a> &'a i32: A,
|
||||||
|
{
|
||||||
|
type AssocB = <&'static i32 as A>::AssocA; //~ERROR: `()` cannot be safely transmuted into `<&i32 as A>::AssocA`
|
||||||
|
}
|
31
tests/ui/transmutability/assoc-bound.stderr
Normal file
31
tests/ui/transmutability/assoc-bound.stderr
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
error[E0277]: the trait bound `<T as A>::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not satisfied
|
||||||
|
--> $DIR/assoc-bound.rs:16:19
|
||||||
|
|
|
||||||
|
LL | type AssocB = T::AssocA;
|
||||||
|
| ^^^^^^^^^ the trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `<T as A>::AssocA`
|
||||||
|
|
|
||||||
|
note: required by a bound in `B::AssocB`
|
||||||
|
--> $DIR/assoc-bound.rs:9:18
|
||||||
|
|
|
||||||
|
LL | type AssocB: std::mem::TransmuteFrom<()>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `B::AssocB`
|
||||||
|
help: consider further restricting the associated type
|
||||||
|
|
|
||||||
|
LL | T: A, <T as A>::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error[E0277]: `()` cannot be safely transmuted into `<&i32 as A>::AssocA`
|
||||||
|
--> $DIR/assoc-bound.rs:24:19
|
||||||
|
|
|
||||||
|
LL | type AssocB = <&'static i32 as A>::AssocA;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<&i32 as A>::AssocA` has an unknown layout
|
||||||
|
|
|
||||||
|
note: required by a bound in `B::AssocB`
|
||||||
|
--> $DIR/assoc-bound.rs:9:18
|
||||||
|
|
|
||||||
|
LL | type AssocB: std::mem::TransmuteFrom<()>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `B::AssocB`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue