mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Process second review
This commit is contained in:
parent
f6eb44cd9e
commit
6249989e6c
3 changed files with 35 additions and 44 deletions
|
@ -470,12 +470,12 @@ impl Ty {
|
||||||
}
|
}
|
||||||
// add placeholders for args that were not provided
|
// add placeholders for args that were not provided
|
||||||
// TODO: handle defaults
|
// TODO: handle defaults
|
||||||
for _ in segment
|
let supplied_params = segment
|
||||||
.args_and_bindings
|
.args_and_bindings
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|ga| ga.args.len())
|
.map(|ga| ga.args.len())
|
||||||
.unwrap_or(0)..def_generics.params.len()
|
.unwrap_or(0);
|
||||||
{
|
for _ in supplied_params..def_generics.params.len() {
|
||||||
substs.push(Ty::Unknown);
|
substs.push(Ty::Unknown);
|
||||||
}
|
}
|
||||||
assert_eq!(substs.len(), def_generics.params.len());
|
assert_eq!(substs.len(), def_generics.params.len());
|
||||||
|
@ -507,7 +507,20 @@ impl Ty {
|
||||||
}
|
}
|
||||||
sig_mut.output.walk_mut(f);
|
sig_mut.output.walk_mut(f);
|
||||||
}
|
}
|
||||||
Ty::FnDef { substs, .. } | Ty::Adt { substs, .. } => {
|
Ty::FnDef { substs, sig, .. } => {
|
||||||
|
let sig_mut = Arc::make_mut(sig);
|
||||||
|
for input in &mut sig_mut.input {
|
||||||
|
input.walk_mut(f);
|
||||||
|
}
|
||||||
|
sig_mut.output.walk_mut(f);
|
||||||
|
// Without an Arc::make_mut_slice, we can't avoid the clone here:
|
||||||
|
let mut v: Vec<_> = substs.0.iter().cloned().collect();
|
||||||
|
for t in &mut v {
|
||||||
|
t.walk_mut(f);
|
||||||
|
}
|
||||||
|
substs.0 = v.into();
|
||||||
|
}
|
||||||
|
Ty::Adt { substs, .. } => {
|
||||||
// Without an Arc::make_mut_slice, we can't avoid the clone here:
|
// Without an Arc::make_mut_slice, we can't avoid the clone here:
|
||||||
let mut v: Vec<_> = substs.0.iter().cloned().collect();
|
let mut v: Vec<_> = substs.0.iter().cloned().collect();
|
||||||
for t in &mut v {
|
for t in &mut v {
|
||||||
|
@ -579,7 +592,7 @@ impl Ty {
|
||||||
/// or function); so if `self` is `Option<u32>`, this returns the `u32`.
|
/// or function); so if `self` is `Option<u32>`, this returns the `u32`.
|
||||||
fn substs(&self) -> Option<Substs> {
|
fn substs(&self) -> Option<Substs> {
|
||||||
match self {
|
match self {
|
||||||
Ty::Adt { substs, .. } => Some(substs.clone()),
|
Ty::Adt { substs, .. } | Ty::FnDef { substs, .. } => Some(substs.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -617,9 +630,6 @@ impl fmt::Display for Ty {
|
||||||
Ty::FnDef {
|
Ty::FnDef {
|
||||||
name, substs, sig, ..
|
name, substs, sig, ..
|
||||||
} => {
|
} => {
|
||||||
// don't have access to the param types here :-(
|
|
||||||
// we could store them in the def, but not sure if it
|
|
||||||
// is worth it
|
|
||||||
write!(f, "fn {}", name)?;
|
write!(f, "fn {}", name)?;
|
||||||
if substs.0.len() > 0 {
|
if substs.0.len() > 0 {
|
||||||
join(substs.0.iter())
|
join(substs.0.iter())
|
||||||
|
@ -1156,32 +1166,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
.into();
|
.into();
|
||||||
let typable = typable?;
|
let typable = typable?;
|
||||||
let ty = self.db.type_for_def(typable);
|
let ty = self.db.type_for_def(typable);
|
||||||
let ty = self.insert_type_vars(ty);
|
let generics = GenericParams::default();
|
||||||
|
|
||||||
// try to get generic parameters from the path and add them to the
|
|
||||||
// function type substitutions
|
|
||||||
if let Ty::FnDef { ref def, .. } = ty {
|
|
||||||
let last_seg_bindings = path
|
|
||||||
.segments
|
|
||||||
.last()
|
|
||||||
.and_then(|segment| segment.args_and_bindings.as_ref());
|
|
||||||
if let Some(generic_args) = last_seg_bindings {
|
|
||||||
let generic_params = def.generic_params(self.db);
|
|
||||||
if generic_args.args.len() == generic_params.params.len() {
|
|
||||||
let substs = Ty::substs_from_path(
|
let substs = Ty::substs_from_path(
|
||||||
self.db,
|
self.db,
|
||||||
&self.module,
|
&self.module,
|
||||||
self.impl_block.as_ref(),
|
self.impl_block.as_ref(),
|
||||||
&generic_params,
|
&generics,
|
||||||
path,
|
path,
|
||||||
(*def).into(),
|
typable,
|
||||||
);
|
);
|
||||||
return Some(ty.apply_substs(substs));
|
let ty = ty.apply_substs(substs);
|
||||||
} else {
|
let ty = self.insert_type_vars(ty);
|
||||||
// ERROR: incorrect number of type params
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(ty)
|
Some(ty)
|
||||||
}
|
}
|
||||||
|
@ -1408,8 +1403,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Ty::Unknown
|
Ty::Unknown
|
||||||
}
|
}
|
||||||
Expr::Call { callee, args } => {
|
Expr::Call { callee, args } => {
|
||||||
// TODO: we should use turbofish hints like this:
|
|
||||||
// f::<u32>(x)
|
|
||||||
let callee_ty = self.infer_expr(*callee, &Expectation::none());
|
let callee_ty = self.infer_expr(*callee, &Expectation::none());
|
||||||
let (param_tys, ret_ty) = match &callee_ty {
|
let (param_tys, ret_ty) = match &callee_ty {
|
||||||
Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
|
Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
created: "2019-01-26T18:16:16.568375+00:00"
|
created: "2019-01-27T16:54:18.368427685+00:00"
|
||||||
creator: insta@0.5.2
|
creator: insta@0.5.2
|
||||||
expression: "&result"
|
expression: "&result"
|
||||||
source: crates/ra_hir/src/ty/tests.rs
|
source: crates/ra_hir/src/ty/tests.rs
|
||||||
|
@ -10,7 +10,7 @@ source: crates/ra_hir/src/ty/tests.rs
|
||||||
[44; 45) 'x': &[unknown]
|
[44; 45) 'x': &[unknown]
|
||||||
[56; 65) '{ x }': &[unknown]
|
[56; 65) '{ x }': &[unknown]
|
||||||
[62; 63) 'x': &[unknown]
|
[62; 63) 'x': &[unknown]
|
||||||
[77; 197) '{ ...(1); }': ()
|
[77; 157) '{ ...(1); }': ()
|
||||||
[87; 88) 'y': u32
|
[87; 88) 'y': u32
|
||||||
[91; 96) '10u32': u32
|
[91; 96) '10u32': u32
|
||||||
[102; 104) 'id': fn id<u32>(T) -> T
|
[102; 104) 'id': fn id<u32>(T) -> T
|
||||||
|
@ -20,7 +20,7 @@ source: crates/ra_hir/src/ty/tests.rs
|
||||||
[127; 132) 'clone': fn clone<bool>(&T) -> T
|
[127; 132) 'clone': fn clone<bool>(&T) -> T
|
||||||
[127; 135) 'clone(z)': bool
|
[127; 135) 'clone(z)': bool
|
||||||
[133; 134) 'z': &bool
|
[133; 134) 'z': &bool
|
||||||
[173; 191) 'id::<i...tring>': fn id<i32>(T) -> T
|
[141; 151) 'id::<i128>': fn id<i128>(T) -> T
|
||||||
[173; 194) 'id::<i...ng>(1)': i32
|
[141; 154) 'id::<i128>(1)': i128
|
||||||
[192; 193) '1': i32
|
[152; 153) '1': i128
|
||||||
|
|
|
@ -597,7 +597,7 @@ fn test() {
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_type_param() {
|
fn infer_type_param() {
|
||||||
check_inference(
|
check_inference(
|
||||||
"generic_fn",
|
"infer_type_param",
|
||||||
r#"
|
r#"
|
||||||
fn id<T>(x: T) -> T {
|
fn id<T>(x: T) -> T {
|
||||||
x
|
x
|
||||||
|
@ -611,9 +611,7 @@ fn test() {
|
||||||
let y = 10u32;
|
let y = 10u32;
|
||||||
id(y);
|
id(y);
|
||||||
let x: bool = clone(z);
|
let x: bool = clone(z);
|
||||||
|
id::<i128>(1);
|
||||||
// bad turbofish - ignore!
|
|
||||||
id::<i128, String>(1);
|
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue