Skip to content

Simplify ImplSource candidates a bit #112687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,8 +781,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
);
return;
}
Ok(Some(ImplSource::Closure(data))) => {
if !tcx.is_const_fn_raw(data.closure_def_id) {
// Closure: Fn{Once|Mut}
Ok(Some(ImplSource::Builtin(_)))
if poly_trait_pred.self_ty().skip_binder().is_closure()
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
{
let ty::Closure(closure_def_id, substs) =
*poly_trait_pred.self_ty().no_bound_vars().unwrap().kind()
else {
unreachable!()
};
if !tcx.is_const_fn_raw(closure_def_id) {
self.check_op(ops::FnCallNonConst {
caller,
callee,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl Qualif for NeedsNonConstDrop {

if !matches!(
impl_src,
ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
ImplSource::Builtin(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
) {
// If our const destruct candidate is not ConstDestruct or implied by the param env,
// then it's bad
Expand Down
156 changes: 11 additions & 145 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,97 +646,53 @@ pub enum ImplSource<'tcx, N> {
/// ImplSource identifying a particular impl.
UserDefined(ImplSourceUserDefinedData<'tcx, N>),

/// ImplSource for auto trait implementations.
/// This carries the information and nested obligations with regards
/// to an auto implementation for a trait `Trait`. The nested obligations
/// ensure the trait implementation holds for all the constituent types.
AutoImpl(ImplSourceAutoImplData<N>),

/// Successful resolution to an obligation provided by the caller
/// for some type parameter. The `Vec<N>` represents the
/// obligations incurred from normalizing the where-clause (if
/// any).
Param(Vec<N>, ty::BoundConstness),

/// Virtual calls through an object.
Object(ImplSourceObjectData<'tcx, N>),
Object(ImplSourceObjectData<N>),

/// Successful resolution for a builtin trait.
Builtin(ImplSourceBuiltinData<N>),
Builtin(Vec<N>),

/// ImplSource for trait upcasting coercion
TraitUpcasting(ImplSourceTraitUpcastingData<'tcx, N>),

/// ImplSource automatically generated for a closure. The `DefId` is the ID
/// of the closure expression. This is an `ImplSource::UserDefined` in spirit, but the
/// impl is generated by the compiler and does not appear in the source.
Closure(ImplSourceClosureData<'tcx, N>),

/// Same as above, but for a function pointer type with the given signature.
FnPointer(ImplSourceFnPointerData<'tcx, N>),

/// ImplSource automatically generated for a generator.
Generator(ImplSourceGeneratorData<'tcx, N>),

/// ImplSource automatically generated for a generator backing an async future.
Future(ImplSourceFutureData<'tcx, N>),
TraitUpcasting(ImplSourceTraitUpcastingData<N>),

/// ImplSource for a trait alias.
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),

/// ImplSource for a `const Drop` implementation.
ConstDestruct(ImplSourceConstDestructData<N>),
}

impl<'tcx, N> ImplSource<'tcx, N> {
pub fn nested_obligations(self) -> Vec<N> {
match self {
ImplSource::UserDefined(i) => i.nested,
ImplSource::Param(n, _) => n,
ImplSource::Builtin(i) => i.nested,
ImplSource::AutoImpl(d) => d.nested,
ImplSource::Closure(c) => c.nested,
ImplSource::Generator(c) => c.nested,
ImplSource::Future(c) => c.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
ImplSource::Object(d) => d.nested,
ImplSource::FnPointer(d) => d.nested,
ImplSource::TraitAlias(d) => d.nested,
ImplSource::TraitUpcasting(d) => d.nested,
ImplSource::ConstDestruct(i) => i.nested,
}
}

pub fn borrow_nested_obligations(&self) -> &[N] {
match self {
ImplSource::UserDefined(i) => &i.nested,
ImplSource::Param(n, _) => n,
ImplSource::Builtin(i) => &i.nested,
ImplSource::AutoImpl(d) => &d.nested,
ImplSource::Closure(c) => &c.nested,
ImplSource::Generator(c) => &c.nested,
ImplSource::Future(c) => &c.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n,
ImplSource::Object(d) => &d.nested,
ImplSource::FnPointer(d) => &d.nested,
ImplSource::TraitAlias(d) => &d.nested,
ImplSource::TraitUpcasting(d) => &d.nested,
ImplSource::ConstDestruct(i) => &i.nested,
}
}

pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
match self {
ImplSource::UserDefined(i) => &mut i.nested,
ImplSource::Param(n, _) => n,
ImplSource::Builtin(i) => &mut i.nested,
ImplSource::AutoImpl(d) => &mut d.nested,
ImplSource::Closure(c) => &mut c.nested,
ImplSource::Generator(c) => &mut c.nested,
ImplSource::Future(c) => &mut c.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
ImplSource::Object(d) => &mut d.nested,
ImplSource::FnPointer(d) => &mut d.nested,
ImplSource::TraitAlias(d) => &mut d.nested,
ImplSource::TraitUpcasting(d) => &mut d.nested,
ImplSource::ConstDestruct(i) => &mut i.nested,
}
}

Expand All @@ -751,54 +707,23 @@ impl<'tcx, N> ImplSource<'tcx, N> {
nested: i.nested.into_iter().map(f).collect(),
}),
ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
ImplSource::Builtin(i) => ImplSource::Builtin(ImplSourceBuiltinData {
nested: i.nested.into_iter().map(f).collect(),
}),
ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()),
ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
upcast_trait_ref: o.upcast_trait_ref,
upcast_trait_def_id: o.upcast_trait_def_id,
vtable_base: o.vtable_base,
nested: o.nested.into_iter().map(f).collect(),
}),
ImplSource::AutoImpl(d) => ImplSource::AutoImpl(ImplSourceAutoImplData {
trait_def_id: d.trait_def_id,
nested: d.nested.into_iter().map(f).collect(),
}),
ImplSource::Closure(c) => ImplSource::Closure(ImplSourceClosureData {
closure_def_id: c.closure_def_id,
substs: c.substs,
nested: c.nested.into_iter().map(f).collect(),
}),
ImplSource::Generator(c) => ImplSource::Generator(ImplSourceGeneratorData {
generator_def_id: c.generator_def_id,
substs: c.substs,
nested: c.nested.into_iter().map(f).collect(),
}),
ImplSource::Future(c) => ImplSource::Future(ImplSourceFutureData {
generator_def_id: c.generator_def_id,
substs: c.substs,
nested: c.nested.into_iter().map(f).collect(),
}),
ImplSource::FnPointer(p) => ImplSource::FnPointer(ImplSourceFnPointerData {
fn_ty: p.fn_ty,
nested: p.nested.into_iter().map(f).collect(),
}),
ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
alias_def_id: d.alias_def_id,
substs: d.substs,
nested: d.nested.into_iter().map(f).collect(),
}),
ImplSource::TraitUpcasting(d) => {
ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
upcast_trait_ref: d.upcast_trait_ref,
vtable_vptr_slot: d.vtable_vptr_slot,
nested: d.nested.into_iter().map(f).collect(),
})
}
ImplSource::ConstDestruct(i) => {
ImplSource::ConstDestruct(ImplSourceConstDestructData {
nested: i.nested.into_iter().map(f).collect(),
})
}
}
}
}
Expand All @@ -823,47 +748,7 @@ pub struct ImplSourceUserDefinedData<'tcx, N> {

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceGeneratorData<'tcx, N> {
pub generator_def_id: DefId,
pub substs: SubstsRef<'tcx>,
/// Nested obligations. This can be non-empty if the generator
/// signature contains associated types.
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceFutureData<'tcx, N> {
pub generator_def_id: DefId,
pub substs: SubstsRef<'tcx>,
/// Nested obligations. This can be non-empty if the generator
/// signature contains associated types.
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceClosureData<'tcx, N> {
pub closure_def_id: DefId,
pub substs: SubstsRef<'tcx>,
/// Nested obligations. This can be non-empty if the closure
/// signature contains associated types.
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceAutoImplData<N> {
pub trait_def_id: DefId,
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceTraitUpcastingData<'tcx, N> {
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,

pub struct ImplSourceTraitUpcastingData<N> {
/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will
/// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable
Expand All @@ -873,17 +758,11 @@ pub struct ImplSourceTraitUpcastingData<'tcx, N> {
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceBuiltinData<N> {
pub nested: Vec<N>,
}

#[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceObjectData<'tcx, N> {
pub struct ImplSourceObjectData<N> {
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
pub upcast_trait_def_id: DefId,

/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will
Expand All @@ -894,19 +773,6 @@ pub struct ImplSourceObjectData<'tcx, N> {
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceFnPointerData<'tcx, N> {
pub fn_ty: Ty<'tcx>,
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceConstDestructData<N> {
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceTraitAliasData<'tcx, N> {
Expand Down
Loading