Skip to content

Commit

Permalink
Implement use associated items of traits
Browse files Browse the repository at this point in the history
  • Loading branch information
frank-king committed Dec 25, 2024
1 parent 32c8a9f commit 6905a19
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 20 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,8 @@ declare_features! (
(unstable, impl_trait_in_bindings, "1.64.0", Some(63065)),
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
(unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
/// Allows `use` associated functions from traits.
(unstable, import_trait_associated_functions, "CURRENT_RUSTC_VERSION", Some(134691)),
/// Allows associated types in inherent impls.
(incomplete, inherent_associated_types, "1.52.0", Some(8995)),
/// Allow anonymous constants from an inline `const` block in pattern position
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,6 @@ resolve_invalid_asm_sym =
.label = is a local variable
.help = `sym` operands must refer to either a function or a static
resolve_is_not_directly_importable =
`{$target}` is not directly importable
.label = cannot be imported directly
resolve_is_private =
{$ident_descr} `{$ident}` is private
.label = private {$ident_descr}
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,15 +785,6 @@ pub(crate) struct ItemsInTraitsAreNotImportable {
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag(resolve_is_not_directly_importable, code = E0253)]
pub(crate) struct IsNotDirectlyImportable {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) target: Ident,
}

#[derive(Subdiagnostic)]
#[suggestion(
resolve_unexpected_res_change_ty_to_const_param_sugg,
Expand Down
21 changes: 14 additions & 7 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ use rustc_session::lint::builtin::{
AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE,
REDUNDANT_IMPORTS, UNUSED_IMPORTS,
};
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::LocalExpnId;
use rustc_span::{Ident, Span, Symbol, kw};
use rustc_span::{Ident, Span, Symbol, kw, sym};
use smallvec::SmallVec;
use tracing::debug;

Expand All @@ -29,8 +30,7 @@ use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
use crate::errors::{
CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable,
ItemsInTraitsAreNotImportable,
ConsiderAddingMacroExport, ConsiderMarkingAsPub, ItemsInTraitsAreNotImportable,
};
use crate::{
AmbiguityError, AmbiguityKind, BindingKey, Finalize, ImportSuggestion, Module,
Expand Down Expand Up @@ -828,16 +828,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Err(Undetermined) => indeterminate_count += 1,
// Don't update the resolution, because it was never added.
Err(Determined) if target.name == kw::Underscore => {}
Ok(binding) if binding.is_importable() => {
Ok(binding)
if binding.is_importable()
|| this.tcx.features().import_trait_associated_functions() =>
{
let imported_binding = this.import(binding, import);
target_bindings[ns].set(Some(imported_binding));
this.define(parent, target, ns, imported_binding);
}
source_binding @ (Ok(..) | Err(Determined)) => {
if source_binding.is_ok() {
this.dcx()
.create_err(IsNotDirectlyImportable { span: import.span, target })
.emit();
feature_err(
this.tcx.sess,
sym::import_trait_associated_functions,
import.span,
"`use` associated items of traits is unstable",
)
.emit();
}
let key = BindingKey::new(target, ns);
this.update_resolution(parent, key, false, |_, resolution| {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,7 @@ symbols! {
import,
import_name_type,
import_shadowing,
import_trait_associated_functions,
imported_main,
in_band_lifetimes,
include,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//@ edition:2018
use std::collections::HashMap;

use A::{DEFAULT, new};
//~^ ERROR `use` associated items of traits is unstable [E0658]
//~| ERROR `use` associated items of traits is unstable [E0658]
use Default::default;
//~^ ERROR `use` associated items of traits is unstable [E0658]

struct S {
a: HashMap<i32, i32>,
}

impl S {
fn new() -> S {
S { a: default() }
}
}

trait A: Sized {
const DEFAULT: Option<Self> = None;
fn new() -> Self;
fn do_something(&self);
}

mod b {
use super::A::{self, DEFAULT, new};
//~^ ERROR `use` associated items of traits is unstable [E0658]
//~| ERROR `use` associated items of traits is unstable [E0658]

struct B();

impl A for B {
const DEFAULT: Option<Self> = Some(B());
fn new() -> Self {
B()
}

fn do_something(&self) {}
}

fn f() {
let b: B = new();
b.do_something();
let c: B = DEFAULT.unwrap();
}
}

impl A for S {
fn new() -> Self {
S::new()
}

fn do_something(&self) {}
}

fn f() {
let s: S = new();
s.do_something();
let t: Option<S> = DEFAULT;
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
error[E0658]: `use` associated items of traits is unstable
--> $DIR/feature-gate-import-trait-associated-functions.rs:4:9
|
LL | use A::{DEFAULT, new};
| ^^^^^^^
|
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: `use` associated items of traits is unstable
--> $DIR/feature-gate-import-trait-associated-functions.rs:4:18
|
LL | use A::{DEFAULT, new};
| ^^^
|
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: `use` associated items of traits is unstable
--> $DIR/feature-gate-import-trait-associated-functions.rs:7:5
|
LL | use Default::default;
| ^^^^^^^^^^^^^^^^
|
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: `use` associated items of traits is unstable
--> $DIR/feature-gate-import-trait-associated-functions.rs:27:26
|
LL | use super::A::{self, DEFAULT, new};
| ^^^^^^^
|
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: `use` associated items of traits is unstable
--> $DIR/feature-gate-import-trait-associated-functions.rs:27:35
|
LL | use super::A::{self, DEFAULT, new};
| ^^^
|
= note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
= help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0658`.
61 changes: 61 additions & 0 deletions tests/ui/use/import_trait_associated_functions-2015.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//@ edition:2015
//@ check-pass
#![feature(import_trait_associated_functions)]

use std::collections::HashMap;

use A::{DEFAULT, new};
use std::default::Default::default;

struct S {
a: HashMap<i32, i32>,
}

impl S {
fn new() -> S {
S { a: default() }
}
}

trait A: Sized {
const DEFAULT: Option<Self> = None;
fn new() -> Self;
fn do_something(&self);
}

mod b {
use super::A::{self, DEFAULT, new};

struct B();

impl A for B {
const DEFAULT: Option<Self> = Some(B());
fn new() -> Self {
B()
}

fn do_something(&self) {}
}

fn f() {
let b: B = new();
b.do_something();
let c: B = DEFAULT.unwrap();
}
}

impl A for S {
fn new() -> Self {
S::new()
}

fn do_something(&self) {}
}

fn f() {
let s: S = new();
s.do_something();
let t: Option<S> = DEFAULT;
}

fn main() {}
61 changes: 61 additions & 0 deletions tests/ui/use/import_trait_associated_functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//@ edition:2018
//@ check-pass
#![feature(import_trait_associated_functions)]

use std::collections::HashMap;

use A::{DEFAULT, new};
use Default::default;

struct S {
a: HashMap<i32, i32>,
}

impl S {
fn new() -> S {
S { a: default() }
}
}

trait A: Sized {
const DEFAULT: Option<Self> = None;
fn new() -> Self;
fn do_something(&self);
}

mod b {
use super::A::{self, DEFAULT, new};

struct B();

impl A for B {
const DEFAULT: Option<Self> = Some(B());
fn new() -> Self {
B()
}

fn do_something(&self) {}
}

fn f() {
let b: B = new();
b.do_something();
let c: B = DEFAULT.unwrap();
}
}

impl A for S {
fn new() -> Self {
S::new()
}

fn do_something(&self) {}
}

fn f() {
let s: S = new();
s.do_something();
let t: Option<S> = DEFAULT;
}

fn main() {}

0 comments on commit 6905a19

Please sign in to comment.