mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
Merge #11936
11936: Ignore `Drop` and `Destruct` bounds for now r=flodiebold a=flodiebold - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement. (So ideally, we'd only ignore `~const Drop`, but this should be fine for now.) - `Destruct` impls are built-in in 1.62 (current nightlies), so until the builtin impls are supported by Chalk, we ignore them as well. Since `Destruct` is implemented for everything in non-const contexts IIUC, this should also work fine. Fixes #11932. Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
commit
847c552ab3
2 changed files with 97 additions and 1 deletions
|
@ -14,6 +14,7 @@ use chalk_ir::interner::HasInterner;
|
|||
use chalk_ir::{cast::Cast, fold::Shift, Mutability, Safety};
|
||||
use hir_def::generics::TypeOrConstParamData;
|
||||
use hir_def::intern::Interned;
|
||||
use hir_def::lang_item::lang_attr;
|
||||
use hir_def::path::{ModPath, PathKind};
|
||||
use hir_def::type_ref::ConstScalarOrPath;
|
||||
use hir_def::{
|
||||
|
@ -863,7 +864,23 @@ impl<'a> TyLoweringContext<'a> {
|
|||
let trait_ref = match bound {
|
||||
TypeBound::Path(path, TraitBoundModifier::None) => {
|
||||
bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
|
||||
bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
|
||||
bindings
|
||||
.clone()
|
||||
.filter(|tr| {
|
||||
// ignore `T: Drop` or `T: Destruct` bounds.
|
||||
// - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
|
||||
// (So ideally, we'd only ignore `~const Drop` here)
|
||||
// - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
|
||||
// the builtin impls are supported by Chalk, we ignore them here.
|
||||
if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
|
||||
if lang == "drop" || lang == "destruct" {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
})
|
||||
.map(WhereClause::Implemented)
|
||||
.map(crate::wrap_empty_binders)
|
||||
}
|
||||
TypeBound::Path(path, TraitBoundModifier::Maybe) => {
|
||||
let sized_trait = self
|
||||
|
|
|
@ -1505,3 +1505,82 @@ fn f(s: S) {
|
|||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rust_161_option_clone() {
|
||||
check_types(
|
||||
r#"
|
||||
//- minicore: option, drop
|
||||
|
||||
fn test(o: &Option<i32>) {
|
||||
o.my_clone();
|
||||
//^^^^^^^^^^^^ Option<i32>
|
||||
}
|
||||
|
||||
pub trait MyClone: Sized {
|
||||
fn my_clone(&self) -> Self;
|
||||
}
|
||||
|
||||
impl<T> const MyClone for Option<T>
|
||||
where
|
||||
T: ~const MyClone + ~const Drop + ~const Destruct,
|
||||
{
|
||||
fn my_clone(&self) -> Self {
|
||||
match self {
|
||||
Some(x) => Some(x.my_clone()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl const MyClone for i32 {
|
||||
fn my_clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Destruct {}
|
||||
|
||||
impl<T: ?Sized> const Destruct for T {}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rust_162_option_clone() {
|
||||
check_types(
|
||||
r#"
|
||||
//- minicore: option, drop
|
||||
|
||||
fn test(o: &Option<i32>) {
|
||||
o.my_clone();
|
||||
//^^^^^^^^^^^^ Option<i32>
|
||||
}
|
||||
|
||||
pub trait MyClone: Sized {
|
||||
fn my_clone(&self) -> Self;
|
||||
}
|
||||
|
||||
impl<T> const MyClone for Option<T>
|
||||
where
|
||||
T: ~const MyClone + ~const Destruct,
|
||||
{
|
||||
fn my_clone(&self) -> Self {
|
||||
match self {
|
||||
Some(x) => Some(x.my_clone()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl const MyClone for i32 {
|
||||
fn my_clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "destruct"]
|
||||
pub trait Destruct {}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue