Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions crates/hir-def/src/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub struct StructData {
pub repr: Option<ReprOptions>,
pub visibility: RawVisibility,
pub rustc_has_incoherent_inherent_impls: bool,
pub fundamental: bool,
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -173,10 +174,10 @@ impl StructData {
let item_tree = loc.id.item_tree(db);
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
let rustc_has_incoherent_inherent_impls = item_tree
.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into())
.by_key("rustc_has_incoherent_inherent_impls")
.exists();
let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
let rustc_has_incoherent_inherent_impls =
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
let fundamental = attrs.by_key("fundamental").exists();

let strukt = &item_tree[loc.id.value];
let (variant_data, diagnostics) = lower_fields(
Expand All @@ -196,6 +197,7 @@ impl StructData {
repr,
visibility: item_tree[strukt.visibility].clone(),
rustc_has_incoherent_inherent_impls,
fundamental,
}),
diagnostics.into(),
)
Expand All @@ -215,10 +217,10 @@ impl StructData {
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();

let rustc_has_incoherent_inherent_impls = item_tree
.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into())
.by_key("rustc_has_incoherent_inherent_impls")
.exists();
let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
let rustc_has_incoherent_inherent_impls =
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
let fundamental = attrs.by_key("fundamental").exists();

let union = &item_tree[loc.id.value];
let (variant_data, diagnostics) = lower_fields(
Expand All @@ -238,6 +240,7 @@ impl StructData {
repr,
visibility: item_tree[union.visibility].clone(),
rustc_has_incoherent_inherent_impls,
fundamental,
}),
diagnostics.into(),
)
Expand Down
33 changes: 26 additions & 7 deletions crates/hir-def/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct FunctionData {
pub visibility: RawVisibility,
pub abi: Option<Interned<str>>,
pub legacy_const_generics_indices: Box<[u32]>,
pub rustc_allow_incoherent_impl: bool,
flags: FnFlags,
}

Expand Down Expand Up @@ -84,13 +85,14 @@ impl FunctionData {
}
}

let legacy_const_generics_indices = item_tree
.attrs(db, krate, ModItem::from(loc.id.value).into())
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
let legacy_const_generics_indices = attrs
.by_key("rustc_legacy_const_generics")
.tt_values()
.next()
.map(parse_rustc_legacy_const_generics)
.unwrap_or_default();
let rustc_allow_incoherent_impl = attrs.by_key("rustc_allow_incoherent_impl").exists();

Arc::new(FunctionData {
name: func.name.clone(),
Expand All @@ -108,6 +110,7 @@ impl FunctionData {
abi: func.abi.clone(),
legacy_const_generics_indices,
flags,
rustc_allow_incoherent_impl,
})
}

Expand Down Expand Up @@ -171,6 +174,7 @@ pub struct TypeAliasData {
pub visibility: RawVisibility,
pub is_extern: bool,
pub rustc_has_incoherent_inherent_impls: bool,
pub rustc_allow_incoherent_impl: bool,
/// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl).
pub bounds: Vec<Interned<TypeBound>>,
}
Expand All @@ -189,17 +193,22 @@ impl TypeAliasData {
item_tree[typ.visibility].clone()
};

let rustc_has_incoherent_inherent_impls = item_tree
.attrs(db, loc.container.module(db).krate(), ModItem::from(loc.id.value).into())
.by_key("rustc_has_incoherent_inherent_impls")
.exists();
let attrs = item_tree.attrs(
db,
loc.container.module(db).krate(),
ModItem::from(loc.id.value).into(),
);
let rustc_has_incoherent_inherent_impls =
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
let rustc_allow_incoherent_impl = attrs.by_key("rustc_allow_incoherent_impl").exists();

Arc::new(TypeAliasData {
name: typ.name.clone(),
type_ref: typ.type_ref.clone(),
visibility,
is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
rustc_has_incoherent_inherent_impls,
rustc_allow_incoherent_impl,
bounds: typ.bounds.to_vec(),
})
}
Expand All @@ -212,11 +221,12 @@ pub struct TraitData {
pub is_auto: bool,
pub is_unsafe: bool,
pub rustc_has_incoherent_inherent_impls: bool,
pub skip_array_during_method_dispatch: bool,
pub fundamental: bool,
pub visibility: RawVisibility,
/// Whether the trait has `#[rust_skip_array_during_method_dispatch]`. `hir_ty` will ignore
/// method calls to this trait's methods when the receiver is an array and the crate edition is
/// 2015 or 2018.
pub skip_array_during_method_dispatch: bool,
// box it as the vec is usually empty anyways
pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
}
Expand Down Expand Up @@ -245,6 +255,7 @@ impl TraitData {
attrs.by_key("rustc_skip_array_during_method_dispatch").exists();
let rustc_has_incoherent_inherent_impls =
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
let fundamental = attrs.by_key("fundamental").exists();
let mut collector =
AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr));
collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items);
Expand All @@ -260,6 +271,7 @@ impl TraitData {
visibility,
skip_array_during_method_dispatch,
rustc_has_incoherent_inherent_impls,
fundamental,
}),
diagnostics.into(),
)
Expand Down Expand Up @@ -450,6 +462,7 @@ pub struct ConstData {
pub name: Option<Name>,
pub type_ref: Interned<TypeRef>,
pub visibility: RawVisibility,
pub rustc_allow_incoherent_impl: bool,
}

impl ConstData {
Expand All @@ -463,10 +476,16 @@ impl ConstData {
item_tree[konst.visibility].clone()
};

let rustc_allow_incoherent_impl = item_tree
.attrs(db, loc.container.module(db).krate(), ModItem::from(loc.id.value).into())
.by_key("rustc_allow_incoherent_impl")
.exists();

Arc::new(ConstData {
name: konst.name.clone(),
type_ref: konst.type_ref.clone(),
visibility,
rustc_allow_incoherent_impl,
})
}
}
Expand Down
10 changes: 9 additions & 1 deletion crates/hir-def/src/nameres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ pub struct DefMap {
registered_tools: Vec<SmolStr>,
/// Unstable features of Rust enabled with `#![feature(A, B)]`.
unstable_features: FxHashSet<SmolStr>,
/// #[rustc_coherence_is_core]
rustc_coherence_is_core: bool,

edition: Edition,
recursion_limit: Option<u32>,
Expand Down Expand Up @@ -292,6 +294,7 @@ impl DefMap {
registered_tools: Vec::new(),
unstable_features: FxHashSet::default(),
diagnostics: Vec::new(),
rustc_coherence_is_core: false,
}
}

Expand Down Expand Up @@ -325,6 +328,10 @@ impl DefMap {
self.unstable_features.contains(feature)
}

pub fn is_rustc_coherence_is_core(&self) -> bool {
self.rustc_coherence_is_core
}

pub fn root(&self) -> LocalModuleId {
self.root
}
Expand All @@ -337,7 +344,7 @@ impl DefMap {
self.proc_macro_loading_error.as_deref()
}

pub(crate) fn krate(&self) -> CrateId {
pub fn krate(&self) -> CrateId {
self.krate
}

Expand Down Expand Up @@ -502,6 +509,7 @@ impl DefMap {
krate: _,
prelude: _,
root: _,
rustc_coherence_is_core: _,
} = self;

extern_prelude.shrink_to_fit();
Expand Down
5 changes: 5 additions & 0 deletions crates/hir-def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ impl DefCollector<'_> {
continue;
}

if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") {
self.def_map.rustc_coherence_is_core = true;
continue;
}

if *attr_name == hir_expand::name![feature] {
let features =
attr.parse_path_comma_token_tree().into_iter().flatten().filter_map(
Expand Down
15 changes: 14 additions & 1 deletion crates/hir-ty/src/chalk_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use hir_def::{
use crate::{
db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders,
CallableDefId, CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy,
CallableDefId, CallableSig, DynTy, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy,
QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, WhereClause,
};

Expand Down Expand Up @@ -378,6 +378,19 @@ impl ProjectionTyExt for ProjectionTy {
}
}

pub trait DynTyExt {
fn principal(&self) -> Option<&TraitRef>;
}

impl DynTyExt for DynTy {
fn principal(&self) -> Option<&TraitRef> {
self.bounds.skip_binders().interned().get(0).and_then(|b| match b.skip_binders() {
crate::WhereClause::Implemented(trait_ref) => Some(trait_ref),
_ => None,
})
}
}

pub trait TraitRefExt {
fn hir_trait_id(&self) -> TraitId;
}
Expand Down
6 changes: 6 additions & 0 deletions crates/hir-ty/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ pub use crate::diagnostics::{
},
unsafe_check::{missing_unsafe, unsafe_expressions, UnsafeExpr},
};

#[derive(Debug, PartialEq, Eq)]
pub struct IncoherentImpl {
pub file_id: hir_expand::HirFileId,
pub impl_: syntax::AstPtr<syntax::ast::Impl>,
}
Loading