Skip to content

Commit 2b10891

Browse files
authored
Rollup merge of #103833 - lnicola:rust-analyzer-2022-11-01, r=lnicola
⬆️ rust-analyzer r? `@ghost`
2 parents 2b0ead3 + 0b3e75e commit 2b10891

40 files changed

+824
-404
lines changed

Diff for: src/tools/rust-analyzer/Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -872,9 +872,9 @@ dependencies = [
872872

873873
[[package]]
874874
name = "lsp-types"
875-
version = "0.93.1"
875+
version = "0.93.2"
876876
source = "registry+https://github.com/rust-lang/crates.io-index"
877-
checksum = "a3bcfee315dde785ba887edb540b08765fd7df75a7d948844be6bf5712246734"
877+
checksum = "9be6e9c7e2d18f651974370d7aff703f9513e0df6e464fd795660edc77e6ca51"
878878
dependencies = [
879879
"bitflags",
880880
"serde",

Diff for: src/tools/rust-analyzer/crates/flycheck/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,9 @@ impl FlycheckActor {
295295
} => {
296296
let mut cmd = Command::new(toolchain::cargo());
297297
cmd.arg(command);
298-
cmd.args(&["--workspace", "--message-format=json"]);
298+
cmd.current_dir(&self.root);
299+
cmd.args(&["--workspace", "--message-format=json", "--manifest-path"])
300+
.arg(self.root.join("Cargo.toml").as_os_str());
299301

300302
if let Some(target) = target_triple {
301303
cmd.args(&["--target", target.as_str()]);

Diff for: src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,12 @@ fn desugar_future_path(orig: TypeRef) -> Path {
662662
let mut generic_args: Vec<_> =
663663
std::iter::repeat(None).take(path.segments().len() - 1).collect();
664664
let mut last = GenericArgs::empty();
665-
let binding =
666-
AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() };
665+
let binding = AssociatedTypeBinding {
666+
name: name![Output],
667+
args: None,
668+
type_ref: Some(orig),
669+
bounds: Vec::new(),
670+
};
667671
last.bindings.push(binding);
668672
generic_args.push(Some(Interned::new(last)));
669673

Diff for: src/tools/rust-analyzer/crates/hir-def/src/path.rs

+3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ pub struct GenericArgs {
6868
pub struct AssociatedTypeBinding {
6969
/// The name of the associated type.
7070
pub name: Name,
71+
/// The generic arguments to the associated type. e.g. For `Trait<Assoc<'a, T> = &'a T>`, this
72+
/// would be `['a, T]`.
73+
pub args: Option<Interned<GenericArgs>>,
7174
/// The type bound to this associated type (in `Item = T`, this would be the
7275
/// `T`). This can be `None` if there are bounds instead.
7376
pub type_ref: Option<TypeRef>,

Diff for: src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ pub(super) fn lower_generic_args(
163163
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
164164
if let Some(name_ref) = assoc_type_arg.name_ref() {
165165
let name = name_ref.as_name();
166+
let args = assoc_type_arg
167+
.generic_arg_list()
168+
.and_then(|args| lower_generic_args(lower_ctx, args))
169+
.map(Interned::new);
166170
let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
167171
let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
168172
l.bounds()
@@ -171,7 +175,7 @@ pub(super) fn lower_generic_args(
171175
} else {
172176
Vec::new()
173177
};
174-
bindings.push(AssociatedTypeBinding { name, type_ref, bounds });
178+
bindings.push(AssociatedTypeBinding { name, args, type_ref, bounds });
175179
}
176180
}
177181
ast::GenericArg::LifetimeArg(lifetime_arg) => {
@@ -214,6 +218,7 @@ fn lower_generic_args_from_fn_path(
214218
let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
215219
bindings.push(AssociatedTypeBinding {
216220
name: name![Output],
221+
args: None,
217222
type_ref: Some(type_ref),
218223
bounds: Vec::new(),
219224
});
@@ -222,6 +227,7 @@ fn lower_generic_args_from_fn_path(
222227
let type_ref = TypeRef::Tuple(Vec::new());
223228
bindings.push(AssociatedTypeBinding {
224229
name: name![Output],
230+
args: None,
225231
type_ref: Some(type_ref),
226232
bounds: Vec::new(),
227233
});

Diff for: src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use syntax::SmolStr;
1111

1212
use crate::{
1313
db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
14-
from_placeholder_idx, to_chalk_trait_id, AdtId, AliasEq, AliasTy, Binders, CallableDefId,
15-
CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy, QuantifiedWhereClause,
16-
Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause,
14+
from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders,
15+
CallableDefId, CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy,
16+
QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause,
1717
};
1818

1919
pub trait TyExt {
@@ -338,10 +338,13 @@ pub trait ProjectionTyExt {
338338

339339
impl ProjectionTyExt for ProjectionTy {
340340
fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
341-
TraitRef {
342-
trait_id: to_chalk_trait_id(self.trait_(db)),
343-
substitution: self.substitution.clone(),
344-
}
341+
// FIXME: something like `Split` trait from chalk-solve might be nice.
342+
let generics = generics(db.upcast(), from_assoc_type_id(self.associated_ty_id).into());
343+
let substitution = Substitution::from_iter(
344+
Interner,
345+
self.substitution.iter(Interner).skip(generics.len_self()),
346+
);
347+
TraitRef { trait_id: to_chalk_trait_id(self.trait_(db)), substitution }
345348
}
346349

347350
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {

Diff for: src/tools/rust-analyzer/crates/hir-ty/src/display.rs

+26-10
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,18 @@ impl HirDisplay for ProjectionTy {
289289
return write!(f, "{}", TYPE_HINT_TRUNCATION);
290290
}
291291

292-
let trait_ = f.db.trait_data(self.trait_(f.db));
292+
let trait_ref = self.trait_ref(f.db);
293293
write!(f, "<")?;
294-
self.self_type_parameter(f.db).hir_fmt(f)?;
295-
write!(f, " as {}", trait_.name)?;
296-
if self.substitution.len(Interner) > 1 {
294+
fmt_trait_ref(&trait_ref, f, true)?;
295+
write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
296+
let proj_params_count =
297+
self.substitution.len(Interner) - trait_ref.substitution.len(Interner);
298+
let proj_params = &self.substitution.as_slice(Interner)[..proj_params_count];
299+
if !proj_params.is_empty() {
297300
write!(f, "<")?;
298-
f.write_joined(&self.substitution.as_slice(Interner)[1..], ", ")?;
301+
f.write_joined(proj_params, ", ")?;
299302
write!(f, ">")?;
300303
}
301-
write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
302304
Ok(())
303305
}
304306
}
@@ -641,9 +643,12 @@ impl HirDisplay for Ty {
641643
// Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
642644
if f.display_target.is_test() {
643645
write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
646+
// Note that the generic args for the associated type come before those for the
647+
// trait (including the self type).
648+
// FIXME: reconsider the generic args order upon formatting?
644649
if parameters.len(Interner) > 0 {
645650
write!(f, "<")?;
646-
f.write_joined(&*parameters.as_slice(Interner), ", ")?;
651+
f.write_joined(parameters.as_slice(Interner), ", ")?;
647652
write!(f, ">")?;
648653
}
649654
} else {
@@ -972,9 +977,20 @@ fn write_bounds_like_dyn_trait(
972977
angle_open = true;
973978
}
974979
if let AliasTy::Projection(proj) = alias {
975-
let type_alias =
976-
f.db.type_alias_data(from_assoc_type_id(proj.associated_ty_id));
977-
write!(f, "{} = ", type_alias.name)?;
980+
let assoc_ty_id = from_assoc_type_id(proj.associated_ty_id);
981+
let type_alias = f.db.type_alias_data(assoc_ty_id);
982+
write!(f, "{}", type_alias.name)?;
983+
984+
let proj_arg_count = generics(f.db.upcast(), assoc_ty_id.into()).len_self();
985+
if proj_arg_count > 0 {
986+
write!(f, "<")?;
987+
f.write_joined(
988+
&proj.substitution.as_slice(Interner)[..proj_arg_count],
989+
", ",
990+
)?;
991+
write!(f, ">")?;
992+
}
993+
write!(f, " = ")?;
978994
}
979995
ty.hir_fmt(f)?;
980996
}

Diff for: src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ impl<'a> InferenceContext<'a> {
157157
remaining_segments_for_ty,
158158
true,
159159
);
160-
if let TyKind::Error = ty.kind(Interner) {
160+
if ty.is_unknown() {
161161
return None;
162162
}
163163

Diff for: src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ impl<'a> InferenceTable<'a> {
340340
self.resolve_with_fallback(t, &|_, _, d, _| d)
341341
}
342342

343-
/// Unify two types and register new trait goals that arise from that.
344-
pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
343+
/// Unify two relatable values (e.g. `Ty`) and register new trait goals that arise from that.
344+
pub(crate) fn unify<T: ?Sized + Zip<Interner>>(&mut self, ty1: &T, ty2: &T) -> bool {
345345
let result = match self.try_unify(ty1, ty2) {
346346
Ok(r) => r,
347347
Err(_) => return false,
@@ -350,9 +350,13 @@ impl<'a> InferenceTable<'a> {
350350
true
351351
}
352352

353-
/// Unify two types and return new trait goals arising from it, so the
353+
/// Unify two relatable values (e.g. `Ty`) and return new trait goals arising from it, so the
354354
/// caller needs to deal with them.
355-
pub(crate) fn try_unify<T: Zip<Interner>>(&mut self, t1: &T, t2: &T) -> InferResult<()> {
355+
pub(crate) fn try_unify<T: ?Sized + Zip<Interner>>(
356+
&mut self,
357+
t1: &T,
358+
t2: &T,
359+
) -> InferResult<()> {
356360
match self.var_unification_table.relate(
357361
Interner,
358362
&self.db,

Diff for: src/tools/rust-analyzer/crates/hir-ty/src/lib.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,20 @@ pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
8181
pub type VariableKind = chalk_ir::VariableKind<Interner>;
8282
pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
8383
pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
84+
/// Represents generic parameters and an item bound by them. When the item has parent, the binders
85+
/// also contain the generic parameters for its parent. See chalk's documentation for details.
86+
///
87+
/// One thing to keep in mind when working with `Binders` (and `Substitution`s, which represent
88+
/// generic arguments) in rust-analyzer is that the ordering within *is* significant - the generic
89+
/// parameters/arguments for an item MUST come before those for its parent. This is to facilitate
90+
/// the integration with chalk-solve, which mildly puts constraints as such. See #13335 for its
91+
/// motivation in detail.
8492
pub type Binders<T> = chalk_ir::Binders<T>;
93+
/// Interned list of generic arguments for an item. When an item has parent, the `Substitution` for
94+
/// it contains generic arguments for both its parent and itself. See chalk's documentation for
95+
/// details.
96+
///
97+
/// See `Binders` for the constraint on the ordering.
8598
pub type Substitution = chalk_ir::Substitution<Interner>;
8699
pub type GenericArg = chalk_ir::GenericArg<Interner>;
87100
pub type GenericArgData = chalk_ir::GenericArgData<Interner>;
@@ -124,14 +137,6 @@ pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>;
124137
pub type Guidance = chalk_solve::Guidance<Interner>;
125138
pub type WhereClause = chalk_ir::WhereClause<Interner>;
126139

127-
// FIXME: get rid of this
128-
pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution {
129-
Substitution::from_iter(
130-
Interner,
131-
s.as_slice(Interner)[..std::cmp::min(s.len(Interner), n)].iter().cloned(),
132-
)
133-
}
134-
135140
/// Return an index of a parameter in the generic type parameter list by it's id.
136141
pub fn param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<usize> {
137142
generics(db.upcast(), id.parent).param_idx(id)
@@ -382,7 +387,6 @@ pub(crate) fn fold_tys_and_consts<T: HasInterner<Interner = Interner> + TypeFold
382387
pub fn replace_errors_with_variables<T>(t: &T) -> Canonical<T>
383388
where
384389
T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + Clone,
385-
T: HasInterner<Interner = Interner>,
386390
{
387391
use chalk_ir::{
388392
fold::{FallibleTypeFolder, TypeSuperFoldable},

0 commit comments

Comments
 (0)