Comments (4)
@rustbot labels -I-lang-nominated -C-discussion +C-bug
We discussed this in the lang call today. We had everyone there, and our unanimous consensus was that we do not want the RFC 3373 lint to fire in these cases. E.g., we do not want to lint against:
trait Tr {}
fn foo() {
struct S {};
impl Tr for &S {}
}
This has non-local effect due to the "only one thing could go here" inference rule. But still, we consider this beyond the intention of the lint, and if we were to later try to tighten things up (e.g. for the benefit of tooling), we may consider instead trying, in a new edition, to do away with or limit the inference rule (e.g. by adding a check to error if the type being inferred can't be named). For that, we discussed how there may be some precedent for it in the RFC 2145 work from @petrochenkov.
That is, we'd expect people to be able to write (lint-free) the code above, and so we're OK with accepting the leakage here, as we tentatively plan to deal with that in a different way.
Thanks to @jstarks for raising this point and filing this issue.
from rust.
where
Inner
is defined within the function and cannot be named outside it.
It's not because it cannot be named that it cannot be inferred.
This can be demonstrate with your example, here Bar
can be inferred outside the foo
function, showing that the impl definition is not local:
trait Tr {}
fn foo() {
struct Bar;
impl Tr for Box<Bar> {} // with this impl definition
}
fn do_stuff<U: Tr>() {}
fn main() {
do_stuff::<Box<_>>(); // this code will compile, as `_` will be resolved to `Bar`
}
@rustbot labels -C-bug +C-discussion +L-non_local_definitions -needs-triage
from rust.
@rustbot labels +I-lang-nominated
This is kind of a surprising interaction of things. Nominating as we should discuss for visibility and to confirm whether this is what we meant to do.
(In general, we had wanted to support people making local impls for local types on outer traits. While it's clear the impls in this issue do have a non-local effect, the only workaround is to promote the local type to a broader scope outside of the function. That seems a bit strange and unfortunate, and probably isn't what the user wanted to do. There may or may not be a better option; we should just discuss to confirm.)
from rust.
@traviscross I agree that this interaction is surprising and I think that because it is surprising (and non-intuitive) we should warn about it.
@workingjubilee brought up in #125068 (comment) an example where someone might write a private type that for someone might rely on privacy to not be constructible outside of the function:
Also, just to remove all doubt as to whether this is a Real Problem, I present a new example of a completed escape:
pub trait Trait {} fn test() { // Private field to make it more annoying to construct! #[derive(Default)] // oh, but what's this...? struct Local(i32); impl Trait for Option<Local> {} } fn do_stuff<U: Trait + Default>() -> U { Default::default() } fn main() { let x = do_stuff::<Option<_>>().unwrap_or_default(); println!("an instance of {} escaped", std::any::type_name_of_val(&x)); }I think that code would be something someone would probably write, especially if we're talking about a fairly big private function, not just the 4 lines in this example but more like 400 lines. They happen. But if someone was relying on that type not being constructible outside that fn, they are now dead wrong!
Note that it doesn't work with just
U: Default
though because that won't unambiguously resolve and it will demand type annotations. So this is relying on the fact rustc secretly knows there is another type, but only one, that can apply.It's still not clear to me whether we should trigger the lint on the initial example here, as this requires two steps... a way to make the type constructible... but the answer to "is there something unexpected", i.e. is this making the code (and moreover, the code's implications) harder to understand... is probably Very Yes.
As for "bad" or "good", well, I don't like the thought of calling this code "bad" because it doesn't seem inherently objectionable. You may simply not care that much. But I don't think it's a great shining example of code either. It's just... there.
from rust.
Related Issues (20)
- Regression in `#[used]` attribute on Windows msvc HOT 16
- ICE in TaggedSerializer (serde) HOT 2
- missed optimization: coalese PathBuf reallocation HOT 5
- `thread 'rustc' panicked at compiler/rustc_codegen_ssa/src/back/link.rs:2700:27: index out of bounds: the len is 41 but the index is 41` HOT 1
- Vxworks build error for current master branch. Need to update some source. HOT 3
- rustdoc: add link prefix which would allow overwriting explicit links with item links
- Left-padding using format! does not work when using a fmt::Display as the argument HOT 4
- ICE: Cannot Eq compare incompatible types *mut T/#0 and *const T/#0 HOT 2
- Rust binaries cannot load relocatable libraries on macOS without `-rpath`
- Rust suggests invalid syntax for returning a method call in E0282
- Should tokens passed through `macro_rules` be able to join? HOT 1
- rustc ignores first exposed private type / span incorrect
- spurious ci failure: `The process cannot access the file because it is being used by another process` HOT 1
- A problem has to do with tuple and println!()
- Unresolved symbol linker error when running `cargo test` with an `#[used]` static variable on Windows HOT 2
- Assertion failure: Unexpected captures in ABI-compatible shim for Fn/FnMut implementation of coroutine-closure HOT 1
- ICE: assertion failed `Alias(Projection, ..` != `FreshTy(0)`
- ICE: `associated_type_for_effects: Defid .. should be Trait or Impl but is TraitAlias`
- ICE: `expected type for .. but found Const(false) when instantiating`
- ICE: `parent item: DefId(0:5 ~ a[9a36]::{impl#1}) not marked as default` HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rust.