Auto merge of #134164 - jhpratt:rollup-s7z0vcc, r=jhpratt
Rollup of 8 pull requests Successful merges: - #134079 (Add a note saying that `{u8,i8}::from_{be,le,ne}_bytes` is meaningless) - #134105 (Validate self in host predicates correctly) - #134136 (Exercise const trait interaction with default fields) - #134139 ([AIX] keep profile-rt symbol alive) - #134141 (Remove more traces of anonymous ADTs) - #134142 (Rudimentary heuristic to insert parentheses when needed for RPIT overcaptures lint) - #134158 (Rename `projection_def_id` to `item_def_id`) - #134160 (Add vacation entry for myself in triagebot.toml) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
1f3bf231e1
29 changed files with 174 additions and 72 deletions
|
@ -1694,6 +1694,8 @@ impl<'a> Linker for AixLinker<'a> {
|
|||
|
||||
fn pgo_gen(&mut self) {
|
||||
self.link_arg("-bdbg:namedsects:ss");
|
||||
self.link_arg("-u");
|
||||
self.link_arg("__llvm_profile_runtime");
|
||||
}
|
||||
|
||||
fn control_flow_guard(&mut self) {}
|
||||
|
|
|
@ -9,7 +9,6 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
|||
use rustc_span::Symbol;
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::symbol::kw;
|
||||
|
||||
use crate::definitions::DefPathData;
|
||||
use crate::hir;
|
||||
|
@ -256,7 +255,6 @@ impl DefKind {
|
|||
|
||||
pub fn def_path_data(self, name: Symbol) -> DefPathData {
|
||||
match self {
|
||||
DefKind::Struct | DefKind::Union if name == kw::Empty => DefPathData::AnonAdt,
|
||||
DefKind::Mod
|
||||
| DefKind::Struct
|
||||
| DefKind::Union
|
||||
|
|
|
@ -289,8 +289,6 @@ pub enum DefPathData {
|
|||
/// An existential `impl Trait` type node.
|
||||
/// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name.
|
||||
OpaqueTy,
|
||||
/// An anonymous struct or union type i.e. `struct { foo: Type }` or `union { bar: Type }`
|
||||
AnonAdt,
|
||||
}
|
||||
|
||||
impl Definitions {
|
||||
|
@ -415,7 +413,7 @@ impl DefPathData {
|
|||
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
|
||||
|
||||
Impl | ForeignMod | CrateRoot | Use | GlobalAsm | Closure | Ctor | AnonConst
|
||||
| OpaqueTy | AnonAdt => None,
|
||||
| OpaqueTy => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,7 +436,6 @@ impl DefPathData {
|
|||
Ctor => DefPathDataName::Anon { namespace: sym::constructor },
|
||||
AnonConst => DefPathDataName::Anon { namespace: sym::constant },
|
||||
OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque },
|
||||
AnonAdt => DefPathDataName::Anon { namespace: sym::anon_adt },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2882,8 +2882,6 @@ pub enum TyKind<'hir> {
|
|||
Never,
|
||||
/// A tuple (`(A, B, C, D, ...)`).
|
||||
Tup(&'hir [Ty<'hir>]),
|
||||
/// An anonymous struct or union type i.e. `struct { foo: Type }` or `union { foo: Type }`
|
||||
AnonAdt(ItemId),
|
||||
/// A path to a type definition (`module::module::...::Type`), or an
|
||||
/// associated type (e.g., `<Vec<T> as Trait>::Type` or `<T>::Target`).
|
||||
///
|
||||
|
|
|
@ -904,9 +904,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
|
|||
}
|
||||
TyKind::Typeof(ref expression) => try_visit!(visitor.visit_anon_const(expression)),
|
||||
TyKind::Infer | TyKind::InferDelegation(..) | TyKind::Err(_) => {}
|
||||
TyKind::AnonAdt(item_id) => {
|
||||
try_visit!(visitor.visit_nested_item(item_id));
|
||||
}
|
||||
TyKind::Pat(ty, pat) => {
|
||||
try_visit!(visitor.visit_ty(ty));
|
||||
try_visit!(visitor.visit_pattern_type_pattern(pat));
|
||||
|
|
|
@ -711,12 +711,19 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
|
|||
`{filter:?}` implied bounds: {clause:?}"
|
||||
);
|
||||
}
|
||||
ty::ClauseKind::HostEffect(host_effect_predicate) => {
|
||||
assert_eq!(
|
||||
host_effect_predicate.self_ty(),
|
||||
ty,
|
||||
"expected `Self` predicate when computing \
|
||||
`{filter:?}` implied bounds: {clause:?}"
|
||||
);
|
||||
}
|
||||
|
||||
ty::ClauseKind::RegionOutlives(_)
|
||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||
| ty::ClauseKind::WellFormed(_)
|
||||
| ty::ClauseKind::ConstEvaluatable(_)
|
||||
| ty::ClauseKind::HostEffect(..) => {
|
||||
| ty::ClauseKind::ConstEvaluatable(_) => {
|
||||
bug!(
|
||||
"unexpected non-`Self` predicate when computing \
|
||||
`{filter:?}` implied bounds: {clause:?}"
|
||||
|
|
|
@ -203,7 +203,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// corresponding `Projection` clause
|
||||
for def_ids in associated_types.values_mut() {
|
||||
for (projection_bound, span) in &projection_bounds {
|
||||
let def_id = projection_bound.projection_def_id();
|
||||
let def_id = projection_bound.item_def_id();
|
||||
def_ids.swap_remove(&def_id);
|
||||
if tcx.generics_require_sized_self(def_id) {
|
||||
tcx.emit_node_span_lint(
|
||||
|
@ -413,7 +413,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
late_bound_in_projection_term,
|
||||
late_bound_in_term,
|
||||
|br_name| {
|
||||
let item_name = tcx.item_name(pred.projection_def_id());
|
||||
let item_name = tcx.item_name(pred.item_def_id());
|
||||
struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
|
|
|
@ -50,7 +50,7 @@ use rustc_span::{DUMMY_SP, Span};
|
|||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::wf::object_region_bounds;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
use tracing::{debug, debug_span, instrument};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::bounds::Bounds;
|
||||
use crate::check::check_abi_fn_ptr;
|
||||
|
@ -2304,19 +2304,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
hir::TyKind::Tup(fields) => {
|
||||
Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t)))
|
||||
}
|
||||
hir::TyKind::AnonAdt(item_id) => {
|
||||
let _guard = debug_span!("AnonAdt");
|
||||
|
||||
let did = item_id.owner_id.def_id;
|
||||
let adt_def = tcx.adt_def(did);
|
||||
|
||||
let args = ty::GenericArgs::for_item(tcx, did.to_def_id(), |param, _| {
|
||||
tcx.mk_param_from_def(param)
|
||||
});
|
||||
debug!(?args);
|
||||
|
||||
Ty::new_adt(tcx, adt_def, tcx.mk_args(args))
|
||||
}
|
||||
hir::TyKind::BareFn(bf) => {
|
||||
require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, hir_ty.span);
|
||||
|
||||
|
|
|
@ -330,7 +330,6 @@ impl<'a> State<'a> {
|
|||
hir::TyKind::Infer | hir::TyKind::InferDelegation(..) => {
|
||||
self.word("_");
|
||||
}
|
||||
hir::TyKind::AnonAdt(..) => self.word("/* anonymous adt */"),
|
||||
hir::TyKind::Pat(ty, pat) => {
|
||||
self.print_type(ty);
|
||||
self.word(" is ");
|
||||
|
|
|
@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
closure_kind: hir::ClosureKind,
|
||||
projection: ty::PolyProjectionPredicate<'tcx>,
|
||||
) -> Option<ExpectedSig<'tcx>> {
|
||||
let def_id = projection.projection_def_id();
|
||||
let def_id = projection.item_def_id();
|
||||
|
||||
// For now, we only do signature deduction based off of the `Fn` and `AsyncFn` traits,
|
||||
// for closures and async closures, respectively.
|
||||
|
|
|
@ -1020,7 +1020,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
|
||||
self.insert_trait_and_projection(
|
||||
trait_ref,
|
||||
Some((proj.projection_def_id(), proj.term())),
|
||||
Some((proj.item_def_id(), proj.term())),
|
||||
&mut traits,
|
||||
&mut fn_traits,
|
||||
);
|
||||
|
|
|
@ -144,7 +144,7 @@ where
|
|||
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if let Some(projection_pred) = assumption.as_projection_clause() {
|
||||
if projection_pred.projection_def_id() == goal.predicate.def_id() {
|
||||
if projection_pred.item_def_id() == goal.predicate.def_id() {
|
||||
let cx = ecx.cx();
|
||||
if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
|
||||
goal.predicate.alias.args,
|
||||
|
|
|
@ -337,7 +337,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
|||
BareFn,
|
||||
Never,
|
||||
Tup,
|
||||
AnonAdt,
|
||||
Path,
|
||||
OpaqueDef,
|
||||
TraitObject,
|
||||
|
|
|
@ -716,8 +716,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
|
|||
| hir::definitions::DefPathData::Use
|
||||
| hir::definitions::DefPathData::GlobalAsm
|
||||
| hir::definitions::DefPathData::MacroNs(..)
|
||||
| hir::definitions::DefPathData::LifetimeNs(..)
|
||||
| hir::definitions::DefPathData::AnonAdt => {
|
||||
| hir::definitions::DefPathData::LifetimeNs(..) => {
|
||||
bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -772,8 +772,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
|||
| DefPathData::GlobalAsm
|
||||
| DefPathData::Impl
|
||||
| DefPathData::MacroNs(_)
|
||||
| DefPathData::LifetimeNs(_)
|
||||
| DefPathData::AnonAdt => {
|
||||
| DefPathData::LifetimeNs(_) => {
|
||||
bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data)
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{Visitor, walk_ty};
|
||||
use rustc_hir::{FnRetTy, GenericParamKind};
|
||||
use rustc_hir::{FnRetTy, GenericParamKind, Node};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath};
|
||||
use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt};
|
||||
|
@ -1888,10 +1888,35 @@ pub fn impl_trait_overcapture_suggestion<'tcx>(
|
|||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
suggs.push((
|
||||
tcx.def_span(opaque_def_id).shrink_to_hi(),
|
||||
format!(" + use<{concatenated_bounds}>"),
|
||||
));
|
||||
let opaque_hir_id = tcx.local_def_id_to_hir_id(opaque_def_id);
|
||||
// FIXME: This is a bit too conservative, since it ignores parens already written in AST.
|
||||
let (lparen, rparen) = match tcx
|
||||
.hir()
|
||||
.parent_iter(opaque_hir_id)
|
||||
.nth(1)
|
||||
.expect("expected ty to have a parent always")
|
||||
.1
|
||||
{
|
||||
Node::PathSegment(segment)
|
||||
if segment.args().paren_sugar_output().is_some_and(|ty| ty.hir_id == opaque_hir_id) =>
|
||||
{
|
||||
("(", ")")
|
||||
}
|
||||
Node::Ty(ty) => match ty.kind {
|
||||
rustc_hir::TyKind::Ptr(_) | rustc_hir::TyKind::Ref(..) => ("(", ")"),
|
||||
// FIXME: RPITs are not allowed to be nested in `impl Fn() -> ...`,
|
||||
// but we eventually could support that, and that would necessitate
|
||||
// making this more sophisticated.
|
||||
_ => ("", ""),
|
||||
},
|
||||
_ => ("", ""),
|
||||
};
|
||||
|
||||
let rpit_span = tcx.def_span(opaque_def_id);
|
||||
if !lparen.is_empty() {
|
||||
suggs.push((rpit_span.shrink_to_lo(), lparen.to_string()));
|
||||
}
|
||||
suggs.push((rpit_span.shrink_to_hi(), format!(" + use<{concatenated_bounds}>{rparen}")));
|
||||
|
||||
Some(AddPreciseCapturingForOvercapture { suggs, apit_spans })
|
||||
}
|
||||
|
|
|
@ -744,7 +744,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
|
|||
let Some(clause) = clause.as_projection_clause() else {
|
||||
return ControlFlow::Continue(());
|
||||
};
|
||||
if clause.projection_def_id() != obligation.predicate.def_id {
|
||||
if clause.item_def_id() != obligation.predicate.def_id {
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
|
||||
|
@ -847,7 +847,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
|
|||
let bound_predicate = predicate.kind();
|
||||
if let ty::ClauseKind::Projection(data) = predicate.kind().skip_binder() {
|
||||
let data = bound_predicate.rebind(data);
|
||||
if data.projection_def_id() != obligation.predicate.def_id {
|
||||
if data.item_def_id() != obligation.predicate.def_id {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1737,7 +1737,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
env_predicate: PolyProjectionPredicate<'tcx>,
|
||||
potentially_unnormalized_candidates: bool,
|
||||
) -> ProjectionMatchesProjection {
|
||||
debug_assert_eq!(obligation.predicate.def_id, env_predicate.projection_def_id());
|
||||
debug_assert_eq!(obligation.predicate.def_id, env_predicate.item_def_id());
|
||||
|
||||
let mut nested_obligations = PredicateObligations::new();
|
||||
let infer_predicate = self.infcx.instantiate_binder_with_fresh_vars(
|
||||
|
|
|
@ -692,7 +692,7 @@ impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
|
|||
///
|
||||
/// Note that this is not the `DefId` of the `TraitRef` containing this
|
||||
/// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
|
||||
pub fn projection_def_id(&self) -> I::DefId {
|
||||
pub fn item_def_id(&self) -> I::DefId {
|
||||
// Ok to skip binder since trait `DefId` does not care about regions.
|
||||
self.skip_binder().projection_term.def_id
|
||||
}
|
||||
|
|
|
@ -77,6 +77,31 @@ pub use saturating::Saturating;
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use wrapping::Wrapping;
|
||||
|
||||
macro_rules! u8_xe_bytes_doc {
|
||||
() => {
|
||||
"
|
||||
|
||||
**Note**: This function is meaningless on `u8`. Byte order does not exist as a
|
||||
concept for byte-sized integers. This function is only provided in symmetry
|
||||
with larger integer types.
|
||||
|
||||
"
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! i8_xe_bytes_doc {
|
||||
() => {
|
||||
"
|
||||
|
||||
**Note**: This function is meaningless on `i8`. Byte order does not exist as a
|
||||
concept for byte-sized integers. This function is only provided in symmetry
|
||||
with larger integer types. You can cast from and to `u8` using `as i8` and `as
|
||||
u8`.
|
||||
|
||||
"
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! usize_isize_to_xe_bytes_doc {
|
||||
() => {
|
||||
"
|
||||
|
@ -348,8 +373,8 @@ impl i8 {
|
|||
reversed = "0x48",
|
||||
le_bytes = "[0x12]",
|
||||
be_bytes = "[0x12]",
|
||||
to_xe_bytes_doc = "",
|
||||
from_xe_bytes_doc = "",
|
||||
to_xe_bytes_doc = i8_xe_bytes_doc!(),
|
||||
from_xe_bytes_doc = i8_xe_bytes_doc!(),
|
||||
bound_condition = "",
|
||||
}
|
||||
midpoint_impl! { i8, i16, signed }
|
||||
|
@ -547,8 +572,8 @@ impl u8 {
|
|||
reversed = "0x48",
|
||||
le_bytes = "[0x12]",
|
||||
be_bytes = "[0x12]",
|
||||
to_xe_bytes_doc = "",
|
||||
from_xe_bytes_doc = "",
|
||||
to_xe_bytes_doc = u8_xe_bytes_doc!(),
|
||||
from_xe_bytes_doc = u8_xe_bytes_doc!(),
|
||||
bound_condition = "",
|
||||
}
|
||||
widening_impl! { u8, u16, 8, unsigned }
|
||||
|
|
|
@ -1841,9 +1841,6 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
|||
TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
|
||||
// Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
|
||||
TyKind::Infer | TyKind::Err(_) | TyKind::Typeof(..) | TyKind::InferDelegation(..) => Infer,
|
||||
TyKind::AnonAdt(..) => {
|
||||
unimplemented!("Anonymous structs or unions are not supported yet")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -818,7 +818,6 @@ impl TyCoercionStability {
|
|||
| TyKind::Typeof(..)
|
||||
| TyKind::TraitObject(..)
|
||||
| TyKind::InferDelegation(..)
|
||||
| TyKind::AnonAdt(..)
|
||||
| TyKind::Err(_) => Self::Reborrow,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -596,7 +596,6 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
(TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r),
|
||||
(&TyKind::Tup(l), &TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)),
|
||||
(&TyKind::Infer, &TyKind::Infer) => true,
|
||||
(TyKind::AnonAdt(l_item_id), TyKind::AnonAdt(r_item_id)) => l_item_id == r_item_id,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -1246,8 +1245,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
| TyKind::Infer
|
||||
| TyKind::Never
|
||||
| TyKind::InferDelegation(..)
|
||||
| TyKind::OpaqueDef(_)
|
||||
| TyKind::AnonAdt(_) => {},
|
||||
| TyKind::OpaqueDef(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,4 +42,8 @@ async fn async_fn<'a>(x: &'a ()) -> impl Sized + use<> {}
|
|||
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
|
||||
//~| WARN this changes meaning in Rust 2024
|
||||
|
||||
pub fn parens(x: &i32) -> &(impl Clone + use<>) { x }
|
||||
//~^ ERROR `impl Clone` will capture more lifetimes than possibly intended in edition 2024
|
||||
//~| WARN this changes meaning in Rust 2024
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -42,4 +42,8 @@ async fn async_fn<'a>(x: &'a ()) -> impl Sized {}
|
|||
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
|
||||
//~| WARN this changes meaning in Rust 2024
|
||||
|
||||
pub fn parens(x: &i32) -> &impl Clone { x }
|
||||
//~^ ERROR `impl Clone` will capture more lifetimes than possibly intended in edition 2024
|
||||
//~| WARN this changes meaning in Rust 2024
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -146,5 +146,24 @@ help: use the precise capturing `use<...>` syntax to make the captures explicit
|
|||
LL | async fn async_fn<'a>(x: &'a ()) -> impl Sized + use<> {}
|
||||
| +++++++
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: `impl Clone` will capture more lifetimes than possibly intended in edition 2024
|
||||
--> $DIR/overcaptures-2024.rs:45:28
|
||||
|
|
||||
LL | pub fn parens(x: &i32) -> &impl Clone { x }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
|
||||
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
|
||||
--> $DIR/overcaptures-2024.rs:45:18
|
||||
|
|
||||
LL | pub fn parens(x: &i32) -> &impl Clone { x }
|
||||
| ^
|
||||
= note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
|
||||
help: use the precise capturing `use<...>` syntax to make the captures explicit
|
||||
|
|
||||
LL | pub fn parens(x: &i32) -> &(impl Clone + use<>) { x }
|
||||
| + ++++++++
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
// Exercise the `default_field_values` feature to confirm it interacts correctly with other nightly
|
||||
// features. In particular, we want to verify that interaction with consts coming from different
|
||||
// contexts are usable as a default field value.
|
||||
//@ run-pass
|
||||
//@ aux-build:struct_field_default.rs
|
||||
#![feature(default_field_values, generic_const_exprs)]
|
||||
#![feature(const_trait_impl, default_field_values, generic_const_exprs)]
|
||||
#![allow(unused_variables, dead_code, incomplete_features)]
|
||||
|
||||
extern crate struct_field_default as xc;
|
||||
|
||||
pub struct S;
|
||||
|
||||
// Basic expressions and `Default` expansion
|
||||
#[derive(Default)]
|
||||
pub struct Foo {
|
||||
pub bar: S = S,
|
||||
pub baz: i32 = 42 + 3,
|
||||
}
|
||||
|
||||
// Enum support for deriving `Default` when all fields have default values
|
||||
#[derive(Default)]
|
||||
pub enum Bar {
|
||||
#[default]
|
||||
|
@ -22,17 +27,27 @@ pub enum Bar {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Qux<A, const C: i32> {
|
||||
bar: S = Qux::<A, C>::S,
|
||||
baz: i32 = foo(),
|
||||
bat: i32 = <Qux<A, C> as T>::K,
|
||||
baq: i32 = Self::K,
|
||||
bay: i32 = C,
|
||||
bak: Vec<A> = Vec::new(),
|
||||
#[const_trait] pub trait ConstDefault {
|
||||
fn value() -> Self;
|
||||
}
|
||||
|
||||
impl<A, const C: i32> Qux<A, C> {
|
||||
impl const ConstDefault for i32 {
|
||||
fn value() -> i32 {
|
||||
101
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Qux<A, const C: i32, X: const ConstDefault> {
|
||||
bar: S = Qux::<A, C, X>::S, // Associated constant from inherent impl
|
||||
baz: i32 = foo(), // Constant function
|
||||
bat: i32 = <Qux<A, C, X> as T>::K, // Associated constant from explicit trait
|
||||
baq: i32 = Self::K, // Associated constant from implicit trait
|
||||
bay: i32 = C, // `const` parameter
|
||||
bak: Vec<A> = Vec::new(), // Associated constant function
|
||||
ban: X = X::value(), // Associated constant function from `const` trait parameter
|
||||
}
|
||||
|
||||
impl<A, const C: i32, X: const ConstDefault> Qux<A, C, X> {
|
||||
const S: S = S;
|
||||
}
|
||||
|
||||
|
@ -40,7 +55,7 @@ trait T {
|
|||
const K: i32;
|
||||
}
|
||||
|
||||
impl<A, const C: i32> T for Qux<A, C> {
|
||||
impl<A, const C: i32, X: const ConstDefault> T for Qux<A, C, X> {
|
||||
const K: i32 = 2;
|
||||
}
|
||||
|
||||
|
@ -65,8 +80,19 @@ fn main () {
|
|||
assert!(matches!(Bar::Foo { bar: S, baz: 45 }, y));
|
||||
assert!(matches!(Bar::Foo { bar: S, baz: 1 }, z));
|
||||
|
||||
let x = Qux::<i32, 4> { .. };
|
||||
assert!(matches!(Qux::<i32, 4> { bar: S, baz: 42, bat: 2, baq: 2, bay: 4, .. }, x));
|
||||
let x = Qux::<i32, 4, i32> { .. };
|
||||
assert!(matches!(
|
||||
Qux::<i32, 4, i32> {
|
||||
bar: S,
|
||||
baz: 42,
|
||||
bat: 2,
|
||||
baq: 2,
|
||||
bay: 4,
|
||||
ban: 101,
|
||||
..
|
||||
},
|
||||
x,
|
||||
));
|
||||
assert!(x.bak.is_empty());
|
||||
|
||||
let x = xc::A { .. };
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// Regression test for <https://github.com/rust-lang/rust/issues/133526>.
|
||||
|
||||
// Ensures we don't ICE when we encounter a `HostEffectPredicate` when computing
|
||||
// the "item super predicates" for `Assoc`.
|
||||
|
||||
//@ compile-flags: -Znext-solver
|
||||
//@ check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
trait Trait {
|
||||
type Assoc: const Trait;
|
||||
}
|
||||
|
||||
const fn needs_trait<T: ~const Trait>() {}
|
||||
|
||||
fn test<T: Trait>() {
|
||||
const { needs_trait::<T::Assoc>() };
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -995,6 +995,7 @@ warn_non_default_branch = true
|
|||
contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
|
||||
users_on_vacation = [
|
||||
"jyn514",
|
||||
"celinval",
|
||||
]
|
||||
|
||||
[assign.adhoc_groups]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue