Skip to content

Commit b4d7ea0

Browse files
committed
Auto merge of #13994 - Veykril:incoherent-impl, r=Veykril
lint incoherent inherent impls
2 parents c15335c + 510e4b4 commit b4d7ea0

File tree

19 files changed

+305
-73
lines changed

19 files changed

+305
-73
lines changed

crates/hir-def/src/adt.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub struct StructData {
4040
pub repr: Option<ReprOptions>,
4141
pub visibility: RawVisibility,
4242
pub rustc_has_incoherent_inherent_impls: bool,
43+
pub fundamental: bool,
4344
}
4445

4546
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -173,10 +174,10 @@ impl StructData {
173174
let item_tree = loc.id.item_tree(db);
174175
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
175176
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
176-
let rustc_has_incoherent_inherent_impls = item_tree
177-
.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into())
178-
.by_key("rustc_has_incoherent_inherent_impls")
179-
.exists();
177+
let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
178+
let rustc_has_incoherent_inherent_impls =
179+
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
180+
let fundamental = attrs.by_key("fundamental").exists();
180181

181182
let strukt = &item_tree[loc.id.value];
182183
let (variant_data, diagnostics) = lower_fields(
@@ -196,6 +197,7 @@ impl StructData {
196197
repr,
197198
visibility: item_tree[strukt.visibility].clone(),
198199
rustc_has_incoherent_inherent_impls,
200+
fundamental,
199201
}),
200202
diagnostics.into(),
201203
)
@@ -215,10 +217,10 @@ impl StructData {
215217
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
216218
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
217219

218-
let rustc_has_incoherent_inherent_impls = item_tree
219-
.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into())
220-
.by_key("rustc_has_incoherent_inherent_impls")
221-
.exists();
220+
let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
221+
let rustc_has_incoherent_inherent_impls =
222+
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
223+
let fundamental = attrs.by_key("fundamental").exists();
222224

223225
let union = &item_tree[loc.id.value];
224226
let (variant_data, diagnostics) = lower_fields(
@@ -238,6 +240,7 @@ impl StructData {
238240
repr,
239241
visibility: item_tree[union.visibility].clone(),
240242
rustc_has_incoherent_inherent_impls,
243+
fundamental,
241244
}),
242245
diagnostics.into(),
243246
)

crates/hir-def/src/data.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub struct FunctionData {
3535
pub visibility: RawVisibility,
3636
pub abi: Option<Interned<str>>,
3737
pub legacy_const_generics_indices: Box<[u32]>,
38+
pub rustc_allow_incoherent_impl: bool,
3839
flags: FnFlags,
3940
}
4041

@@ -84,13 +85,14 @@ impl FunctionData {
8485
}
8586
}
8687

87-
let legacy_const_generics_indices = item_tree
88-
.attrs(db, krate, ModItem::from(loc.id.value).into())
88+
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
89+
let legacy_const_generics_indices = attrs
8990
.by_key("rustc_legacy_const_generics")
9091
.tt_values()
9192
.next()
9293
.map(parse_rustc_legacy_const_generics)
9394
.unwrap_or_default();
95+
let rustc_allow_incoherent_impl = attrs.by_key("rustc_allow_incoherent_impl").exists();
9496

9597
Arc::new(FunctionData {
9698
name: func.name.clone(),
@@ -108,6 +110,7 @@ impl FunctionData {
108110
abi: func.abi.clone(),
109111
legacy_const_generics_indices,
110112
flags,
113+
rustc_allow_incoherent_impl,
111114
})
112115
}
113116

@@ -171,6 +174,7 @@ pub struct TypeAliasData {
171174
pub visibility: RawVisibility,
172175
pub is_extern: bool,
173176
pub rustc_has_incoherent_inherent_impls: bool,
177+
pub rustc_allow_incoherent_impl: bool,
174178
/// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl).
175179
pub bounds: Vec<Interned<TypeBound>>,
176180
}
@@ -189,17 +193,22 @@ impl TypeAliasData {
189193
item_tree[typ.visibility].clone()
190194
};
191195

192-
let rustc_has_incoherent_inherent_impls = item_tree
193-
.attrs(db, loc.container.module(db).krate(), ModItem::from(loc.id.value).into())
194-
.by_key("rustc_has_incoherent_inherent_impls")
195-
.exists();
196+
let attrs = item_tree.attrs(
197+
db,
198+
loc.container.module(db).krate(),
199+
ModItem::from(loc.id.value).into(),
200+
);
201+
let rustc_has_incoherent_inherent_impls =
202+
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
203+
let rustc_allow_incoherent_impl = attrs.by_key("rustc_allow_incoherent_impl").exists();
196204

197205
Arc::new(TypeAliasData {
198206
name: typ.name.clone(),
199207
type_ref: typ.type_ref.clone(),
200208
visibility,
201209
is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
202210
rustc_has_incoherent_inherent_impls,
211+
rustc_allow_incoherent_impl,
203212
bounds: typ.bounds.to_vec(),
204213
})
205214
}
@@ -212,11 +221,12 @@ pub struct TraitData {
212221
pub is_auto: bool,
213222
pub is_unsafe: bool,
214223
pub rustc_has_incoherent_inherent_impls: bool,
224+
pub skip_array_during_method_dispatch: bool,
225+
pub fundamental: bool,
215226
pub visibility: RawVisibility,
216227
/// Whether the trait has `#[rust_skip_array_during_method_dispatch]`. `hir_ty` will ignore
217228
/// method calls to this trait's methods when the receiver is an array and the crate edition is
218229
/// 2015 or 2018.
219-
pub skip_array_during_method_dispatch: bool,
220230
// box it as the vec is usually empty anyways
221231
pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
222232
}
@@ -245,6 +255,7 @@ impl TraitData {
245255
attrs.by_key("rustc_skip_array_during_method_dispatch").exists();
246256
let rustc_has_incoherent_inherent_impls =
247257
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
258+
let fundamental = attrs.by_key("fundamental").exists();
248259
let mut collector =
249260
AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr));
250261
collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items);
@@ -260,6 +271,7 @@ impl TraitData {
260271
visibility,
261272
skip_array_during_method_dispatch,
262273
rustc_has_incoherent_inherent_impls,
274+
fundamental,
263275
}),
264276
diagnostics.into(),
265277
)
@@ -450,6 +462,7 @@ pub struct ConstData {
450462
pub name: Option<Name>,
451463
pub type_ref: Interned<TypeRef>,
452464
pub visibility: RawVisibility,
465+
pub rustc_allow_incoherent_impl: bool,
453466
}
454467

455468
impl ConstData {
@@ -463,10 +476,16 @@ impl ConstData {
463476
item_tree[konst.visibility].clone()
464477
};
465478

479+
let rustc_allow_incoherent_impl = item_tree
480+
.attrs(db, loc.container.module(db).krate(), ModItem::from(loc.id.value).into())
481+
.by_key("rustc_allow_incoherent_impl")
482+
.exists();
483+
466484
Arc::new(ConstData {
467485
name: konst.name.clone(),
468486
type_ref: konst.type_ref.clone(),
469487
visibility,
488+
rustc_allow_incoherent_impl,
470489
})
471490
}
472491
}

crates/hir-def/src/nameres.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ pub struct DefMap {
120120
registered_tools: Vec<SmolStr>,
121121
/// Unstable features of Rust enabled with `#![feature(A, B)]`.
122122
unstable_features: FxHashSet<SmolStr>,
123+
/// #[rustc_coherence_is_core]
124+
rustc_coherence_is_core: bool,
123125

124126
edition: Edition,
125127
recursion_limit: Option<u32>,
@@ -292,6 +294,7 @@ impl DefMap {
292294
registered_tools: Vec::new(),
293295
unstable_features: FxHashSet::default(),
294296
diagnostics: Vec::new(),
297+
rustc_coherence_is_core: false,
295298
}
296299
}
297300

@@ -325,6 +328,10 @@ impl DefMap {
325328
self.unstable_features.contains(feature)
326329
}
327330

331+
pub fn is_rustc_coherence_is_core(&self) -> bool {
332+
self.rustc_coherence_is_core
333+
}
334+
328335
pub fn root(&self) -> LocalModuleId {
329336
self.root
330337
}
@@ -337,7 +344,7 @@ impl DefMap {
337344
self.proc_macro_loading_error.as_deref()
338345
}
339346

340-
pub(crate) fn krate(&self) -> CrateId {
347+
pub fn krate(&self) -> CrateId {
341348
self.krate
342349
}
343350

@@ -502,6 +509,7 @@ impl DefMap {
502509
krate: _,
503510
prelude: _,
504511
root: _,
512+
rustc_coherence_is_core: _,
505513
} = self;
506514

507515
extern_prelude.shrink_to_fit();

crates/hir-def/src/nameres/collector.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ impl DefCollector<'_> {
296296
continue;
297297
}
298298

299+
if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") {
300+
self.def_map.rustc_coherence_is_core = true;
301+
continue;
302+
}
303+
299304
if *attr_name == hir_expand::name![feature] {
300305
let features =
301306
attr.parse_path_comma_token_tree().into_iter().flatten().filter_map(

crates/hir-ty/src/chalk_ext.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir_def::{
1212
use crate::{
1313
db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
1414
from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders,
15-
CallableDefId, CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy,
15+
CallableDefId, CallableSig, DynTy, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy,
1616
QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, WhereClause,
1717
};
1818

@@ -378,6 +378,19 @@ impl ProjectionTyExt for ProjectionTy {
378378
}
379379
}
380380

381+
pub trait DynTyExt {
382+
fn principal(&self) -> Option<&TraitRef>;
383+
}
384+
385+
impl DynTyExt for DynTy {
386+
fn principal(&self) -> Option<&TraitRef> {
387+
self.bounds.skip_binders().interned().get(0).and_then(|b| match b.skip_binders() {
388+
crate::WhereClause::Implemented(trait_ref) => Some(trait_ref),
389+
_ => None,
390+
})
391+
}
392+
}
393+
381394
pub trait TraitRefExt {
382395
fn hir_trait_id(&self) -> TraitId;
383396
}

crates/hir-ty/src/diagnostics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,9 @@ pub use crate::diagnostics::{
1111
},
1212
unsafe_check::{missing_unsafe, unsafe_expressions, UnsafeExpr},
1313
};
14+
15+
#[derive(Debug, PartialEq, Eq)]
16+
pub struct IncoherentImpl {
17+
pub file_id: hir_expand::HirFileId,
18+
pub impl_: syntax::AstPtr<syntax::ast::Impl>,
19+
}

0 commit comments

Comments
 (0)