diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs index 38197c8c72de2..f42f45cc658d6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs @@ -13,10 +13,16 @@ where #[instrument(level = "trace", skip(self), ret)] pub(super) fn normalize_anon_const( &mut self, - goal: Goal>, - def_id: I::UnevaluatedConstId, + goal: Goal>, ) -> QueryResultOrRerunNonErased { - let uv = goal.predicate.alias.expect_ct(); + let cx = self.cx(); + let uv = ty::UnevaluatedConst::new( + cx, + ty::UnevaluatedConstKind::Anon { def_id: goal.predicate.alias.kind }, + goal.predicate.alias.args, + ); + let alias = ty::AliasTerm::from(uv); + let goal = goal.with(cx, ty::NormalizesTo { alias, term: goal.predicate.term }); self.evaluate_const_and_instantiate_normalizes_to_term(goal, uv) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index d35e05aa33cf2..f006d5ac934f2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -11,7 +11,7 @@ use rustc_type_ir::solve::{ RerunNonErased, RerunReason, RerunResultExt, }; use rustc_type_ir::{ - self as ty, FieldInfo, Interner, NormalizesTo, PredicateKind, Unnormalized, Upcast as _, + self as ty, Alias, FieldInfo, Interner, NormalizesTo, PredicateKind, Unnormalized, Upcast as _, }; use tracing::instrument; @@ -50,7 +50,13 @@ where self.normalize_free_alias(goal).map_err(Into::into) } ty::AliasTermKind::AnonConst { def_id } => { - self.normalize_anon_const(goal, def_id).map_err(Into::into) + let cx = self.cx(); + let alias = + Alias::new_unevaluated_const_from_args(cx, def_id, goal.predicate.alias.args); + self.normalize_anon_const( + goal.with(cx, ty::NormalizesTo { alias, term: goal.predicate.term }), + ) + .map_err(Into::into) } } } @@ -121,9 +127,9 @@ where /// We know `term` to always be a fully unconstrained inference variable, so /// `eq` should never fail here. However, in case `term` contains aliases, we /// emit nested `AliasRelate` goals to structurally normalize the alias. - pub fn instantiate_normalizes_to_term( + pub fn instantiate_normalizes_to_term( &mut self, - goal: Goal>, + goal: Goal>, term: I::Term, ) { self.eq(goal.param_env, goal.predicate.term, term) @@ -132,9 +138,9 @@ where /// Unlike `instantiate_normalizes_to_term` this instantiates the expected term /// with a rigid alias. Using this is pretty much always wrong. - pub fn structurally_instantiate_normalizes_to_term( + pub fn structurally_instantiate_normalizes_to_term( &mut self, - goal: Goal>, + goal: Goal>, term: ty::AliasTerm, ) { self.relate_rigid_alias_non_alias(goal.param_env, term, ty::Invariant, goal.predicate.term) diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index d9906795dfba6..daebb5368c00b 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -52,6 +52,7 @@ mod pattern; mod predicate; mod predicate_kind; mod region_kind; +mod ty; mod ty_info; mod ty_kind; mod unnormalized; @@ -80,6 +81,7 @@ pub use predicate_kind::*; pub use region_kind::*; pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy}; use rustc_type_ir_macros::GenericTypeVisitable; +pub use ty::{Alias, AliasTerm, AliasTy}; pub use ty_info::*; pub use ty_kind::*; pub use unnormalized::Unnormalized; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 8de64762c30b5..c48e9777584f5 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -8,10 +8,12 @@ use rustc_type_ir_macros::{ GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, }; +use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use crate::inherent::*; +use crate::ty::AliasTerm; use crate::upcast::{Upcast, UpcastFrom}; -use crate::visit::TypeVisitableExt as _; -use crate::{self as ty, AliasTyKind, Interner, UnevaluatedConstKind}; +use crate::visit::{TypeVisitable, TypeVisitableExt as _, TypeVisitor}; +use crate::{self as ty, Alias, AliasTyKind, Interner, UnevaluatedConstKind, try_visit}; /// `A: 'region` #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)] @@ -544,7 +546,7 @@ impl ty::Binder> { } #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] -#[derive(Lift_Generic, GenericTypeVisitable)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic, GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext) @@ -661,41 +663,6 @@ impl From> for AliasTermKind { } } -/// Represents the unprojected term of a projection goal. -/// -/// * For a projection, this would be `>::N<...>`. -/// * For an inherent projection, this would be `Ty::N<...>`. -/// * For an opaque type, there is no explicit syntax. -#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] -#[cfg_attr( - feature = "nightly", - derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) -)] -pub struct AliasTerm { - /// The parameters of the associated or opaque item. - /// - /// For a projection, these are the generic parameters for the trait and the - /// GAT parameters, if there are any. - /// - /// For an inherent projection, they consist of the self type and the GAT parameters, - /// if there are any. - /// - /// For RPIT the generic parameters are for the generics of the function, - /// while for TAIT it is used for the generic parameters of the alias. - pub args: I::GenericArgs, - - #[type_foldable(identity)] - #[type_visitable(ignore)] - pub kind: AliasTermKind, - - /// This field exists to prevent the creation of `AliasTerm` without using [`AliasTerm::new_from_args`]. - #[derive_where(skip(Debug))] - _use_alias_term_new_instead: (), -} - -impl Eq for AliasTerm {} - impl AliasTerm { pub fn new_from_args( interner: I, @@ -703,7 +670,7 @@ impl AliasTerm { args: I::GenericArgs, ) -> AliasTerm { interner.debug_assert_args_compatible(kind.def_id(), args); - AliasTerm { kind, args, _use_alias_term_new_instead: () } + AliasTerm { kind, args, _use_alias_new_instead: () } } pub fn new( @@ -733,7 +700,7 @@ impl AliasTerm { panic!("Cannot turn `{}` into `AliasTy`", kind.descr()) } }; - ty::AliasTy { kind, args: self.args, _use_alias_ty_new_instead: () } + ty::AliasTy { kind, args: self.args, _use_alias_new_instead: () } } pub fn expect_ct(self) -> ty::UnevaluatedConst { @@ -884,21 +851,13 @@ impl AliasTerm { impl From> for AliasTerm { fn from(ty: ty::AliasTy) -> Self { - AliasTerm { - args: ty.args, - kind: AliasTermKind::from(ty.kind), - _use_alias_term_new_instead: (), - } + AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () } } } impl From> for AliasTerm { fn from(ty: ty::UnevaluatedConst) -> Self { - AliasTerm { - args: ty.args, - kind: AliasTermKind::from(ty.kind), - _use_alias_term_new_instead: (), - } + AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () } } } @@ -977,18 +936,36 @@ impl fmt::Debug for ProjectionPredicate { /// Used by the new solver to normalize an alias. This always expects the `term` to /// be an unconstrained inference variable which is used as the output. -#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] +#[derive_where(Clone, Copy, Hash, Eq, PartialEq; I: Interner, K)] +#[derive(GenericTypeVisitable, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) )] -pub struct NormalizesTo { - pub alias: AliasTerm, +pub struct NormalizesTo> { + pub alias: Alias, pub term: I::Term, } -impl Eq for NormalizesTo {} +impl> TypeVisitable for NormalizesTo { + fn visit_with>(&self, visitor: &mut V) -> V::Result { + try_visit!(self.alias.visit_with(visitor)); + self.term.visit_with(visitor) + } +} + +impl> TypeFoldable for NormalizesTo { + fn try_fold_with>(self, folder: &mut F) -> Result { + Ok(NormalizesTo { + alias: self.alias.try_fold_with(folder)?, + term: self.term.try_fold_with(folder)?, + }) + } + + fn fold_with>(self, folder: &mut F) -> Self { + NormalizesTo { alias: self.alias.fold_with(folder), term: self.term.fold_with(folder) } + } +} impl NormalizesTo { pub fn self_ty(self) -> I::Ty { @@ -1008,7 +985,7 @@ impl NormalizesTo { } } -impl fmt::Debug for NormalizesTo { +impl fmt::Debug for NormalizesTo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term) } diff --git a/compiler/rustc_type_ir/src/ty/alias.rs b/compiler/rustc_type_ir/src/ty/alias.rs new file mode 100644 index 0000000000000..f8c303628304d --- /dev/null +++ b/compiler/rustc_type_ir/src/ty/alias.rs @@ -0,0 +1,66 @@ +use derive_where::derive_where; +#[cfg(feature = "nightly")] +use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext}; +use rustc_type_ir_macros::{ + GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; + +use crate::Interner; +use crate::predicate::AliasTermKind; +use crate::ty_kind::AliasTyKind; + +/// Represents an alias of a type, constant, or other term-like item. +/// +/// * For a projection, this would be `>::N<...>`. +/// * For an inherent projection, this would be `Ty::N<...>`. +/// * For an opaque type, there is no explicit syntax. +#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner, K)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr( + feature = "nightly", + derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) +)] +pub struct Alias { + /// The parameters of the associated, opaque, or constant alias. + /// + /// For a projection, these are the generic parameters for the trait and the + /// GAT parameters, if there are any. + /// + /// For an inherent projection, they consist of the self type and the GAT parameters, + /// if there are any. + /// + /// For RPIT the generic parameters are for the generics of the function, + /// while for TAIT it is used for the generic parameters of the alias. + pub args: I::GenericArgs, + + pub kind: K, + + /// This field exists to prevent the creation of `Alias` without using the relevant constructor. + #[derive_where(skip(Debug))] + #[type_visitable(ignore)] + #[type_foldable(identity)] + #[lift(identity)] + pub(crate) _use_alias_new_instead: (), +} + +impl Eq for Alias {} + +impl Alias { + pub fn kind(self, _interner: I) -> K { + self.kind + } +} + +impl Alias { + pub fn new_unevaluated_const_from_args( + interner: I, + kind: I::UnevaluatedConstId, + args: I::GenericArgs, + ) -> Self { + interner.debug_assert_args_compatible(kind.into(), args); + Alias { kind, args, _use_alias_new_instead: () } + } +} + +pub type AliasTerm = Alias>; +pub type AliasTy = Alias>; diff --git a/compiler/rustc_type_ir/src/ty/mod.rs b/compiler/rustc_type_ir/src/ty/mod.rs new file mode 100644 index 0000000000000..0b0ae47e37c62 --- /dev/null +++ b/compiler/rustc_type_ir/src/ty/mod.rs @@ -0,0 +1,3 @@ +mod alias; + +pub use alias::{Alias, AliasTerm, AliasTy}; diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 2014ec094524f..b9b42cbb35f56 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -17,6 +17,7 @@ use rustc_type_ir_macros::{ use self::TyKind::*; pub use self::closure::*; use crate::inherent::*; +use crate::ty::AliasTy; #[cfg(feature = "nightly")] use crate::visit::TypeVisitable; use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy}; @@ -24,7 +25,7 @@ use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy}; mod closure; #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(GenericTypeVisitable, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext) @@ -431,45 +432,10 @@ impl fmt::Debug for TyKind { } } -/// Represents the projection of an associated, opaque, or lazy-type-alias type. -/// -/// * For a projection, this would be `>::N<...>`. -/// * For an inherent projection, this would be `Ty::N<...>`. -/// * For an opaque type, there is no explicit syntax. -#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] -#[cfg_attr( - feature = "nightly", - derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) -)] -pub struct AliasTy { - /// The parameters of the associated or opaque type. - /// - /// For a projection, these are the generic parameters for the trait and the - /// GAT parameters, if there are any. - /// - /// For an inherent projection, they consist of the self type and the GAT parameters, - /// if there are any. - /// - /// For RPIT the generic parameters are for the generics of the function, - /// while for TAIT it is used for the generic parameters of the alias. - pub args: I::GenericArgs, - - #[type_foldable(identity)] - #[type_visitable(ignore)] - pub kind: AliasTyKind, - - /// This field exists to prevent the creation of `AliasTy` without using [`AliasTy::new_from_args`]. - #[derive_where(skip(Debug))] - pub(crate) _use_alias_ty_new_instead: (), -} - -impl Eq for AliasTy {} - impl AliasTy { pub fn new_from_args(interner: I, kind: AliasTyKind, args: I::GenericArgs) -> AliasTy { interner.debug_assert_args_compatible(kind.def_id(), args); - AliasTy { kind, args, _use_alias_ty_new_instead: () } + AliasTy { kind, args, _use_alias_new_instead: () } } pub fn new( @@ -481,6 +447,19 @@ impl AliasTy { Self::new_from_args(interner, kind, args) } + pub fn new_from_def_id(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy { + let kind = interner.alias_ty_kind_from_def_id(def_id); + Self::new_from_args(interner, kind, args) + } + + pub fn def_id(self) -> I::DefId { + self.kind.def_id() + } + + pub fn with_args(self, interner: I, args: I::GenericArgs) -> Self { + Self::new_from_args(interner, self.kind, args) + } + /// Whether this alias type is an opaque. pub fn is_opaque(self) -> bool { matches!(self.kind, AliasTyKind::Opaque { .. }) diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index 12d9308431734..39ec8faf51b74 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -33,7 +33,7 @@ error: rustc_dump_item_bounds LL | type Assoc: std::ops::Deref | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Binder { value: ProjectionPredicate(AliasTerm { args: [Alias(AliasTy { args: [Self/#0, T/#1, P/#2], kind: Projection { def_id: DefId(..) }, .. })], kind: ProjectionTy { def_id: DefId(..) }, .. }, Term::Ty(())), bound_vars: [] } + = note: Binder { value: ProjectionPredicate(Alias { args: [Alias(Alias { args: [Self/#0, T/#1, P/#2], kind: Projection { def_id: DefId(..) }, .. })], kind: ProjectionTy { def_id: DefId(..) }, .. }, Term::Ty(())), bound_vars: [] } = note: Binder { value: TraitPredicate(<>::Assoc

as std::ops::Deref>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<>::Assoc

as std::marker::Sized>, polarity:Positive), bound_vars: [] } diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index 38fb75483f3b3..ba66f4e012a82 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -1,5 +1,5 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], kind: ProjectionTy { def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }, .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], kind: ProjectionTy { def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }, .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], kind: ProjectionTy { def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }, .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], kind: ProjectionTy { def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }, .. } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:32:1 | diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index 1dac3ecea2687..d86c82c268986 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,5 +1,5 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], kind: ProjectionTy { def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }, .. } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], kind: ProjectionTy { def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }, .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], kind: ProjectionTy { def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }, .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1))], kind: ProjectionTy { def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }, .. } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:32:1 | diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index 4649aac47cdbf..99fd0010a7695 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -1,4 +1,4 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a))], kind: ProjectionTy { def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) }, .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a))], kind: ProjectionTy { def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) }, .. } error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied --> $DIR/structually-relate-aliases.rs:13:36 | diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 32adbb491bee7..da6931eaa5c07 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -16,7 +16,7 @@ help: this trait has no implementations, consider adding one LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTerm { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a)), ?1t], kind: FreeTy { def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }, .. } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a)), ?1t], kind: FreeTy { def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }, .. } error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0425.