Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8606eb3

Browse files
committedDec 25, 2024
Implement use associated items of traits
1 parent 32c8a9f commit 8606eb3

16 files changed

+311
-28
lines changed
 

‎compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,8 @@ declare_features! (
519519
(unstable, impl_trait_in_bindings, "1.64.0", Some(63065)),
520520
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
521521
(unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
522+
/// Allows `use` associated functions from traits.
523+
(unstable, import_trait_associated_functions, "CURRENT_RUSTC_VERSION", Some(134691)),
522524
/// Allows associated types in inherent impls.
523525
(incomplete, inherent_associated_types, "1.52.0", Some(8995)),
524526
/// Allow anonymous constants from an inline `const` block in pattern position

‎compiler/rustc_resolve/src/imports.rs

+23-5
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ use rustc_session::lint::builtin::{
1717
AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE,
1818
REDUNDANT_IMPORTS, UNUSED_IMPORTS,
1919
};
20+
use rustc_session::parse::feature_err;
2021
use rustc_span::edit_distance::find_best_match_for_name;
2122
use rustc_span::hygiene::LocalExpnId;
22-
use rustc_span::{Ident, Span, Symbol, kw};
23+
use rustc_span::{Ident, Span, Symbol, kw, sym};
2324
use smallvec::SmallVec;
2425
use tracing::debug;
2526

@@ -828,16 +829,33 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
828829
Err(Undetermined) => indeterminate_count += 1,
829830
// Don't update the resolution, because it was never added.
830831
Err(Determined) if target.name == kw::Underscore => {}
831-
Ok(binding) if binding.is_importable() => {
832+
Ok(binding)
833+
if binding.is_importable()
834+
|| binding.is_assoc_const_or_fn()
835+
&& this.tcx.features().import_trait_associated_functions() =>
836+
{
832837
let imported_binding = this.import(binding, import);
833838
target_bindings[ns].set(Some(imported_binding));
834839
this.define(parent, target, ns, imported_binding);
835840
}
836841
source_binding @ (Ok(..) | Err(Determined)) => {
837-
if source_binding.is_ok() {
838-
this.dcx()
839-
.create_err(IsNotDirectlyImportable { span: import.span, target })
842+
if let Ok(binding) = source_binding {
843+
if binding.is_assoc_const_or_fn() {
844+
feature_err(
845+
this.tcx.sess,
846+
sym::import_trait_associated_functions,
847+
import.span,
848+
"`use` associated items of traits is unstable",
849+
)
840850
.emit();
851+
} else {
852+
this.dcx()
853+
.create_err(IsNotDirectlyImportable {
854+
span: import.span,
855+
target,
856+
})
857+
.emit();
858+
}
841859
}
842860
let key = BindingKey::new(target, ns);
843861
this.update_resolution(parent, key, false, |_, resolution| {

‎compiler/rustc_resolve/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,10 @@ impl<'ra> NameBindingData<'ra> {
926926
)
927927
}
928928

929+
fn is_assoc_const_or_fn(&self) -> bool {
930+
matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _))
931+
}
932+
929933
fn macro_kind(&self) -> Option<MacroKind> {
930934
self.res().macro_kind()
931935
}

‎compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,7 @@ symbols! {
10921092
import,
10931093
import_name_type,
10941094
import_shadowing,
1095+
import_trait_associated_functions,
10951096
imported_main,
10961097
in_band_lifetimes,
10971098
include,

‎tests/ui/error-codes/E0253.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
mod foo {
22
pub trait MyTrait {
3-
fn do_something();
3+
type SomeType;
44
}
55
}
66

7-
use foo::MyTrait::do_something;
7+
use foo::MyTrait::SomeType;
88
//~^ ERROR E0253
99

1010
fn main() {}

‎tests/ui/error-codes/E0253.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0253]: `do_something` is not directly importable
1+
error[E0253]: `SomeType` is not directly importable
22
--> $DIR/E0253.rs:7:5
33
|
4-
LL | use foo::MyTrait::do_something;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
4+
LL | use foo::MyTrait::SomeType;
5+
| ^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
66

77
error: aborting due to 1 previous error
88

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//@ edition:2018
2+
use std::collections::HashMap;
3+
4+
use A::{DEFAULT, new};
5+
//~^ ERROR `use` associated items of traits is unstable [E0658]
6+
//~| ERROR `use` associated items of traits is unstable [E0658]
7+
use Default::default;
8+
//~^ ERROR `use` associated items of traits is unstable [E0658]
9+
10+
struct S {
11+
a: HashMap<i32, i32>,
12+
}
13+
14+
impl S {
15+
fn new() -> S {
16+
S { a: default() }
17+
}
18+
}
19+
20+
trait A: Sized {
21+
const DEFAULT: Option<Self> = None;
22+
fn new() -> Self;
23+
fn do_something(&self);
24+
}
25+
26+
mod b {
27+
use super::A::{self, DEFAULT, new};
28+
//~^ ERROR `use` associated items of traits is unstable [E0658]
29+
//~| ERROR `use` associated items of traits is unstable [E0658]
30+
31+
struct B();
32+
33+
impl A for B {
34+
const DEFAULT: Option<Self> = Some(B());
35+
fn new() -> Self {
36+
B()
37+
}
38+
39+
fn do_something(&self) {}
40+
}
41+
42+
fn f() {
43+
let b: B = new();
44+
b.do_something();
45+
let c: B = DEFAULT.unwrap();
46+
}
47+
}
48+
49+
impl A for S {
50+
fn new() -> Self {
51+
S::new()
52+
}
53+
54+
fn do_something(&self) {}
55+
}
56+
57+
fn f() {
58+
let s: S = new();
59+
s.do_something();
60+
let t: Option<S> = DEFAULT;
61+
}
62+
63+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
error[E0658]: `use` associated items of traits is unstable
2+
--> $DIR/feature-gate-import-trait-associated-functions.rs:4:9
3+
|
4+
LL | use A::{DEFAULT, new};
5+
| ^^^^^^^
6+
|
7+
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
8+
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error[E0658]: `use` associated items of traits is unstable
12+
--> $DIR/feature-gate-import-trait-associated-functions.rs:4:18
13+
|
14+
LL | use A::{DEFAULT, new};
15+
| ^^^
16+
|
17+
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
18+
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
19+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
20+
21+
error[E0658]: `use` associated items of traits is unstable
22+
--> $DIR/feature-gate-import-trait-associated-functions.rs:7:5
23+
|
24+
LL | use Default::default;
25+
| ^^^^^^^^^^^^^^^^
26+
|
27+
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
28+
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
29+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
30+
31+
error[E0658]: `use` associated items of traits is unstable
32+
--> $DIR/feature-gate-import-trait-associated-functions.rs:27:26
33+
|
34+
LL | use super::A::{self, DEFAULT, new};
35+
| ^^^^^^^
36+
|
37+
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
38+
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
39+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
40+
41+
error[E0658]: `use` associated items of traits is unstable
42+
--> $DIR/feature-gate-import-trait-associated-functions.rs:27:35
43+
|
44+
LL | use super::A::{self, DEFAULT, new};
45+
| ^^^
46+
|
47+
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
48+
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
49+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
50+
51+
error: aborting due to 5 previous errors
52+
53+
For more information about this error, try `rustc --explain E0658`.

‎tests/ui/imports/import-trait-method.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ trait Foo {
22
fn foo();
33
}
44

5-
use Foo::foo; //~ ERROR not directly importable
5+
use Foo::foo; //~ ERROR `use` associated items of traits is unstable [E0658]
66

77
fn main() { foo(); }
+7-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
error[E0253]: `foo` is not directly importable
1+
error[E0658]: `use` associated items of traits is unstable
22
--> $DIR/import-trait-method.rs:5:5
33
|
44
LL | use Foo::foo;
5-
| ^^^^^^^^ cannot be imported directly
5+
| ^^^^^^^^
6+
|
7+
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
8+
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
610

711
error: aborting due to 1 previous error
812

9-
For more information about this error, try `rustc --explain E0253`.
13+
For more information about this error, try `rustc --explain E0658`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//@ edition:2015
2+
//@ check-pass
3+
#![feature(import_trait_associated_functions)]
4+
5+
use std::collections::HashMap;
6+
7+
use A::{DEFAULT, new};
8+
use std::default::Default::default;
9+
10+
struct S {
11+
a: HashMap<i32, i32>,
12+
}
13+
14+
impl S {
15+
fn new() -> S {
16+
S { a: default() }
17+
}
18+
}
19+
20+
trait A: Sized {
21+
const DEFAULT: Option<Self> = None;
22+
fn new() -> Self;
23+
fn do_something(&self);
24+
}
25+
26+
mod b {
27+
use super::A::{self, DEFAULT, new};
28+
29+
struct B();
30+
31+
impl A for B {
32+
const DEFAULT: Option<Self> = Some(B());
33+
fn new() -> Self {
34+
B()
35+
}
36+
37+
fn do_something(&self) {}
38+
}
39+
40+
fn f() {
41+
let b: B = new();
42+
b.do_something();
43+
let c: B = DEFAULT.unwrap();
44+
}
45+
}
46+
47+
impl A for S {
48+
fn new() -> Self {
49+
S::new()
50+
}
51+
52+
fn do_something(&self) {}
53+
}
54+
55+
fn f() {
56+
let s: S = new();
57+
s.do_something();
58+
let t: Option<S> = DEFAULT;
59+
}
60+
61+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//@ edition:2018
2+
//@ check-pass
3+
#![feature(import_trait_associated_functions)]
4+
5+
use std::collections::HashMap;
6+
7+
use A::{DEFAULT, new};
8+
use Default::default;
9+
10+
struct S {
11+
a: HashMap<i32, i32>,
12+
}
13+
14+
impl S {
15+
fn new() -> S {
16+
S { a: default() }
17+
}
18+
}
19+
20+
trait A: Sized {
21+
const DEFAULT: Option<Self> = None;
22+
fn new() -> Self;
23+
fn do_something(&self);
24+
}
25+
26+
mod b {
27+
use super::A::{self, DEFAULT, new};
28+
29+
struct B();
30+
31+
impl A for B {
32+
const DEFAULT: Option<Self> = Some(B());
33+
fn new() -> Self {
34+
B()
35+
}
36+
37+
fn do_something(&self) {}
38+
}
39+
40+
fn f() {
41+
let b: B = new();
42+
b.do_something();
43+
let c: B = DEFAULT.unwrap();
44+
}
45+
}
46+
47+
impl A for S {
48+
fn new() -> Self {
49+
S::new()
50+
}
51+
52+
fn do_something(&self) {}
53+
}
54+
55+
fn f() {
56+
let s: S = new();
57+
s.do_something();
58+
let t: Option<S> = DEFAULT;
59+
}
60+
61+
fn main() {}

‎tests/ui/use/use-from-trait-xc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
extern crate use_from_trait_xc;
44

55
use use_from_trait_xc::Trait::foo;
6-
//~^ ERROR `foo` is not directly importable
6+
//~^ ERROR `use` associated items of traits is unstable [E0658]
77

88
use use_from_trait_xc::Trait::Assoc;
99
//~^ ERROR `Assoc` is not directly importable
1010

1111
use use_from_trait_xc::Trait::CONST;
12-
//~^ ERROR `CONST` is not directly importable
12+
//~^ ERROR `use` associated items of traits is unstable [E0658]
1313

1414
use use_from_trait_xc::Foo::new; //~ ERROR struct `Foo` is private
1515
//~^ ERROR unresolved import `use_from_trait_xc::Foo`
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.