Skip to content

Commit 20bda4e

Browse files
committed
fixes
1 parent 34696fe commit 20bda4e

14 files changed

+374
-45
lines changed

compiler/src/type_check/expressions.rs

+65-25
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,20 @@ impl<'a> CheckConstant<'a> {
12531253
}
12541254
}
12551255

1256+
struct ExpectedClosure<'a> {
1257+
/// The type ID of the closure that is expected.
1258+
id: ClosureId,
1259+
1260+
/// The full type of the expected closure
1261+
value_type: TypeRef,
1262+
1263+
/// The type arguments to expose when resolving types.
1264+
arguments: &'a TypeArguments,
1265+
1266+
/// The type to replace `Self` with.
1267+
self_type: TypeEnum,
1268+
}
1269+
12561270
/// A visitor for type-checking the bodies of methods.
12571271
struct CheckMethodBody<'a> {
12581272
state: &'a mut State,
@@ -1443,16 +1457,22 @@ impl<'a> CheckMethodBody<'a> {
14431457

14441458
fn argument_expression(
14451459
&mut self,
1446-
expected_type: TypeRef,
14471460
node: &mut hir::Expression,
1448-
scope: &mut LexicalScope,
1461+
receiver_type: TypeEnum,
1462+
expected_type: TypeRef,
14491463
type_arguments: &TypeArguments,
1464+
scope: &mut LexicalScope,
14501465
) -> TypeRef {
14511466
match node {
14521467
hir::Expression::Closure(ref mut n) => {
1453-
let expected = expected_type
1454-
.closure_id(self.db())
1455-
.map(|f| (f, expected_type, type_arguments));
1468+
let expected = expected_type.closure_id(self.db()).map(|id| {
1469+
ExpectedClosure {
1470+
id,
1471+
value_type: expected_type,
1472+
arguments: type_arguments,
1473+
self_type: receiver_type,
1474+
}
1475+
});
14561476

14571477
self.closure(n, expected, scope)
14581478
}
@@ -2322,14 +2342,12 @@ impl<'a> CheckMethodBody<'a> {
23222342
fn closure(
23232343
&mut self,
23242344
node: &mut hir::Closure,
2325-
mut expected: Option<(ClosureId, TypeRef, &TypeArguments)>,
2345+
mut expected: Option<ExpectedClosure>,
23262346
scope: &mut LexicalScope,
23272347
) -> TypeRef {
23282348
let self_type = self.self_type;
23292349
let moving = node.moving
2330-
|| expected
2331-
.as_ref()
2332-
.map_or(false, |(id, _, _)| id.is_moving(self.db()));
2350+
|| expected.as_ref().map_or(false, |e| e.id.is_moving(self.db()));
23332351

23342352
let closure = Closure::alloc(self.db_mut(), moving);
23352353
let bounds = self.bounds;
@@ -2340,10 +2358,12 @@ impl<'a> CheckMethodBody<'a> {
23402358

23412359
expected
23422360
.as_mut()
2343-
.map(|(id, _, targs)| {
2344-
let raw = id.return_type(db);
2361+
.map(|e| {
2362+
let raw = e.id.return_type(db);
23452363

2346-
TypeResolver::new(db, targs, bounds).resolve(raw)
2364+
TypeResolver::new(db, e.arguments, bounds)
2365+
.with_self_type(e.self_type)
2366+
.resolve(raw)
23472367
})
23482368
.unwrap_or_else(|| TypeRef::placeholder(db, None))
23492369
};
@@ -2367,7 +2387,7 @@ impl<'a> CheckMethodBody<'a> {
23672387
break_in_loop: Cell::new(false),
23682388
};
23692389

2370-
for (index, arg) in node.arguments.iter_mut().enumerate() {
2390+
for (idx, arg) in node.arguments.iter_mut().enumerate() {
23712391
let name = arg.name.name.clone();
23722392
let typ = if let Some(n) = arg.value_type.as_mut() {
23732393
self.type_signature(n, self.self_type)
@@ -2376,9 +2396,11 @@ impl<'a> CheckMethodBody<'a> {
23762396

23772397
expected
23782398
.as_mut()
2379-
.and_then(|(id, _, targs)| {
2380-
id.positional_argument_input_type(db, index).map(|t| {
2381-
TypeResolver::new(db, targs, bounds).resolve(t)
2399+
.and_then(|e| {
2400+
e.id.positional_argument_input_type(db, idx).map(|t| {
2401+
TypeResolver::new(db, e.arguments, bounds)
2402+
.with_self_type(e.self_type)
2403+
.resolve(t)
23822404
})
23832405
})
23842406
.unwrap_or_else(|| TypeRef::placeholder(db, None))
@@ -2410,8 +2432,8 @@ impl<'a> CheckMethodBody<'a> {
24102432
//
24112433
// `fn move` closures are not inferred as `uni fn`, as the values
24122434
// moved into the closure may still be referred to from elsewhere.
2413-
Some((_, exp, _))
2414-
if exp.is_uni_value(self.db())
2435+
Some(exp)
2436+
if exp.value_type.is_uni_value(self.db())
24152437
&& closure.can_infer_as_uni(self.db()) =>
24162438
{
24172439
TypeRef::Uni(TypeEnum::Closure(closure))
@@ -3542,8 +3564,15 @@ impl<'a> CheckMethodBody<'a> {
35423564
}
35433565
};
35443566

3567+
let rec = receiver.as_type_enum(self.db()).unwrap();
35453568
let given = self
3546-
.argument_expression(exp, &mut pos_node.value, scope, &targs)
3569+
.argument_expression(
3570+
&mut pos_node.value,
3571+
rec,
3572+
exp,
3573+
&targs,
3574+
scope,
3575+
)
35473576
.cast_according_to(self.db(), exp);
35483577

35493578
if !TypeChecker::check(self.db(), given, exp) {
@@ -4326,10 +4355,11 @@ impl<'a> CheckMethodBody<'a> {
43264355
call.method.positional_argument_input_type(self.db(), index)
43274356
{
43284357
let given = self.argument_expression(
4329-
expected,
43304358
node,
4331-
scope,
4359+
call.receiver.as_type_enum(self.db()).unwrap(),
4360+
expected,
43324361
&call.type_arguments,
4362+
scope,
43334363
);
43344364

43354365
call.check_argument(self.state, given, expected, node.location())
@@ -4354,10 +4384,11 @@ impl<'a> CheckMethodBody<'a> {
43544384
node.index = index;
43554385

43564386
let given = self.argument_expression(
4357-
expected,
43584387
&mut node.value,
4359-
scope,
4388+
call.receiver.as_type_enum(self.db()).unwrap(),
4389+
expected,
43604390
&call.type_arguments,
4391+
scope,
43614392
);
43624393

43634394
if call.named_arguments.contains(name) {
@@ -4436,8 +4467,17 @@ impl<'a> CheckMethodBody<'a> {
44364467
node: &mut hir::Type,
44374468
self_type: TypeEnum,
44384469
) -> TypeRef {
4439-
let rules =
4440-
Rules { type_parameters_as_rigid: true, ..Default::default() };
4470+
// Within the bodies of static and module methods, the meaning of `Self`
4471+
// is either unclear or there simply is no type to replace it with.
4472+
let allow_self = matches!(
4473+
self_type,
4474+
TypeEnum::TypeInstance(_) | TypeEnum::TraitInstance(_)
4475+
);
4476+
let rules = Rules {
4477+
type_parameters_as_rigid: true,
4478+
allow_self,
4479+
..Default::default()
4480+
};
44414481
let type_scope = TypeScope::with_bounds(
44424482
self.module,
44434483
self_type,

compiler/src/type_check/methods.rs

+46-14
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,9 @@ impl<'a> DefineMethods<'a> {
587587
let scope = TypeScope::new(self.module, self_type, Some(method));
588588
let rules = Rules {
589589
allow_private_types: method.is_private(self.db()),
590+
// `Self` isn't allowed in module methods because there's no
591+
// meaningful type to replace it with.
592+
allow_self: false,
590593
..Default::default()
591594
};
592595

@@ -641,7 +644,7 @@ impl<'a> DefineMethods<'a> {
641644
) {
642645
let receiver = TypeRef::Owned(TypeEnum::Type(type_id));
643646
let bounds = TypeBounds::new();
644-
let self_type = TypeEnum::TypeInstance(TypeInstance::rigid(
647+
let self_type = TypeEnum::TypeInstance(TypeInstance::for_self_type(
645648
self.db_mut(),
646649
type_id,
647650
&bounds,
@@ -676,10 +679,16 @@ impl<'a> DefineMethods<'a> {
676679
);
677680
self.define_type_parameter_requirements(
678681
&mut node.type_parameters,
679-
rules,
682+
rules.without_self_type(),
680683
&scope,
681684
);
682-
self.define_arguments(&mut node.arguments, method, rules, &scope);
685+
self.define_arguments(
686+
&mut node.arguments,
687+
method,
688+
rules.without_self_type(),
689+
&scope,
690+
);
691+
// Return types _are_ allowed to use `Self`.
683692
self.define_return_type(
684693
node.return_type.as_mut(),
685694
method,
@@ -766,15 +775,20 @@ impl<'a> DefineMethods<'a> {
766775
|| method.is_private(self.db()),
767776
..Default::default()
768777
};
769-
let self_type = TypeEnum::TypeInstance(TypeInstance::rigid(
778+
let rec_type = TypeEnum::TypeInstance(TypeInstance::rigid(
770779
self.db_mut(),
771780
type_id,
772781
&bounds,
773782
));
774-
let receiver = receiver_type(self.db(), self_type, node.kind);
783+
let receiver = receiver_type(self.db(), rec_type, node.kind);
775784

776785
method.set_receiver(self.db_mut(), receiver);
777786

787+
let self_type = TypeEnum::TypeInstance(TypeInstance::for_self_type(
788+
self.db_mut(),
789+
type_id,
790+
&bounds,
791+
));
778792
let scope = TypeScope::with_bounds(
779793
self.module,
780794
self_type,
@@ -851,20 +865,25 @@ impl<'a> DefineMethods<'a> {
851865
..Default::default()
852866
};
853867
let bounds = TypeBounds::new();
854-
let self_type = TypeEnum::TypeInstance(TypeInstance::rigid(
868+
let rec_type = TypeEnum::TypeInstance(TypeInstance::rigid(
855869
self.db_mut(),
856870
type_id,
857871
&bounds,
858872
));
859873
let receiver = if node.mutable {
860-
TypeRef::Mut(self_type)
874+
TypeRef::Mut(rec_type)
861875
} else {
862-
TypeRef::Ref(self_type)
876+
TypeRef::Ref(rec_type)
863877
};
864878

865879
method.set_receiver(self.db_mut(), receiver);
866880
method.set_return_type(self.db_mut(), TypeRef::nil());
867881

882+
let self_type = TypeEnum::TypeInstance(TypeInstance::for_self_type(
883+
self.db_mut(),
884+
type_id,
885+
&bounds,
886+
));
868887
let scope = TypeScope::with_bounds(
869888
self.module,
870889
self_type,
@@ -925,13 +944,18 @@ impl<'a> DefineMethods<'a> {
925944
..Default::default()
926945
};
927946
let bounds = TypeBounds::new();
928-
let ins = TraitInstance::rigid(self.db_mut(), trait_id, &bounds)
947+
let rec_ins = TraitInstance::rigid(self.db_mut(), trait_id, &bounds)
929948
.as_self_type();
930-
let self_type = TypeEnum::TraitInstance(ins);
931-
let receiver = receiver_type(self.db(), self_type, node.kind);
949+
let rec_type = TypeEnum::TraitInstance(rec_ins);
950+
let receiver = receiver_type(self.db(), rec_type, node.kind);
932951

933952
method.set_receiver(self.db_mut(), receiver);
934953

954+
let self_type = TypeEnum::TraitInstance(TraitInstance::for_self_type(
955+
self.db_mut(),
956+
trait_id,
957+
&bounds,
958+
));
935959
let scope = TypeScope::with_bounds(
936960
self.module,
937961
self_type,
@@ -996,13 +1020,21 @@ impl<'a> DefineMethods<'a> {
9961020
..Default::default()
9971021
};
9981022
let bounds = TypeBounds::new();
999-
let ins = TraitInstance::rigid(self.db_mut(), trait_id, &bounds)
1023+
let rec_ins = TraitInstance::rigid(self.db_mut(), trait_id, &bounds)
10001024
.as_self_type();
1001-
let self_type = TypeEnum::TraitInstance(ins);
1002-
let receiver = receiver_type(self.db(), self_type, node.kind);
1025+
let receiver = receiver_type(
1026+
self.db(),
1027+
TypeEnum::TraitInstance(rec_ins),
1028+
node.kind,
1029+
);
10031030

10041031
method.set_receiver(self.db_mut(), receiver);
10051032

1033+
let self_type = TypeEnum::TraitInstance(TraitInstance::for_self_type(
1034+
self.db_mut(),
1035+
trait_id,
1036+
&bounds,
1037+
));
10061038
let scope = TypeScope::with_bounds(
10071039
self.module,
10081040
self_type,

compiler/src/type_check/mod.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,27 @@ pub(crate) struct Rules {
117117
/// If references are allowed.
118118
pub(crate) allow_refs: bool,
119119

120-
/// If the "Never" type can be used.
120+
/// If the `Never` type can be used.
121121
pub(crate) allow_never: bool,
122122

123-
/// If upon encountering a "Self" type we should flag the surrounding trait
123+
/// If upon encountering a `Self` type we should flag the surrounding trait
124124
/// as not allowing casts.
125125
pub(crate) mark_trait_for_self: bool,
126+
127+
/// If the `Self` type can be used.
128+
pub(crate) allow_self: bool,
126129
}
127130

128131
impl Rules {
129132
pub(crate) fn with_never(mut self) -> Rules {
130133
self.allow_never = true;
131134
self
132135
}
136+
137+
pub(crate) fn without_self_type(mut self) -> Rules {
138+
self.allow_self = false;
139+
self
140+
}
133141
}
134142

135143
impl Default for Rules {
@@ -140,6 +148,7 @@ impl Default for Rules {
140148
allow_refs: true,
141149
allow_never: false,
142150
mark_trait_for_self: false,
151+
allow_self: true,
143152
}
144153
}
145154
}
@@ -327,7 +336,7 @@ impl<'a> DefineTypeSignature<'a> {
327336
"Never" if !self.rules.allow_never => {
328337
self.state.diagnostics.error(
329338
DiagnosticId::InvalidType,
330-
"The 'Never' type can't be used in this context",
339+
"the 'Never' type can't be used in this context",
331340
self.file(),
332341
node.location,
333342
);
@@ -349,6 +358,17 @@ impl<'a> DefineTypeSignature<'a> {
349358
}
350359
}
351360
"Self" => {
361+
if !self.rules.allow_self {
362+
self.state.diagnostics.error(
363+
DiagnosticId::InvalidType,
364+
"the 'Self' type can't be used in this context",
365+
self.file(),
366+
node.location,
367+
);
368+
369+
return TypeRef::Error;
370+
}
371+
352372
if self.rules.mark_trait_for_self {
353373
if let TypeEnum::TraitInstance(i) = self.scope.self_type
354374
{

0 commit comments

Comments
 (0)