diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index 4203ae8c509cc..7d526a0a07d71 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -1069,13 +1069,25 @@ where else { return Err(NoSolution.into()); }; - let def_id = goal.predicate.alias.expect_projection_ty_def_id(); - let ty = match ecx.cx().as_projection_lang_item(def_id) { - Some(SolverProjectionLangItem::FieldBase) => base, - Some(SolverProjectionLangItem::FieldType) => ty, - _ => panic!("unexpected associated type {:?} in `Field`", goal.predicate), - }; ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + let ty = match goal.predicate.alias.kind { + ty::AliasTermKind::ProjectionTy { def_id } => { + match ecx.cx().as_projection_lang_item(def_id) { + Some(SolverProjectionLangItem::FieldBase) => base, + Some(SolverProjectionLangItem::FieldType) => ty, + _ => panic!("unexpected associated type {:?} in `Field`", goal.predicate), + } + } + ty::AliasTermKind::ProjectionConst { .. } => { + return ecx.evaluate_const_and_instantiate_projection_term( + goal.param_env, + goal.predicate.alias, + goal.predicate.term, + goal.predicate.alias.expect_ct(), + ); + } + kind => panic!("expected projection, found {kind:?}"), + }; ecx.instantiate_normalizes_to_term(goal, ty.into())?; ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) diff --git a/tests/ui/field_representing_types/offset-missing-features-issue-162338.rs b/tests/ui/field_representing_types/offset-missing-features-issue-162338.rs new file mode 100644 index 0000000000000..61ae4776f8222 --- /dev/null +++ b/tests/ui/field_representing_types/offset-missing-features-issue-162338.rs @@ -0,0 +1,21 @@ +// Request MIR so normalization runs even though the crate has feature errors. +//@ compile-flags: -Znext-solver --emit=mir + +#![feature(gca_const_items)] +//~^ ERROR `gca_const_items` requires `gca_min_const_items` to be enabled +#![allow(incomplete_features)] + +use std::field::{field_of, Field}; +//~^ ERROR use of unstable library feature `field_projections` +//~| ERROR use of unstable library feature `field_projections` + +struct Struct { + b: i64, +} + +fn project_ref() { + ::OFFSET; + //~^ ERROR use of unstable library feature `field_projections` + //~| ERROR use of unstable library feature `field_projections` +} +//~^ ERROR `main` function not found diff --git a/tests/ui/field_representing_types/offset-missing-features-issue-162338.stderr b/tests/ui/field_representing_types/offset-missing-features-issue-162338.stderr new file mode 100644 index 0000000000000..11a10c83ebffc --- /dev/null +++ b/tests/ui/field_representing_types/offset-missing-features-issue-162338.stderr @@ -0,0 +1,58 @@ +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/offset-missing-features-issue-162338.rs:17:6 + | +LL | ::OFFSET; + | ^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` 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: `gca_const_items` requires `gca_min_const_items` to be enabled + --> $DIR/offset-missing-features-issue-162338.rs:4:12 + | +LL | #![feature(gca_const_items)] + | ^^^^^^^^^^^^^^^ + | + = help: enable all of these features + +error[E0601]: `main` function not found in crate `offset_missing_features_issue_162338` + --> $DIR/offset-missing-features-issue-162338.rs:20:2 + | +LL | } + | ^ consider adding a `main` function to `$DIR/offset-missing-features-issue-162338.rs` + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/offset-missing-features-issue-162338.rs:8:18 + | +LL | use std::field::{field_of, Field}; + | ^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/offset-missing-features-issue-162338.rs:8:28 + | +LL | use std::field::{field_of, Field}; + | ^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `field_projections` + --> $DIR/offset-missing-features-issue-162338.rs:17:5 + | +LL | ::OFFSET; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #145383 for more information + = help: add `#![feature(field_projections)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0601, E0658. +For more information about an error, try `rustc --explain E0601`. diff --git a/tests/ui/field_representing_types/offset.rs b/tests/ui/field_representing_types/offset.rs index 1275cc9f00270..d33b0c838ed3a 100644 --- a/tests/ui/field_representing_types/offset.rs +++ b/tests/ui/field_representing_types/offset.rs @@ -1,9 +1,11 @@ -//@ revisions: old next +//@ revisions: old next gca_const_items //@ ignore-compare-mode-next-solver (explicit revisions) //@ [next] compile-flags: -Znext-solver +//@ [gca_const_items] compile-flags: -Znext-solver //@ run-pass #![expect(incomplete_features)] #![feature(field_projections)] +#![cfg_attr(gca_const_items, feature(gca_const_items, gca_min_const_items))] use std::field::{Field, field_of}; use std::mem::offset_of; @@ -32,9 +34,21 @@ fn project_ref<'a, T, F: Field>(r: &'a T) -> &'a F::Type { unsafe { &*ptr::from_ref(r).byte_add(F::OFFSET).cast() } } +#[repr(C)] +struct Generic { + a: u8, + b: T, +} + +fn generic_offset() -> usize { + , b)>::OFFSET +} + fn main() { assert_eq!(::OFFSET, offset_of!(Struct, a)); assert_eq!(::OFFSET, offset_of!(Struct, b)); + assert_eq!(generic_offset::(), offset_of!(Generic, b)); + assert_eq!(generic_offset::(), offset_of!(Generic, b)); let _: field_of!(Union, a); let _: field_of!(Union, b);