From 5f2486e9a84f0850e6e9f57e590693926f85eb43 Mon Sep 17 00:00:00 2001 From: Dawer <7803845+iDawer@users.noreply.github.com> Date: Tue, 15 Jun 2021 23:28:37 +0500 Subject: [PATCH] Handle `impl ?Sized`. Fix tests. --- crates/hir/src/display.rs | 3 +- crates/hir_ty/src/display.rs | 54 +- .../hir_ty/src/tests/display_source_code.rs | 22 +- crates/hir_ty/src/tests/method_resolution.rs | 41 +- crates/hir_ty/src/tests/traits.rs | 562 +++++++++--------- 5 files changed, 352 insertions(+), 330 deletions(-) diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index df9094ac82de..dff4372738b7 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -239,7 +239,8 @@ impl HirDisplay for TypeParam { let predicates = bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect::>(); if !(predicates.is_empty() || f.omit_verbose_types()) { - write_bounds_like_dyn_trait_with_prefix(":", &predicates, SizedByDefault::Sized, f)?; + let default_sized = SizedByDefault::Sized { anchor: self.module(f.db).krate().id }; + write_bounds_like_dyn_trait_with_prefix(":", &predicates, default_sized, f)?; } Ok(()) } diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index df7cf1c39c41..6a8fd2dd4d9a 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -4,6 +4,7 @@ use std::fmt::{self, Debug}; +use base_db::CrateId; use chalk_ir::BoundVar; use hir_def::{ body, @@ -15,7 +16,7 @@ use hir_def::{ path::{Path, PathKind}, type_ref::{TraitBoundModifier, TypeBound, TypeRef}, visibility::Visibility, - AssocContainerId, Lookup, ModuleId, TraitId, + AssocContainerId, HasModule, Lookup, ModuleId, TraitId, }; use hir_expand::{hygiene::Hygiene, name::Name}; use itertools::Itertools; @@ -582,10 +583,11 @@ impl HirDisplay for Ty { .as_ref() .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); let bounds = data.substitute(&Interner, ¶meters); + let krate = func.lookup(f.db.upcast()).module(f.db.upcast()).krate(); write_bounds_like_dyn_trait_with_prefix( "impl", bounds.skip_binders(), - SizedByDefault::Sized, + SizedByDefault::Sized { anchor: krate }, f, )?; // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution @@ -646,10 +648,11 @@ impl HirDisplay for Ty { _ => false, }) .collect::>(); + let krate = id.parent.module(f.db.upcast()).krate(); write_bounds_like_dyn_trait_with_prefix( "impl", &bounds, - SizedByDefault::Sized, + SizedByDefault::Sized { anchor: krate }, f, )?; } @@ -675,10 +678,11 @@ impl HirDisplay for Ty { .as_ref() .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); let bounds = data.substitute(&Interner, &opaque_ty.substitution); + let krate = func.lookup(f.db.upcast()).module(f.db.upcast()).krate(); write_bounds_like_dyn_trait_with_prefix( "impl", bounds.skip_binders(), - SizedByDefault::Sized, + SizedByDefault::Sized { anchor: krate }, f, )?; } @@ -729,17 +733,23 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator Option { - let krate = trait_.lookup(db).container.krate(); - let sized_trait = - db.lang_item(krate, "sized".into()).and_then(|lang_item| lang_item.as_trait())?; - Some(trait_ == sized_trait) -} - #[derive(Clone, Copy, PartialEq, Eq)] pub enum SizedByDefault { NotSized, - Sized, + Sized { anchor: CrateId }, +} + +impl SizedByDefault { + fn is_sized_trait(self, trait_: TraitId, db: &dyn DefDatabase) -> bool { + match self { + Self::NotSized => false, + Self::Sized { anchor } => { + let sized_trait = + db.lang_item(anchor, "sized".into()).and_then(|lang_item| lang_item.as_trait()); + Some(trait_) == sized_trait + } + } + } } pub fn write_bounds_like_dyn_trait_with_prefix( @@ -749,7 +759,9 @@ pub fn write_bounds_like_dyn_trait_with_prefix( f: &mut HirFormatter, ) -> Result<(), HirDisplayError> { write!(f, "{}", prefix)?; - if !predicates.is_empty() { + if !predicates.is_empty() + || predicates.is_empty() && matches!(default_sized, SizedByDefault::Sized { .. }) + { write!(f, " ")?; write_bounds_like_dyn_trait(predicates, default_sized, f) } else { @@ -771,22 +783,18 @@ fn write_bounds_like_dyn_trait( let mut first = true; let mut angle_open = false; let mut is_fn_trait = false; - let mut is_sized = None; + let mut is_sized = false; for p in predicates.iter() { match p.skip_binders() { WhereClause::Implemented(trait_ref) => { let trait_ = trait_ref.hir_trait_id(); - match is_sized_trait(f.db.upcast(), trait_) { - Some(true) => { - is_sized = Some(true); - if default_sized == SizedByDefault::Sized { + if default_sized.is_sized_trait(trait_, f.db.upcast()) { + is_sized = true; + if matches!(default_sized, SizedByDefault::Sized { .. }) { // Don't print +Sized, but rather +?Sized if absent. continue; } } - Some(false) => is_sized = is_sized.or(Some(false)), - None => (), - } if !is_fn_trait { is_fn_trait = fn_traits(f.db.upcast(), trait_).any(|it| it == trait_); } @@ -851,8 +859,8 @@ fn write_bounds_like_dyn_trait( if angle_open { write!(f, ">")?; } - if default_sized == SizedByDefault::Sized && is_sized.is_some() { - if is_sized == Some(false) { + if matches!(default_sized, SizedByDefault::Sized { .. }) { + if !is_sized { write!(f, "{}?Sized", if first { "" } else { " + " })?; } else if first { write!(f, "Sized")?; diff --git a/crates/hir_ty/src/tests/display_source_code.rs b/crates/hir_ty/src/tests/display_source_code.rs index cc2b779072ad..a6ece667e10e 100644 --- a/crates/hir_ty/src/tests/display_source_code.rs +++ b/crates/hir_ty/src/tests/display_source_code.rs @@ -42,15 +42,16 @@ fn main() { #[test] fn render_raw_ptr_impl_ty() { + // FIXME: remove parens, they apper because there is an implicit Sized bound check_types_source_code( r#" -trait Sized {} +#[lang = "sized"] trait Sized {} trait Unpin {} -fn foo() -> *const (impl Unpin + Sized) { loop {} } +fn foo() -> *const impl Unpin { loop {} } fn main() { let foo = foo(); foo; -} //^^^ *const (impl Unpin + Sized) +} //^^^ *const (impl Unpin) "#, ); } @@ -72,8 +73,7 @@ fn foo(foo: &dyn for<'a> Foo<'a>) {} fn sized_bounds_apit() { check_types_source_code( r#" -#[lang = "sized"] -pub trait Sized {} +#[lang = "sized"] trait Sized {} trait Foo {} trait Bar {} @@ -83,7 +83,7 @@ fn test( b: impl Foo + Sized, c: &(impl Foo + ?Sized), d: S, - e: impl Bar, + ref_any: &impl ?Sized, empty: impl, ) { a; @@ -94,8 +94,8 @@ fn test( //^ &impl Foo + ?Sized d; //^ S - e; - //^ impl Bar + ref_any; + //^ &impl ?Sized empty; } //^ impl Sized "#, @@ -106,8 +106,7 @@ fn test( fn sized_bounds_rpit() { check_types_source_code( r#" -#[lang = "sized"] -pub trait Sized {} +#[lang = "sized"] trait Sized {} trait Foo {} fn foo() -> impl Foo { loop {} } @@ -123,8 +122,7 @@ fn test() { fn sized_bounds_impl_traits_in_fn_signature() { check_types_source_code( r#" -#[lang = "sized"] -pub trait Sized {} +#[lang = "sized"] trait Sized {} trait Foo {} fn test( diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs index aa4234969b9a..1f090ccc44d7 100644 --- a/crates/hir_ty/src/tests/method_resolution.rs +++ b/crates/hir_ty/src/tests/method_resolution.rs @@ -922,6 +922,7 @@ fn test() { foo.call(); } fn super_trait_impl_return_trait_method_resolution() { check_infer( r#" + #[lang = "sized"] trait Sized {} trait Base { fn foo(self) -> usize; } @@ -939,26 +940,26 @@ fn super_trait_impl_return_trait_method_resolution() { } "#, expect![[r#" - 24..28 'self': Self - 90..101 '{ loop {} }': ! - 92..99 'loop {}': ! - 97..99 '{}': () - 128..139 '{ loop {} }': ! - 130..137 'loop {}': ! - 135..137 '{}': () - 149..154 'base2': impl Base - 167..173 'super2': impl Super - 187..264 '{ ...o(); }': () - 193..198 'base1': fn base1() -> impl Base - 193..200 'base1()': impl Base - 193..206 'base1().foo()': usize - 212..218 'super1': fn super1() -> impl Super - 212..220 'super1()': impl Super - 212..226 'super1().foo()': usize - 232..237 'base2': impl Base - 232..243 'base2.foo()': usize - 249..255 'super2': impl Super - 249..261 'super2.foo()': usize + 57..61 'self': Self + 123..134 '{ loop {} }': ! + 125..132 'loop {}': ! + 130..132 '{}': () + 161..172 '{ loop {} }': ! + 163..170 'loop {}': ! + 168..170 '{}': () + 182..187 'base2': impl Base + 200..206 'super2': impl Super + 220..297 '{ ...o(); }': () + 226..231 'base1': fn base1() -> impl Base + 226..233 'base1()': impl Base + 226..239 'base1().foo()': usize + 245..251 'super1': fn super1() -> impl Super + 245..253 'super1()': impl Super + 245..259 'super1().foo()': usize + 265..270 'base2': impl Base + 265..276 'base2.foo()': usize + 282..288 'super2': impl Super + 282..294 'super2.foo()': usize "#]], ); } diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index dfcc4608c164..37257655ddbd 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -845,6 +845,7 @@ fn test(t: T) { fn argument_impl_trait() { check_infer_with_mismatches( r#" +#[lang = "sized"] trait Sized {} trait Trait { fn foo(&self) -> T; fn foo2(&self) -> i64; @@ -866,34 +867,34 @@ fn test(x: impl Trait, y: &impl Trait) { z.foo2(); }"#, expect![[r#" - 29..33 'self': &Self - 54..58 'self': &Self - 77..78 'x': impl Trait - 97..99 '{}': () - 154..155 'x': impl Trait - 174..175 'y': &impl Trait - 195..323 '{ ...2(); }': () - 201..202 'x': impl Trait - 208..209 'y': &impl Trait - 219..220 'z': S - 223..224 'S': S(u16) -> S - 223..227 'S(1)': S - 225..226 '1': u16 - 233..236 'bar': fn bar(S) - 233..239 'bar(z)': () - 237..238 'z': S - 245..246 'x': impl Trait - 245..252 'x.foo()': u64 - 258..259 'y': &impl Trait - 258..265 'y.foo()': u32 - 271..272 'z': S - 271..278 'z.foo()': u16 - 284..285 'x': impl Trait - 284..292 'x.foo2()': i64 - 298..299 'y': &impl Trait - 298..306 'y.foo2()': i64 - 312..313 'z': S - 312..320 'z.foo2()': i64 + 62..66 'self': &Self + 87..91 'self': &Self + 110..111 'x': impl Trait + 130..132 '{}': () + 187..188 'x': impl Trait + 207..208 'y': &impl Trait + 228..356 '{ ...2(); }': () + 234..235 'x': impl Trait + 241..242 'y': &impl Trait + 252..253 'z': S + 256..257 'S': S(u16) -> S + 256..260 'S(1)': S + 258..259 '1': u16 + 266..269 'bar': fn bar(S) + 266..272 'bar(z)': () + 270..271 'z': S + 278..279 'x': impl Trait + 278..285 'x.foo()': u64 + 291..292 'y': &impl Trait + 291..298 'y.foo()': u32 + 304..305 'z': S + 304..311 'z.foo()': u16 + 317..318 'x': impl Trait + 317..325 'x.foo2()': i64 + 331..332 'y': &impl Trait + 331..339 'y.foo2()': i64 + 345..346 'z': S + 345..353 'z.foo2()': i64 "#]], ); } @@ -902,6 +903,7 @@ fn test(x: impl Trait, y: &impl Trait) { fn argument_impl_trait_type_args_1() { check_infer_with_mismatches( r#" +#[lang = "sized"] trait Sized {} trait Trait {} trait Foo { // this function has an implicit Self param, an explicit type param, @@ -926,39 +928,39 @@ fn test() { foo::(S); // we should ignore the extraneous i32 }"#, expect![[r#" - 155..156 'x': impl Trait - 175..186 '{ loop {} }': T - 177..184 'loop {}': ! - 182..184 '{}': () - 199..200 'x': impl Trait - 219..230 '{ loop {} }': T - 221..228 'loop {}': ! - 226..228 '{}': () - 300..509 '{ ... i32 }': () - 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} - 306..317 'Foo::bar(S)': {unknown} - 315..316 'S': S - 323..338 '::bar': fn bar(S) -> {unknown} - 323..341 '(S) -> {unknown} - 347..356 'F::bar(S)': {unknown} - 354..355 'S': S - 362..377 'Foo::bar::': fn bar<{unknown}, u32>(S) -> u32 - 362..380 'Foo::b...32>(S)': u32 - 378..379 'S': S - 386..408 '': fn bar(S) -> u32 - 386..411 '(S)': u32 - 409..410 'S': S - 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} - 418..424 'foo(S)': {unknown} - 422..423 'S': S - 430..440 'foo::': fn foo(S) -> u32 - 430..443 'foo::(S)': u32 - 441..442 'S': S - 449..464 'foo::': fn foo(S) -> u32 - 449..467 'foo::<...32>(S)': u32 - 465..466 'S': S + 188..189 'x': impl Trait + 208..219 '{ loop {} }': T + 210..217 'loop {}': ! + 215..217 '{}': () + 232..233 'x': impl Trait + 252..263 '{ loop {} }': T + 254..261 'loop {}': ! + 259..261 '{}': () + 333..542 '{ ... i32 }': () + 339..347 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} + 339..350 'Foo::bar(S)': {unknown} + 348..349 'S': S + 356..371 '::bar': fn bar(S) -> {unknown} + 356..374 '(S) -> {unknown} + 380..389 'F::bar(S)': {unknown} + 387..388 'S': S + 395..410 'Foo::bar::': fn bar<{unknown}, u32>(S) -> u32 + 395..413 'Foo::b...32>(S)': u32 + 411..412 'S': S + 419..441 '': fn bar(S) -> u32 + 419..444 '(S)': u32 + 442..443 'S': S + 451..454 'foo': fn foo<{unknown}>(S) -> {unknown} + 451..457 'foo(S)': {unknown} + 455..456 'S': S + 463..473 'foo::': fn foo(S) -> u32 + 463..476 'foo::(S)': u32 + 474..475 'S': S + 482..497 'foo::': fn foo(S) -> u32 + 482..500 'foo::<...32>(S)': u32 + 498..499 'S': S "#]], ); } @@ -967,6 +969,7 @@ fn test() { fn argument_impl_trait_type_args_2() { check_infer_with_mismatches( r#" +#[lang = "sized"] trait Sized {} trait Trait {} struct S; impl Trait for S {} @@ -982,24 +985,24 @@ fn test() { F::.foo::(S); // extraneous argument should be ignored }"#, expect![[r#" - 87..91 'self': F - 93..94 'x': impl Trait - 118..129 '{ loop {} }': (T, U) - 120..127 'loop {}': ! - 125..127 '{}': () - 143..283 '{ ...ored }': () - 149..150 'F': F<{unknown}> - 149..157 'F.foo(S)': ({unknown}, {unknown}) - 155..156 'S': S - 163..171 'F::': F - 163..178 'F::.foo(S)': (u32, {unknown}) - 176..177 'S': S - 184..192 'F::': F - 184..206 'F::(S)': (u32, i32) - 204..205 'S': S - 212..220 'F::': F - 212..239 'F::(S)': (u32, i32) + 120..124 'self': F + 126..127 'x': impl Trait + 151..162 '{ loop {} }': (T, U) + 153..160 'loop {}': ! + 158..160 '{}': () + 176..316 '{ ...ored }': () + 182..183 'F': F<{unknown}> + 182..190 'F.foo(S)': ({unknown}, {unknown}) + 188..189 'S': S + 196..204 'F::': F + 196..211 'F::.foo(S)': (u32, {unknown}) + 209..210 'S': S + 217..225 'F::': F + 217..239 'F::(S)': (u32, i32) 237..238 'S': S + 245..253 'F::': F + 245..272 'F::(S)': (u32, i32) + 270..271 'S': S "#]], ); } @@ -1008,6 +1011,7 @@ fn test() { fn argument_impl_trait_to_fn_pointer() { check_infer_with_mismatches( r#" +#[lang = "sized"] trait Sized {} trait Trait {} fn foo(x: impl Trait) { loop {} } struct S; @@ -1017,13 +1021,13 @@ fn test() { let f: fn(S) -> () = foo; }"#, expect![[r#" - 22..23 'x': impl Trait - 37..48 '{ loop {} }': () - 39..46 'loop {}': ! - 44..46 '{}': () - 90..123 '{ ...foo; }': () - 100..101 'f': fn(S) - 117..120 'foo': fn foo(S) + 55..56 'x': impl Trait + 70..81 '{ loop {} }': () + 72..79 'loop {}': ! + 77..79 '{}': () + 123..156 '{ ...foo; }': () + 133..134 'f': fn(S) + 150..153 'foo': fn foo(S) "#]], ); } @@ -1032,6 +1036,7 @@ fn test() { fn impl_trait() { check_infer( r#" +#[lang = "sized"] trait Sized {} trait Trait { fn foo(&self) -> T; fn foo2(&self) -> i64; @@ -1050,29 +1055,29 @@ fn test(x: impl Trait, y: &impl Trait) { z.foo2(); }"#, expect![[r#" - 29..33 'self': &Self - 54..58 'self': &Self - 98..100 '{}': () - 110..111 'x': impl Trait - 130..131 'y': &impl Trait - 151..268 '{ ...2(); }': () - 157..158 'x': impl Trait - 164..165 'y': &impl Trait - 175..176 'z': impl Trait - 179..182 'bar': fn bar() -> impl Trait - 179..184 'bar()': impl Trait + 62..66 'self': &Self + 87..91 'self': &Self + 131..133 '{}': () + 143..144 'x': impl Trait + 163..164 'y': &impl Trait + 184..301 '{ ...2(); }': () 190..191 'x': impl Trait - 190..197 'x.foo()': u64 - 203..204 'y': &impl Trait - 203..210 'y.foo()': u64 - 216..217 'z': impl Trait - 216..223 'z.foo()': u64 - 229..230 'x': impl Trait - 229..237 'x.foo2()': i64 - 243..244 'y': &impl Trait - 243..251 'y.foo2()': i64 - 257..258 'z': impl Trait - 257..265 'z.foo2()': i64 + 197..198 'y': &impl Trait + 208..209 'z': impl Trait + 212..215 'bar': fn bar() -> impl Trait + 212..217 'bar()': impl Trait + 223..224 'x': impl Trait + 223..230 'x.foo()': u64 + 236..237 'y': &impl Trait + 236..243 'y.foo()': u64 + 249..250 'z': impl Trait + 249..256 'z.foo()': u64 + 262..263 'x': impl Trait + 262..270 'x.foo2()': i64 + 276..277 'y': &impl Trait + 276..284 'y.foo2()': i64 + 290..291 'z': impl Trait + 290..298 'z.foo2()': i64 "#]], ); } @@ -1082,6 +1087,7 @@ fn simple_return_pos_impl_trait() { cov_mark::check!(lower_rpit); check_infer( r#" +#[lang = "sized"] trait Sized {} trait Trait { fn foo(&self) -> T; } @@ -1092,16 +1098,16 @@ fn test() { a.foo(); }"#, expect![[r#" - 29..33 'self': &Self - 71..82 '{ loop {} }': ! - 73..80 'loop {}': ! - 78..80 '{}': () - 94..129 '{ ...o(); }': () - 104..105 'a': impl Trait - 108..111 'bar': fn bar() -> impl Trait - 108..113 'bar()': impl Trait - 119..120 'a': impl Trait - 119..126 'a.foo()': u64 + 62..66 'self': &Self + 104..115 '{ loop {} }': ! + 106..113 'loop {}': ! + 111..113 '{}': () + 127..162 '{ ...o(); }': () + 137..138 'a': impl Trait + 141..144 'bar': fn bar() -> impl Trait + 141..146 'bar()': impl Trait + 152..153 'a': impl Trait + 152..159 'a.foo()': u64 "#]], ); } @@ -1110,6 +1116,7 @@ fn test() { fn more_return_pos_impl_trait() { check_infer( r#" +#[lang = "sized"] trait Sized {} trait Iterator { type Item; fn next(&mut self) -> Self::Item; @@ -1129,37 +1136,37 @@ fn test() { d.foo(); }"#, expect![[r#" - 49..53 'self': &mut Self - 101..105 'self': &Self - 184..195 '{ loop {} }': ({unknown}, {unknown}) - 186..193 'loop {}': ! - 191..193 '{}': () - 206..207 't': T - 268..279 '{ loop {} }': ({unknown}, {unknown}) - 270..277 'loop {}': ! - 275..277 '{}': () - 291..413 '{ ...o(); }': () - 301..307 '(a, b)': (impl Iterator>, impl Trait) - 302..303 'a': impl Iterator> - 305..306 'b': impl Trait - 310..313 'bar': fn bar() -> (impl Iterator>, impl Trait) - 310..315 'bar()': (impl Iterator>, impl Trait) - 321..322 'a': impl Iterator> - 321..329 'a.next()': impl Trait - 321..335 'a.next().foo()': u32 - 341..342 'b': impl Trait - 341..348 'b.foo()': u64 - 358..364 '(c, d)': (impl Iterator>, impl Trait) - 359..360 'c': impl Iterator> - 362..363 'd': impl Trait - 367..370 'baz': fn baz(u128) -> (impl Iterator>, impl Trait) - 367..377 'baz(1u128)': (impl Iterator>, impl Trait) - 371..376 '1u128': u128 - 383..384 'c': impl Iterator> - 383..391 'c.next()': impl Trait - 383..397 'c.next().foo()': u128 - 403..404 'd': impl Trait - 403..410 'd.foo()': u128 + 82..86 'self': &mut Self + 134..138 'self': &Self + 217..228 '{ loop {} }': ({unknown}, {unknown}) + 219..226 'loop {}': ! + 224..226 '{}': () + 239..240 't': T + 301..312 '{ loop {} }': ({unknown}, {unknown}) + 303..310 'loop {}': ! + 308..310 '{}': () + 324..446 '{ ...o(); }': () + 334..340 '(a, b)': (impl Iterator>, impl Trait) + 335..336 'a': impl Iterator> + 338..339 'b': impl Trait + 343..346 'bar': fn bar() -> (impl Iterator>, impl Trait) + 343..348 'bar()': (impl Iterator>, impl Trait) + 354..355 'a': impl Iterator> + 354..362 'a.next()': impl Trait + 354..368 'a.next().foo()': u32 + 374..375 'b': impl Trait + 374..381 'b.foo()': u64 + 391..397 '(c, d)': (impl Iterator>, impl Trait) + 392..393 'c': impl Iterator> + 395..396 'd': impl Trait + 400..403 'baz': fn baz(u128) -> (impl Iterator>, impl Trait) + 400..410 'baz(1u128)': (impl Iterator>, impl Trait) + 404..409 '1u128': u128 + 416..417 'c': impl Iterator> + 416..424 'c.next()': impl Trait + 416..430 'c.next().foo()': u128 + 436..437 'd': impl Trait + 436..443 'd.foo()': u128 "#]], ); } @@ -1168,6 +1175,7 @@ fn test() { fn dyn_trait() { check_infer( r#" +#[lang = "sized"] trait Sized {} trait Trait { fn foo(&self) -> T; fn foo2(&self) -> i64; @@ -1186,29 +1194,29 @@ fn test(x: dyn Trait, y: &dyn Trait) { z.foo2(); }"#, expect![[r#" - 29..33 'self': &Self - 54..58 'self': &Self - 97..99 '{}': () - 109..110 'x': dyn Trait - 128..129 'y': &dyn Trait - 148..265 '{ ...2(); }': () - 154..155 'x': dyn Trait + 62..66 'self': &Self + 87..91 'self': &Self + 130..132 '{}': () + 142..143 'x': dyn Trait 161..162 'y': &dyn Trait - 172..173 'z': dyn Trait - 176..179 'bar': fn bar() -> dyn Trait - 176..181 'bar()': dyn Trait + 181..298 '{ ...2(); }': () 187..188 'x': dyn Trait - 187..194 'x.foo()': u64 - 200..201 'y': &dyn Trait - 200..207 'y.foo()': u64 - 213..214 'z': dyn Trait - 213..220 'z.foo()': u64 - 226..227 'x': dyn Trait - 226..234 'x.foo2()': i64 - 240..241 'y': &dyn Trait - 240..248 'y.foo2()': i64 - 254..255 'z': dyn Trait - 254..262 'z.foo2()': i64 + 194..195 'y': &dyn Trait + 205..206 'z': dyn Trait + 209..212 'bar': fn bar() -> dyn Trait + 209..214 'bar()': dyn Trait + 220..221 'x': dyn Trait + 220..227 'x.foo()': u64 + 233..234 'y': &dyn Trait + 233..240 'y.foo()': u64 + 246..247 'z': dyn Trait + 246..253 'z.foo()': u64 + 259..260 'x': dyn Trait + 259..267 'x.foo2()': i64 + 273..274 'y': &dyn Trait + 273..281 'y.foo2()': i64 + 287..288 'z': dyn Trait + 287..295 'z.foo2()': i64 "#]], ); } @@ -1217,6 +1225,7 @@ fn test(x: dyn Trait, y: &dyn Trait) { fn dyn_trait_in_impl() { check_infer( r#" +#[lang = "sized"] trait Sized {} trait Trait { fn foo(&self) -> (T, U); } @@ -1233,17 +1242,17 @@ fn test(s: S) { s.bar().baz(); }"#, expect![[r#" - 32..36 'self': &Self - 102..106 'self': &S - 128..139 '{ loop {} }': &dyn Trait - 130..137 'loop {}': ! - 135..137 '{}': () - 175..179 'self': &Self - 251..252 's': S - 267..289 '{ ...z(); }': () - 273..274 's': S - 273..280 's.bar()': &dyn Trait - 273..286 's.bar().baz()': (u32, i32) + 65..69 'self': &Self + 135..139 'self': &S + 161..172 '{ loop {} }': &dyn Trait + 163..170 'loop {}': ! + 168..170 '{}': () + 208..212 'self': &Self + 284..285 's': S + 300..322 '{ ...z(); }': () + 306..307 's': S + 306..313 's.bar()': &dyn Trait + 306..319 's.bar().baz()': (u32, i32) "#]], ); } @@ -1252,6 +1261,7 @@ fn test(s: S) { fn dyn_trait_bare() { check_infer( r#" +#[lang = "sized"] trait Sized {} trait Trait { fn foo(&self) -> u64; } @@ -1266,22 +1276,22 @@ fn test(x: Trait, y: &Trait) -> u64 { z.foo(); }"#, expect![[r#" - 26..30 'self': &Self - 60..62 '{}': () - 72..73 'x': dyn Trait - 82..83 'y': &dyn Trait - 100..175 '{ ...o(); }': () - 106..107 'x': dyn Trait - 113..114 'y': &dyn Trait - 124..125 'z': dyn Trait - 128..131 'bar': fn bar() -> dyn Trait - 128..133 'bar()': dyn Trait + 59..63 'self': &Self + 93..95 '{}': () + 105..106 'x': dyn Trait + 115..116 'y': &dyn Trait + 133..208 '{ ...o(); }': () 139..140 'x': dyn Trait - 139..146 'x.foo()': u64 - 152..153 'y': &dyn Trait - 152..159 'y.foo()': u64 - 165..166 'z': dyn Trait - 165..172 'z.foo()': u64 + 146..147 'y': &dyn Trait + 157..158 'z': dyn Trait + 161..164 'bar': fn bar() -> dyn Trait + 161..166 'bar()': dyn Trait + 172..173 'x': dyn Trait + 172..179 'x.foo()': u64 + 185..186 'y': &dyn Trait + 185..192 'y.foo()': u64 + 198..199 'z': dyn Trait + 198..205 'z.foo()': u64 "#]], ); } @@ -1290,6 +1300,7 @@ fn test(x: Trait, y: &Trait) -> u64 { fn weird_bounds() { check_infer( r#" +#[lang = "sized"] trait Sized {} trait Trait {} fn test( a: impl Trait + 'lifetime, @@ -1301,13 +1312,13 @@ fn test( ) {} "#, expect![[r#" - 28..29 'a': impl Trait - 59..60 'b': impl - 82..83 'c': impl Trait - 103..104 'd': impl - 128..129 'e': impl - 148..149 'f': impl Trait - 173..175 '{}': () + 61..62 'a': impl Trait + 92..93 'b': impl Sized + 115..116 'c': impl Trait + 136..137 'd': impl Sized + 161..162 'e': impl ?Sized + 181..182 'f': impl Trait + ?Sized + 206..208 '{}': () "#]], ); } @@ -1331,6 +1342,7 @@ fn test(x: (impl Trait + UnknownTrait)) { fn assoc_type_bindings() { check_infer( r#" +#[lang = "sized"] trait Sized {} trait Trait { type Type; } @@ -1352,41 +1364,41 @@ fn test>(x: T, y: impl Trait) { get2(S::); }"#, expect![[r#" - 49..50 't': T - 77..79 '{}': () - 111..112 't': T - 122..124 '{}': () - 154..155 't': T - 165..168 '{t}': T - 166..167 't': T - 256..257 'x': T - 262..263 'y': impl Trait - 289..397 '{ ...r>); }': () - 295..298 'get': fn get(T) -> ::Type - 295..301 'get(x)': u32 - 299..300 'x': T - 307..311 'get2': fn get2(T) -> u32 - 307..314 'get2(x)': u32 - 312..313 'x': T - 320..323 'get': fn get>(impl Trait) -> as Trait>::Type - 320..326 'get(y)': i64 - 324..325 'y': impl Trait - 332..336 'get2': fn get2>(impl Trait) -> i64 - 332..339 'get2(y)': i64 - 337..338 'y': impl Trait - 345..348 'get': fn get>(S) -> as Trait>::Type - 345..356 'get(set(S))': u64 - 349..352 'set': fn set>(S) -> S - 349..355 'set(S)': S - 353..354 'S': S - 362..366 'get2': fn get2>(S) -> u64 - 362..374 'get2(set(S))': u64 - 367..370 'set': fn set>(S) -> S - 367..373 'set(S)': S - 371..372 'S': S - 380..384 'get2': fn get2>(S) -> str - 380..394 'get2(S::)': str - 385..393 'S::': S + 82..83 't': T + 110..112 '{}': () + 144..145 't': T + 155..157 '{}': () + 187..188 't': T + 198..201 '{t}': T + 199..200 't': T + 289..290 'x': T + 295..296 'y': impl Trait + 322..430 '{ ...r>); }': () + 328..331 'get': fn get(T) -> ::Type + 328..334 'get(x)': u32 + 332..333 'x': T + 340..344 'get2': fn get2(T) -> u32 + 340..347 'get2(x)': u32 + 345..346 'x': T + 353..356 'get': fn get>(impl Trait) -> as Trait>::Type + 353..359 'get(y)': i64 + 357..358 'y': impl Trait + 365..369 'get2': fn get2>(impl Trait) -> i64 + 365..372 'get2(y)': i64 + 370..371 'y': impl Trait + 378..381 'get': fn get>(S) -> as Trait>::Type + 378..389 'get(set(S))': u64 + 382..385 'set': fn set>(S) -> S + 382..388 'set(S)': S + 386..387 'S': S + 395..399 'get2': fn get2>(S) -> u64 + 395..407 'get2(set(S))': u64 + 400..403 'set': fn set>(S) -> S + 400..406 'set(S)': S + 404..405 'S': S + 413..417 'get2': fn get2>(S) -> str + 413..427 'get2(S::)': str + 418..426 'S::': S "#]], ); } @@ -1495,6 +1507,7 @@ fn test(x: T, y: U) { fn super_trait_impl_trait_method_resolution() { check_infer( r#" +#[lang = "sized"] trait Sized {} mod foo { trait SuperTrait { fn foo(&self) -> u32 {} @@ -1506,12 +1519,12 @@ fn test(x: &impl Trait1) { x.foo(); }"#, expect![[r#" - 49..53 'self': &Self - 62..64 '{}': () - 115..116 'x': &impl Trait1 - 132..148 '{ ...o(); }': () - 138..139 'x': &impl Trait1 - 138..145 'x.foo()': u32 + 82..86 'self': &Self + 95..97 '{}': () + 148..149 'x': &impl Trait1 + 165..181 '{ ...o(); }': () + 171..172 'x': &impl Trait1 + 171..178 'x.foo()': u32 "#]], ); } @@ -2299,6 +2312,7 @@ impl TokenStream for Rustc { fn unify_impl_trait() { check_infer_with_mismatches( r#" +#[lang = "sized"] trait Sized {} trait Trait {} fn foo(x: impl Trait) { loop {} } @@ -2316,37 +2330,37 @@ fn test() -> impl Trait { S(default()) }"#, expect![[r#" - 26..27 'x': impl Trait - 46..57 '{ loop {} }': () - 48..55 'loop {}': ! - 53..55 '{}': () - 68..69 'x': impl Trait - 91..102 '{ loop {} }': T - 93..100 'loop {}': ! - 98..100 '{}': () - 171..182 '{ loop {} }': T - 173..180 'loop {}': ! - 178..180 '{}': () - 213..309 '{ ...t()) }': S<{unknown}> - 223..225 's1': S - 228..229 'S': S(u32) -> S - 228..240 'S(default())': S - 230..237 'default': fn default() -> u32 - 230..239 'default()': u32 - 246..249 'foo': fn foo(S) - 246..253 'foo(s1)': () - 250..252 's1': S - 263..264 'x': i32 - 272..275 'bar': fn bar(S) -> i32 - 272..289 'bar(S(...lt()))': i32 - 276..277 'S': S(i32) -> S - 276..288 'S(default())': S - 278..285 'default': fn default() -> i32 - 278..287 'default()': i32 - 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}> - 295..307 'S(default())': S<{unknown}> - 297..304 'default': fn default<{unknown}>() -> {unknown} - 297..306 'default()': {unknown} + 59..60 'x': impl Trait + 79..90 '{ loop {} }': () + 81..88 'loop {}': ! + 86..88 '{}': () + 101..102 'x': impl Trait + 124..135 '{ loop {} }': T + 126..133 'loop {}': ! + 131..133 '{}': () + 204..215 '{ loop {} }': T + 206..213 'loop {}': ! + 211..213 '{}': () + 246..342 '{ ...t()) }': S<{unknown}> + 256..258 's1': S + 261..262 'S': S(u32) -> S + 261..273 'S(default())': S + 263..270 'default': fn default() -> u32 + 263..272 'default()': u32 + 279..282 'foo': fn foo(S) + 279..286 'foo(s1)': () + 283..285 's1': S + 296..297 'x': i32 + 305..308 'bar': fn bar(S) -> i32 + 305..322 'bar(S(...lt()))': i32 + 309..310 'S': S(i32) -> S + 309..321 'S(default())': S + 311..318 'default': fn default() -> i32 + 311..320 'default()': i32 + 328..329 'S': S<{unknown}>({unknown}) -> S<{unknown}> + 328..340 'S(default())': S<{unknown}> + 330..337 'default': fn default<{unknown}>() -> {unknown} + 330..339 'default()': {unknown} "#]], ); }