Skip to content

Commit 6905a19

Browse files
committed
Implement use associated items of traits
1 parent 32c8a9f commit 6905a19

9 files changed

+255
-20
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/messages.ftl

-4
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,6 @@ resolve_invalid_asm_sym =
221221
.label = is a local variable
222222
.help = `sym` operands must refer to either a function or a static
223223
224-
resolve_is_not_directly_importable =
225-
`{$target}` is not directly importable
226-
.label = cannot be imported directly
227-
228224
resolve_is_private =
229225
{$ident_descr} `{$ident}` is private
230226
.label = private {$ident_descr}

compiler/rustc_resolve/src/errors.rs

-9
Original file line numberDiff line numberDiff line change
@@ -785,15 +785,6 @@ pub(crate) struct ItemsInTraitsAreNotImportable {
785785
pub(crate) span: Span,
786786
}
787787

788-
#[derive(Diagnostic)]
789-
#[diag(resolve_is_not_directly_importable, code = E0253)]
790-
pub(crate) struct IsNotDirectlyImportable {
791-
#[primary_span]
792-
#[label]
793-
pub(crate) span: Span,
794-
pub(crate) target: Ident,
795-
}
796-
797788
#[derive(Subdiagnostic)]
798789
#[suggestion(
799790
resolve_unexpected_res_change_ty_to_const_param_sugg,

compiler/rustc_resolve/src/imports.rs

+14-7
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

@@ -29,8 +30,7 @@ use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
2930
use crate::errors::{
3031
CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
3132
CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
32-
ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable,
33-
ItemsInTraitsAreNotImportable,
33+
ConsiderAddingMacroExport, ConsiderMarkingAsPub, ItemsInTraitsAreNotImportable,
3434
};
3535
use crate::{
3636
AmbiguityError, AmbiguityKind, BindingKey, Finalize, ImportSuggestion, Module,
@@ -828,16 +828,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
828828
Err(Undetermined) => indeterminate_count += 1,
829829
// Don't update the resolution, because it was never added.
830830
Err(Determined) if target.name == kw::Underscore => {}
831-
Ok(binding) if binding.is_importable() => {
831+
Ok(binding)
832+
if binding.is_importable()
833+
|| this.tcx.features().import_trait_associated_functions() =>
834+
{
832835
let imported_binding = this.import(binding, import);
833836
target_bindings[ns].set(Some(imported_binding));
834837
this.define(parent, target, ns, imported_binding);
835838
}
836839
source_binding @ (Ok(..) | Err(Determined)) => {
837840
if source_binding.is_ok() {
838-
this.dcx()
839-
.create_err(IsNotDirectlyImportable { span: import.span, target })
840-
.emit();
841+
feature_err(
842+
this.tcx.sess,
843+
sym::import_trait_associated_functions,
844+
import.span,
845+
"`use` associated items of traits is unstable",
846+
)
847+
.emit();
841848
}
842849
let key = BindingKey::new(target, ns);
843850
this.update_resolution(parent, key, false, |_, resolution| {

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,
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`.
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() {}

0 commit comments

Comments
 (0)