diff options
| author | bors <bors@rust-lang.org> | 2022-08-04 10:21:40 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-08-04 10:21:40 +0000 |
| commit | 6f18f0a9d4548bc87afff1e4c0fe9081c35002c2 (patch) | |
| tree | 8663684051908c2006289035b5c910ffddab9540 | |
| parent | 2f2243c9b6686d2314515561a80898e746015231 (diff) | |
| parent | ec3f3074a1d2f0c3f8a4fd245c79a774cf19a7ca (diff) | |
| download | rust-6f18f0a9d4548bc87afff1e4c0fe9081c35002c2.tar.gz rust-6f18f0a9d4548bc87afff1e4c0fe9081c35002c2.zip | |
Auto merge of #99953 - cjgillot:in-path-always, r=petrochenkov
Always create elided lifetimes, even if inferred. `PathSource` gives the context in which a path is encountered. The same `PathSource` is used for the full path and the `QSelf` part. Therefore, we can only rely on `PathSource` to know whether typechecking will be able to infer the lifetimes, not whether we need to insert them at all. Fixes https://github.com/rust-lang/rust/issues/99949
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 43 | ||||
| -rw-r--r-- | src/test/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs | 17 |
2 files changed, 37 insertions, 23 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ed65100ae77..dea3eaecda6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1644,14 +1644,30 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { continue; } - let missing = match source { - PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type => true, + let node_ids = self.r.next_node_ids(expected_lifetimes); + self.record_lifetime_res( + segment_id, + LifetimeRes::ElidedAnchor { start: node_ids.start, end: node_ids.end }, + LifetimeElisionCandidate::Ignore, + ); + + let inferred = match source { + PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type => false, PathSource::Expr(..) | PathSource::Pat | PathSource::Struct - | PathSource::TupleStruct(..) => false, + | PathSource::TupleStruct(..) => true, }; - if !missing && !segment.has_generic_args { + if inferred { + // Do not create a parameter for patterns and expressions: type checking can infer + // the appropriate lifetime for us. + for id in node_ids { + self.record_lifetime_res( + id, + LifetimeRes::Infer, + LifetimeElisionCandidate::Named, + ); + } continue; } @@ -1666,25 +1682,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }; let ident = Ident::new(kw::UnderscoreLifetime, elided_lifetime_span); - let node_ids = self.r.next_node_ids(expected_lifetimes); - self.record_lifetime_res( - segment_id, - LifetimeRes::ElidedAnchor { start: node_ids.start, end: node_ids.end }, - LifetimeElisionCandidate::Ignore, - ); - - if !missing { - // Do not create a parameter for patterns and expressions. - for id in node_ids { - self.record_lifetime_res( - id, - LifetimeRes::Infer, - LifetimeElisionCandidate::Named, - ); - } - continue; - } - let missing_lifetime = MissingLifetime { id: node_ids.start, span: elided_lifetime_span, diff --git a/src/test/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs b/src/test/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs new file mode 100644 index 00000000000..b9d2711fd9c --- /dev/null +++ b/src/test/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs @@ -0,0 +1,17 @@ +// check-pass + +struct Sqlite {} + +trait HasArguments<'q> { + type Arguments; +} + +impl<'q> HasArguments<'q> for Sqlite { + type Arguments = std::marker::PhantomData<&'q ()>; +} + +fn foo() { + let _ = <Sqlite as HasArguments>::Arguments::default(); +} + +fn main() {} |
