From 367487fe88dca78cffad5138673d5259f7f7ba6b Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 28 May 2020 21:42:22 +0200 Subject: Support raw_ref_op's raw reference operator --- crates/ra_hir_ty/src/infer/expr.rs | 37 +++++++++++++++++++++------------- crates/ra_hir_ty/src/lib.rs | 18 +++++++++++++++-- crates/ra_hir_ty/src/tests/coercion.rs | 17 ++++++++++------ crates/ra_hir_ty/src/tests/simple.rs | 20 ++++++++++++++++++ 4 files changed, 70 insertions(+), 22 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index b28724f0e..54bab3476 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -17,8 +17,8 @@ use crate::{ autoderef, method_resolution, op, traits::InEnvironment, utils::{generics, variant_data, Generics}, - ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, - Ty, TypeCtor, Uncertain, + ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs, + TraitRef, Ty, TypeCtor, Uncertain, }; use super::{ @@ -350,19 +350,28 @@ impl<'a> InferenceContext<'a> { // FIXME check the cast... cast_ty } - Expr::Ref { expr, mutability } => { - let expectation = - if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() { - if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { - // FIXME: throw type error - expected mut reference but found shared ref, - // which cannot be coerced - } - Expectation::rvalue_hint(Ty::clone(exp_inner)) - } else { - Expectation::none() - }; + Expr::Ref { expr, rawness, mutability } => { + let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = + &expected.ty.as_reference_or_ptr() + { + if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { + // FIXME: throw type error - expected mut reference but found shared ref, + // which cannot be coerced + } + if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr { + // FIXME: throw type error - expected reference but found ptr, + // which cannot be coerced + } + Expectation::rvalue_hint(Ty::clone(exp_inner)) + } else { + Expectation::none() + }; let inner_ty = self.infer_expr_inner(*expr, &expectation); - Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) + let ty = match rawness { + Rawness::RawPtr => TypeCtor::RawPtr(*mutability), + Rawness::Ref => TypeCtor::Ref(*mutability), + }; + Ty::apply_one(ty, inner_ty) } Expr::Box { expr } => { let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 93cb45a64..9fa8d3bdc 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -49,8 +49,10 @@ use std::sync::Arc; use std::{iter, mem}; use hir_def::{ - expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, - HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, + expr::ExprId, + type_ref::{Mutability, Rawness}, + AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, + TypeParamId, }; use ra_db::{impl_intern_key, salsa, CrateId}; @@ -709,6 +711,18 @@ impl Ty { } } + pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { + match self { + Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { + Some((parameters.as_single(), Rawness::Ref, *mutability)) + } + Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { + Some((parameters.as_single(), Rawness::RawPtr, *mutability)) + } + _ => None, + } + } + pub fn strip_references(&self) -> &Ty { let mut t: &Ty = self; diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 2cc4f4bf9..6f777ed8c 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -116,15 +116,20 @@ fn infer_let_stmt_coerce() { assert_snapshot!( infer(r#" fn test() { - let x: &[i32] = &[1]; + let x: &[isize] = &[1]; + let x: *const [isize] = &[1]; } "#), @r###" - 11..40 '{ ...[1]; }': () - 21..22 'x': &[i32] - 33..37 '&[1]': &[i32; _] - 34..37 '[1]': [i32; _] - 35..36 '1': i32 + 11..76 '{ ...[1]; }': () + 21..22 'x': &[isize] + 35..39 '&[1]': &[isize; _] + 36..39 '[1]': [isize; _] + 37..38 '1': isize + 49..50 'x': *const [isize] + 69..73 '&[1]': &[isize; _] + 70..73 '[1]': [isize; _] + 71..72 '1': isize "###); } diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index fd2208af2..f1db34160 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -384,6 +384,26 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { ); } +#[test] +fn infer_raw_ref() { + assert_snapshot!( + infer(r#" +fn test(a: i32) { + &raw mut a; + &raw const a; +} +"#), + @r###" + 9..10 'a': i32 + 17..54 '{ ...t a; }': () + 23..33 '&raw mut a': *mut i32 + 32..33 'a': i32 + 39..51 '&raw const a': *const i32 + 50..51 'a': i32 + "### + ); +} + #[test] fn infer_literals() { assert_snapshot!( -- cgit v1.2.3