Skip to content

Commit ffd978b

Browse files
committed
Auto merge of rust-lang#132044 - lcnr:no-relate-abi, r=compiler-errors
do not implement `Relate` for "boring" types and update some macros while we're at it. This means we don't have to implement `TypeVisitable` for them. r? `@compiler-errors`
2 parents 9abfcb4 + 00266ee commit ffd978b

File tree

9 files changed

+110
-115
lines changed

9 files changed

+110
-115
lines changed

Diff for: compiler/rustc_middle/src/ty/error.rs

-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ impl<'tcx> TypeError<'tcx> {
3535
TypeError::CyclicTy(_) => "cyclic type of infinite size".into(),
3636
TypeError::CyclicConst(_) => "encountered a self-referencing constant".into(),
3737
TypeError::Mismatch => "types differ".into(),
38-
TypeError::ConstnessMismatch(values) => {
39-
format!("expected {} bound, found {} bound", values.expected, values.found).into()
40-
}
4138
TypeError::PolarityMismatch(values) => {
4239
format!("expected {} polarity, found {} polarity", values.expected, values.found)
4340
.into()

Diff for: compiler/rustc_middle/src/ty/relate.rs

-22
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use std::iter;
22

3-
use rustc_hir as hir;
4-
use rustc_target::spec::abi;
53
pub use rustc_type_ir::relate::*;
64

75
use crate::ty::error::{ExpectedFound, TypeError};
@@ -121,26 +119,6 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<
121119
}
122120
}
123121

124-
impl<'tcx> Relate<TyCtxt<'tcx>> for hir::Safety {
125-
fn relate<R: TypeRelation<TyCtxt<'tcx>>>(
126-
_relation: &mut R,
127-
a: hir::Safety,
128-
b: hir::Safety,
129-
) -> RelateResult<'tcx, hir::Safety> {
130-
if a != b { Err(TypeError::SafetyMismatch(ExpectedFound::new(true, a, b))) } else { Ok(a) }
131-
}
132-
}
133-
134-
impl<'tcx> Relate<TyCtxt<'tcx>> for abi::Abi {
135-
fn relate<R: TypeRelation<TyCtxt<'tcx>>>(
136-
_relation: &mut R,
137-
a: abi::Abi,
138-
b: abi::Abi,
139-
) -> RelateResult<'tcx, abi::Abi> {
140-
if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(ExpectedFound::new(true, a, b))) }
141-
}
142-
}
143-
144122
impl<'tcx> Relate<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> {
145123
fn relate<R: TypeRelation<TyCtxt<'tcx>>>(
146124
relation: &mut R,

Diff for: compiler/rustc_middle/src/ty/structural_impls.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,6 @@ TrivialTypeTraversalImpls! {
264264
// interners).
265265
TrivialTypeTraversalAndLiftImpls! {
266266
::rustc_hir::def_id::DefId,
267-
::rustc_hir::Safety,
268-
::rustc_target::spec::abi::Abi,
269267
crate::ty::ClosureKind,
270268
crate::ty::ParamConst,
271269
crate::ty::ParamTy,
@@ -276,6 +274,11 @@ TrivialTypeTraversalAndLiftImpls! {
276274
rustc_target::abi::Size,
277275
}
278276

277+
TrivialLiftImpls! {
278+
::rustc_hir::Safety,
279+
::rustc_target::spec::abi::Abi,
280+
}
281+
279282
///////////////////////////////////////////////////////////////////////////
280283
// Lift implementations
281284

Diff for: compiler/rustc_type_ir/src/error.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ impl<T> ExpectedFound<T> {
2727
#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
2828
pub enum TypeError<I: Interner> {
2929
Mismatch,
30-
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
31-
PolarityMismatch(ExpectedFound<ty::PredicatePolarity>),
32-
SafetyMismatch(ExpectedFound<I::Safety>),
33-
AbiMismatch(ExpectedFound<I::Abi>),
30+
PolarityMismatch(#[type_visitable(ignore)] ExpectedFound<ty::PredicatePolarity>),
31+
SafetyMismatch(#[type_visitable(ignore)] ExpectedFound<I::Safety>),
32+
AbiMismatch(#[type_visitable(ignore)] ExpectedFound<I::Abi>),
3433
Mutability,
3534
ArgumentMutability(usize),
3635
TupleSize(ExpectedFound<usize>),
@@ -73,9 +72,9 @@ impl<I: Interner> TypeError<I> {
7372
pub fn must_include_note(self) -> bool {
7473
use self::TypeError::*;
7574
match self {
76-
CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | ConstnessMismatch(_)
77-
| PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_)
78-
| ArgumentSorts(..) | Sorts(_) | VariadicMismatch(_) | TargetFeatureCast(_) => false,
75+
CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | PolarityMismatch(_) | Mismatch
76+
| AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_)
77+
| VariadicMismatch(_) | TargetFeatureCast(_) => false,
7978

8079
Mutability
8180
| ArgumentMutability(_)

Diff for: compiler/rustc_type_ir/src/inherent.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,14 @@ pub trait Tys<I: Interner<Tys = Self>>:
208208
fn output(self) -> I::Ty;
209209
}
210210

211-
pub trait Abi<I: Interner<Abi = Self>>: Copy + Debug + Hash + Eq + Relate<I> {
211+
pub trait Abi<I: Interner<Abi = Self>>: Copy + Debug + Hash + Eq {
212212
fn rust() -> Self;
213213

214214
/// Whether this ABI is `extern "Rust"`.
215215
fn is_rust(self) -> bool;
216216
}
217217

218-
pub trait Safety<I: Interner<Safety = Self>>: Copy + Debug + Hash + Eq + Relate<I> {
218+
pub trait Safety<I: Interner<Safety = Self>>: Copy + Debug + Hash + Eq {
219219
fn safe() -> Self;
220220

221221
fn is_safe(self) -> bool;

Diff for: compiler/rustc_type_ir/src/relate.rs

+17-37
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,17 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> {
174174
ExpectedFound::new(true, a, b)
175175
}));
176176
}
177-
let safety = relation.relate(a.safety, b.safety)?;
178-
let abi = relation.relate(a.abi, b.abi)?;
177+
178+
if a.safety != b.safety {
179+
return Err(TypeError::SafetyMismatch(ExpectedFound::new(true, a.safety, b.safety)));
180+
}
181+
182+
if a.abi != b.abi {
183+
return Err(TypeError::AbiMismatch(ExpectedFound::new(true, a.abi, b.abi)));
184+
};
179185

180186
let a_inputs = a.inputs();
181187
let b_inputs = b.inputs();
182-
183188
if a_inputs.len() != b_inputs.len() {
184189
return Err(TypeError::ArgCount);
185190
}
@@ -212,26 +217,12 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> {
212217
Ok(ty::FnSig {
213218
inputs_and_output: cx.mk_type_list_from_iter(inputs_and_output)?,
214219
c_variadic: a.c_variadic,
215-
safety,
216-
abi,
220+
safety: a.safety,
221+
abi: a.abi,
217222
})
218223
}
219224
}
220225

221-
impl<I: Interner> Relate<I> for ty::BoundConstness {
222-
fn relate<R: TypeRelation<I>>(
223-
_relation: &mut R,
224-
a: ty::BoundConstness,
225-
b: ty::BoundConstness,
226-
) -> RelateResult<I, ty::BoundConstness> {
227-
if a != b {
228-
Err(TypeError::ConstnessMismatch(ExpectedFound::new(true, a, b)))
229-
} else {
230-
Ok(a)
231-
}
232-
}
233-
}
234-
235226
impl<I: Interner> Relate<I> for ty::AliasTy<I> {
236227
fn relate<R: TypeRelation<I>>(
237228
relation: &mut R,
@@ -659,29 +650,18 @@ impl<I: Interner, T: Relate<I>> Relate<I> for ty::Binder<I, T> {
659650
}
660651
}
661652

662-
impl<I: Interner> Relate<I> for ty::PredicatePolarity {
663-
fn relate<R: TypeRelation<I>>(
664-
_relation: &mut R,
665-
a: ty::PredicatePolarity,
666-
b: ty::PredicatePolarity,
667-
) -> RelateResult<I, ty::PredicatePolarity> {
668-
if a != b {
669-
Err(TypeError::PolarityMismatch(ExpectedFound::new(true, a, b)))
670-
} else {
671-
Ok(a)
672-
}
673-
}
674-
}
675-
676653
impl<I: Interner> Relate<I> for ty::TraitPredicate<I> {
677654
fn relate<R: TypeRelation<I>>(
678655
relation: &mut R,
679656
a: ty::TraitPredicate<I>,
680657
b: ty::TraitPredicate<I>,
681658
) -> RelateResult<I, ty::TraitPredicate<I>> {
682-
Ok(ty::TraitPredicate {
683-
trait_ref: relation.relate(a.trait_ref, b.trait_ref)?,
684-
polarity: relation.relate(a.polarity, b.polarity)?,
685-
})
659+
let trait_ref = relation.relate(a.trait_ref, b.trait_ref)?;
660+
if a.polarity != b.polarity {
661+
return Err(TypeError::PolarityMismatch(ExpectedFound::new(
662+
true, a.polarity, b.polarity,
663+
)));
664+
}
665+
Ok(ty::TraitPredicate { trait_ref, polarity: a.polarity })
686666
}
687667
}

Diff for: compiler/rustc_type_ir/src/ty_kind.rs

+4
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,11 @@ pub struct TypeAndMut<I: Interner> {
861861
pub struct FnSig<I: Interner> {
862862
pub inputs_and_output: I::Tys,
863863
pub c_variadic: bool,
864+
#[type_visitable(ignore)]
865+
#[type_foldable(identity)]
864866
pub safety: I::Safety,
867+
#[type_visitable(ignore)]
868+
#[type_foldable(identity)]
865869
pub abi: I::Abi,
866870
}
867871

Diff for: compiler/rustc_type_ir/src/ty_kind/closure.rs

+4
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,12 @@ pub struct CoroutineClosureSignature<I: Interner> {
372372
/// Always false
373373
pub c_variadic: bool,
374374
/// Always `Normal` (safe)
375+
#[type_visitable(ignore)]
376+
#[type_foldable(identity)]
375377
pub safety: I::Safety,
376378
/// Always `RustCall`
379+
#[type_visitable(ignore)]
380+
#[type_foldable(identity)]
377381
pub abi: I::Abi,
378382
}
379383

Diff for: compiler/rustc_type_ir_macros/src/lib.rs

+72-42
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,73 @@
1-
use quote::quote;
2-
use syn::parse_quote;
1+
use quote::{ToTokens, quote};
32
use syn::visit_mut::VisitMut;
3+
use syn::{Attribute, parse_quote};
44
use synstructure::decl_derive;
55

66
decl_derive!(
7-
[TypeFoldable_Generic] => type_foldable_derive
7+
[TypeVisitable_Generic, attributes(type_visitable)] => type_visitable_derive
88
);
99
decl_derive!(
10-
[TypeVisitable_Generic] => type_visitable_derive
10+
[TypeFoldable_Generic, attributes(type_foldable)] => type_foldable_derive
1111
);
1212
decl_derive!(
1313
[Lift_Generic] => lift_derive
1414
);
1515

16+
fn has_ignore_attr(attrs: &[Attribute], name: &'static str, meta: &'static str) -> bool {
17+
let mut ignored = false;
18+
attrs.iter().for_each(|attr| {
19+
if !attr.path().is_ident(name) {
20+
return;
21+
}
22+
let _ = attr.parse_nested_meta(|nested| {
23+
if nested.path.is_ident(meta) {
24+
ignored = true;
25+
}
26+
Ok(())
27+
});
28+
});
29+
30+
ignored
31+
}
32+
33+
fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
34+
if let syn::Data::Union(_) = s.ast().data {
35+
panic!("cannot derive on union")
36+
}
37+
38+
if !s.ast().generics.type_params().any(|ty| ty.ident == "I") {
39+
s.add_impl_generic(parse_quote! { I });
40+
}
41+
42+
s.filter(|bi| !has_ignore_attr(&bi.ast().attrs, "type_visitable", "ignore"));
43+
44+
s.add_where_predicate(parse_quote! { I: Interner });
45+
s.add_bounds(synstructure::AddBounds::Fields);
46+
let body_visit = s.each(|bind| {
47+
quote! {
48+
match ::rustc_ast_ir::visit::VisitorResult::branch(
49+
::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor)
50+
) {
51+
::core::ops::ControlFlow::Continue(()) => {},
52+
::core::ops::ControlFlow::Break(r) => {
53+
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
54+
},
55+
}
56+
}
57+
});
58+
s.bind_with(|_| synstructure::BindStyle::Move);
59+
60+
s.bound_impl(quote!(::rustc_type_ir::visit::TypeVisitable<I>), quote! {
61+
fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor<I>>(
62+
&self,
63+
__visitor: &mut __V
64+
) -> __V::Result {
65+
match *self { #body_visit }
66+
<__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
67+
}
68+
})
69+
}
70+
1671
fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
1772
if let syn::Data::Union(_) = s.ast().data {
1873
panic!("cannot derive on union")
@@ -29,12 +84,23 @@ fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke
2984
let bindings = vi.bindings();
3085
vi.construct(|_, index| {
3186
let bind = &bindings[index];
32-
quote! {
33-
::rustc_type_ir::fold::TypeFoldable::try_fold_with(#bind, __folder)?
87+
88+
// retain value of fields with #[type_foldable(identity)]
89+
if has_ignore_attr(&bind.ast().attrs, "type_foldable", "identity") {
90+
bind.to_token_stream()
91+
} else {
92+
quote! {
93+
::rustc_type_ir::fold::TypeFoldable::try_fold_with(#bind, __folder)?
94+
}
3495
}
3596
})
3697
});
3798

99+
// We filter fields which get ignored and don't require them to implement
100+
// `TypeFoldable`. We do so after generating `body_fold` as we still need
101+
// to generate code for them.
102+
s.filter(|bi| !has_ignore_attr(&bi.ast().attrs, "type_foldable", "identity"));
103+
s.add_bounds(synstructure::AddBounds::Fields);
38104
s.bound_impl(quote!(::rustc_type_ir::fold::TypeFoldable<I>), quote! {
39105
fn try_fold_with<__F: ::rustc_type_ir::fold::FallibleTypeFolder<I>>(
40106
self,
@@ -113,39 +179,3 @@ fn lift(mut ty: syn::Type) -> syn::Type {
113179

114180
ty
115181
}
116-
117-
fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
118-
if let syn::Data::Union(_) = s.ast().data {
119-
panic!("cannot derive on union")
120-
}
121-
122-
if !s.ast().generics.type_params().any(|ty| ty.ident == "I") {
123-
s.add_impl_generic(parse_quote! { I });
124-
}
125-
126-
s.add_where_predicate(parse_quote! { I: Interner });
127-
s.add_bounds(synstructure::AddBounds::Fields);
128-
let body_visit = s.each(|bind| {
129-
quote! {
130-
match ::rustc_ast_ir::visit::VisitorResult::branch(
131-
::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor)
132-
) {
133-
::core::ops::ControlFlow::Continue(()) => {},
134-
::core::ops::ControlFlow::Break(r) => {
135-
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
136-
},
137-
}
138-
}
139-
});
140-
s.bind_with(|_| synstructure::BindStyle::Move);
141-
142-
s.bound_impl(quote!(::rustc_type_ir::visit::TypeVisitable<I>), quote! {
143-
fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor<I>>(
144-
&self,
145-
__visitor: &mut __V
146-
) -> __V::Result {
147-
match *self { #body_visit }
148-
<__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
149-
}
150-
})
151-
}

0 commit comments

Comments
 (0)