Skip to content

[ImgBot] Optimize images - #3

Merged
pthariensflame merged 1 commit into
masterfrom
imgbot
Feb 11, 2020
Merged

pthariensflame merged 1 commit into
masterfrom
imgbot

Conversation

@imgbot

@imgbot imgbot Bot commented Feb 11, 2020

Copy link
Copy Markdown

Beep boop. Your images are optimized!

Your image file size has been reduced by 21% 🎉

Details
File Before After Percent reduction
/src/etc/installer/gfx/rust-logo.png 5.71kb 3.82kb 33.11%
/src/librustdoc/html/static/down-arrow.svg 0.63kb 0.50kb 20.44%
/src/librustdoc/html/static/wheel.svg 3.86kb 3.68kb 4.66%
/src/librustdoc/html/static/brush.svg 0.47kb 0.44kb 4.61%
Total : 10.65kb 8.44kb 20.82%

📝docs | :octocat: repo | 🙋issues | 🏅swag | 🏪marketplace

*Total -- 10.65kb -> 8.44kb (20.82%)

/src/etc/installer/gfx/rust-logo.png -- 5.71kb -> 3.82kb (33.11%)
/src/librustdoc/html/static/down-arrow.svg -- 0.63kb -> 0.50kb (20.44%)
/src/librustdoc/html/static/wheel.svg -- 3.86kb -> 3.68kb (4.66%)
/src/librustdoc/html/static/brush.svg -- 0.47kb -> 0.44kb (4.61%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
@pthariensflame
pthariensflame merged this pull request into master Feb 11, 2020
@pthariensflame
pthariensflame deleted the imgbot branch February 11, 2020 03:22
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Feb 13, 2020
…r=GuillaumeGomez

Optimize image sizes

This was done by [ImgBot](https://imgbot.net/) on my own fork, which I then immediately merged and turned into this manual pull request. Below is reproduced [ImgBot's own message](pthariensflame#3 (comment)) on the content of this PR.

r? @steveklabnik since this is a documentation PR, I guess.

---

> ## Beep boop. Your images are optimized!
>
> Your image file size has been reduced by **21%** 🎉
>
> <details>
> <summary>
> Details
> </summary>
>
> | File | Before | After | Percent reduction |
> |:--|:--|:--|:--|
> | /src/etc/installer/gfx/rust-logo.png | 5.71kb | 3.82kb | 33.11% |
> | /src/librustdoc/html/static/down-arrow.svg | 0.63kb | 0.50kb | 20.44% |
> | /src/librustdoc/html/static/wheel.svg | 3.86kb | 3.68kb | 4.66% |
> | /src/librustdoc/html/static/brush.svg | 0.47kb | 0.44kb | 4.61% |
> | | | | |
> | **Total :** | **10.65kb** | **8.44kb** | **20.82%** |
> </details>
>
> ---
>
> [📝docs](https://imgbot.net/docs) | [:octocat: repo](https://github.com/dabutvin/ImgBot) | [🙋issues](https://github.com/dabutvin/ImgBot/issues) | [🏅swag](https://goo.gl/forms/1GX7wlhGEX8nkhGO2) | [🏪marketplace](https://github.com/marketplace/imgbot)
pthariensflame pushed a commit that referenced this pull request Dec 21, 2020
Don't run `resolve_vars_if_possible` in `normalize_erasing_regions`

Neither `@eddyb` nor I could figure out what this was for. I changed it to `assert_eq!(normalized_value, infcx.resolve_vars_if_possible(&normalized_value));` and it passed the UI test suite.

<details><summary>

Outdated, I figured out the issue - `needs_infer()` needs to come _after_ erasing the lifetimes

</summary>

Strangely, if I change it to `assert!(!normalized_value.needs_infer())` it panics almost immediately:

```
query stack during panic:
#0 [normalize_generic_arg_after_erasing_regions] normalizing `<str::IsWhitespace as str::pattern::Pattern>::Searcher`
#1 [needs_drop_raw] computing whether `str::iter::Split<str::IsWhitespace>` needs drop
#2 [mir_built] building MIR for `str::<impl str>::split_whitespace`
#3 [unsafety_check_result] unsafety-checking `str::<impl str>::split_whitespace`
#4 [mir_const] processing MIR for `str::<impl str>::split_whitespace`
#5 [mir_promoted] processing `str::<impl str>::split_whitespace`
#6 [mir_borrowck] borrow-checking `str::<impl str>::split_whitespace`
#7 [analysis] running analysis passes on this crate
end of query stack
```

I'm not entirely sure what's going on - maybe the two disagree?

</details>

For context, this came up while reviewing rust-lang#77467 (cc `@lcnr).`

Possibly this needs a crater run?

r? `@nikomatsakis`
cc `@matthewjasper`
pthariensflame pushed a commit that referenced this pull request Feb 20, 2021
HWAddressSanitizer support

#  Motivation
Compared to regular ASan, HWASan has a [smaller overhead](https://source.android.com/devices/tech/debug/hwasan). The difference in practice is that HWASan'ed code is more usable, e.g. Android device compiled with HWASan can be used as a daily driver.

# Example
```
fn main() {
    let xs = vec![0, 1, 2, 3];
    let _y = unsafe { *xs.as_ptr().offset(4) };
}
```
```
==223==ERROR: HWAddressSanitizer: tag-mismatch on address 0xefdeffff0050 at pc 0xaaaad00b3468
READ of size 4 at 0xefdeffff0050 tags: e5/00 (ptr/mem) in thread T0
    #0 0xaaaad00b3464  (/root/main+0x53464)
    #1 0xaaaad00b39b4  (/root/main+0x539b4)
    #2 0xaaaad00b3dd0  (/root/main+0x53dd0)
    #3 0xaaaad00b61dc  (/root/main+0x561dc)
    #4 0xaaaad00c0574  (/root/main+0x60574)
    #5 0xaaaad00b6290  (/root/main+0x56290)
    #6 0xaaaad00b6170  (/root/main+0x56170)
    #7 0xaaaad00b3578  (/root/main+0x53578)
    rust-lang#8 0xffff81345e70  (/lib64/libc.so.6+0x20e70)
    rust-lang#9 0xaaaad0096310  (/root/main+0x36310)

[0xefdeffff0040,0xefdeffff0060) is a small allocated heap chunk; size: 32 offset: 16
0xefdeffff0050 is located 0 bytes to the right of 16-byte region [0xefdeffff0040,0xefdeffff0050)
allocated here:
    #0 0xaaaad009bcdc  (/root/main+0x3bcdc)
    #1 0xaaaad00b1eb0  (/root/main+0x51eb0)
    #2 0xaaaad00b20d4  (/root/main+0x520d4)
    #3 0xaaaad00b2800  (/root/main+0x52800)
    #4 0xaaaad00b1cf4  (/root/main+0x51cf4)
    #5 0xaaaad00b33d4  (/root/main+0x533d4)
    #6 0xaaaad00b39b4  (/root/main+0x539b4)
    #7 0xaaaad00b61dc  (/root/main+0x561dc)
    rust-lang#8 0xaaaad00b3578  (/root/main+0x53578)
    rust-lang#9 0xaaaad0096310  (/root/main+0x36310)

Thread: T0 0xeffe00002000 stack: [0xffffc0590000,0xffffc0d90000) sz: 8388608 tls: [0xffff81521020,0xffff815217d0)
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  0xfefcefffef80: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffef90: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefa0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefb0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefc0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefd0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefe0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffeff0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
=>0xfefceffff000: a2  a2  05  00  e5 [00] 00  00  00  00  00  00  00  00  00  00
  0xfefceffff010: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff020: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff030: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff040: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff050: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff060: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff070: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff080: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
  0xfefcefffeff0: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
=>0xfefceffff000: ..  ..  c5  ..  .. [..] ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
  0xfefceffff010: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags
Registers where the failure occurred (pc 0xaaaad00b3468):
    x0  e500efdeffff0050  x1  0000000000000004  x2  0000ffffc0d8f5a0  x3  0200efff00000000
    x4  0000ffffc0d8f4c0  x5  000000000000004f  x6  00000ffffc0d8f36  x7  0000efff00000000
    x8  e500efdeffff0050  x9  0200efff00000000  x10 0000000000000000  x11 0200efff00000000
    x12 0200effe000006b0  x13 0200effe000006b0  x14 0000000000000008  x15 00000000c00000cf
    x16 0000aaaad00a0afc  x17 0000000000000003  x18 0000000000000001  x19 0000ffffc0d8f718
    x20 ba00ffffc0d8f7a0  x21 0000aaaad00962e0  x22 0000000000000000  x23 0000000000000000
    x24 0000000000000000  x25 0000000000000000  x26 0000000000000000  x27 0000000000000000
    x28 0000000000000000  x29 0000ffffc0d8f650  x30 0000aaaad00b3468
```

# Comments/Caveats
* HWASan is only supported on arm64.
* I'm not sure if I should add a feature gate or piggyback on the existing one for sanitizers.
* HWASan requires `-C target-feature=+tagged-globals`. That flag should probably be set transparently to the user. Not sure how to go about that.

# TODO
* Need more tests.
* Update documentation.
* Fix symbolization.
* Integrate with CI
pthariensflame pushed a commit that referenced this pull request Sep 14, 2025
…r=jieyouxu

Rehome 30 `tests/ui/issues/` tests to other subdirectories under `tests/ui/` [#3 of Batch #2]

Part of rust-lang#133895

Methodology:

1. Refer to the previously written `tests/ui/SUMMARY.md`
2. Find an appropriate category for the test, using the original issue thread and the test contents.
3. Add the issue URL at the bottom (not at the top, as that would mess up stderr line numbers)
4. Rename the tests to make their purpose clearer

Inspired by the methodology that `@Kivooeo` was using.

r? `@jieyouxu`
pthariensflame pushed a commit that referenced this pull request Mar 28, 2026
…rochenkov

Avoid prematurely choosing a glob import

Fixes rust-lang#153842

Use the following without introducing trait to explain:
```rust
mod a {
    pub use crate::x::y as x; // single import #1
}

mod b {
    pub mod x {
        pub mod y {}
    }
}

use a::x; // single import #2
use b::*; // glob import #3

fn main() {}
```

In current implementation, when `#1` is first resolved, `crate::x` is temporarily taken from glob import `#3` as `crate::b::x`. This happens because `single_import_can_define_name` will see that `#2` cannot define `x` (because it depends on `#1` and `#1` is ignored) and then return `false`. Later, during finalization, `crate::x` in `#1` resolves through single import `#2` instead, which no longer matches the initially cached module `crate::b::x` and triggers the ICE.

I think the resolver should keep this unresolved because `#2` may still define `x` to avoid prematurely choosing a glob import.

r? petrochenkov
pthariensflame pushed a commit that referenced this pull request Sep 8, 2026
…ods, r=petrochenkov

delegation: supporting inherent impls

This PR adds support for delegation to inherent impl functions on the delegation side.

Support for inherent impls in delegation consists of two problems: we need to resolve inherent function through `ProbeContext` routine and then we need to generate delegation function knowing the `DefId` of the signature function. The first problem is a fundamental problem given current compiler architecture, and it is not solved in this PR. To imitate working resolution for tests we adopt simple resolution by name only in inherent impls (not trait impls, which would work if we implement fair resolution through `ProbeContext`). A `resolve_type_relative_delegations` query was created which tries to resolve unresolved delegations after resolve stage. In future, when we will be able to fairly resolve delegations through `ProbeContext` contents of this query can be changed and all other logic implemented in this pull request will work.

## Free to inherent impl

Unlike free to trait delegation where we generated explicit `Self` param, here we just use default parameter.

```rust
struct X<'a, T, const B: bool>(...);
impl<'a, T, const B: bool> X<'a, T, B> {
  fn foo<'b, U, const X: usize>(&self) { ... }
}

reuse X::<'static, (), false>::foo as foo1;
reuse X::<'static, (), false,>::foo::<'static, (), 123> as foo3;

//Desugaring:
#[attr = Inline(Hint)]
fn foo1<'b, U, const X: _>(self: _) -> _ where
    'b:'b { X<'static, (), false>::foo::<'b, U, X>(self) }

#[attr = Inline(Hint)]
fn foo3(self: _) -> _ { X<'static, (), false>::foo::<'static, (), 123>(self) }
```

## Trait to inherent impl

In trait to inherent impl delegation we replace the type of self parameter from impl's type to `Self` generic param (if the signature function is a method).

```rust
trait Trait {
    reuse X::<'static, (), false>::foo as foo1;
    reuse X::<'static, (), false,>::foo::<'static, (), true> as foo3;
}

// Desugaring:
trait Trait {
    #[attr = Inline(Hint)]
    fn foo1<'b, U, const X: _>(self: _) -> _ where
        'b:'b { X<'static, (), false>::foo::<'b, U, X>(self) }

    #[attr = Inline(Hint)]
    fn foo3(self: _)
        -> _ { X<'static, (), false>::foo::<'static, (), 123>(self) }
}
```

Note that we didn't specified target expression, so we would get errors like:
```rust
error[E0308]: mismatched types
  --> $DIR/xd.rs:10:14
   |
LL | trait Trait {
   | ----------- found this type parameter
LL |     reuse X::foo;
   |              ^^^
   |              |
   |              expected `&X<'_, T, B>`, found `&Self`
   |              arguments to this function are incorrect
   |
   = note: expected reference `&X<'_, T, B>`
              found reference `&Self`
```

## Trait impl to inherent impl

Here the resolution should look signature in trait as in other cases where we delegate from trait impl. We generate function whose signature matches the resolved function in trait. We propagate only child generics if they are not specified.

```rust
trait Trait {
    fn foo<A, B, C>(&self) { }
    fn foo1<T, U, V>(&self) { }
    fn foo2<'a, T, U, V>(&self) where 'a:'a { }
    fn foo3(&self) { }
}

impl Trait for X {
    reuse X::<'static, (), false>::foo as foo1;
    reuse X::<'static, (), false,>::foo::<'static, (), 123> as foo3;
}

// Desugaring:
impl Trait for X<'_> {
    #[attr = Inline(Hint)]
    fn foo1<T, U, V>(self: _)
        -> _ { X<'static, (), false>::foo::<T, U, V>(self) }

    #[attr = Inline(Hint)]
    fn foo3(self: _)
        -> _ { X<'static, (), false>::foo::<'static, (), 123>(self) }
}
```

## Inherent impl to inherent impl

In inherent impl to inherent impl delegation we replace signature self type with delegation parent self type in case of methods.
```rust
trait Trait {
    fn foo<A, B, C>(&self) { }
    fn foo1<T, U, V>(&self) { }
    fn foo2<'a, T, U, V>(&self) where 'a:'a { }
    fn foo3(&self) { }
}

struct Y;

impl Trait for Y {
    reuse X::<'static, (), false>::foo as foo1;
    reuse X::<'static, (), false,>::foo::<'static, (), 123> as foo3;
}

impl Trait for Y {
    #[attr = Inline(Hint)]
    fn foo1<T, U, V>(self: _)
        -> _ { X<'static, (), false>::foo::<T, U, V>(self) }

    #[attr = Inline(Hint)]
    fn foo3(self: _)
        -> _ { X<'static, (), false>::foo::<'static, (), 123>(self) }
}
```

We did not specify target expression so we would get errors like:
```rust
error[E0308]: mismatched types
  --> $DIR/xd.rs:12:14
   |
LL |     reuse X::foo;
   |              ^^^
   |              |
   |              expected `&X<'_, T, B>`, found `Y`
   |              arguments to this function are incorrect
   |
   = note: expected reference `&X<'_, T, B>`
                 found struct `Y`
```

## Generics

After some experiments I think that we should force user to always specify generics for parent segment of delegation to inherent impls. Consider the following example and imagine that we can use fair resolution through `ProbeContext`:

```rust
trait M1 {}
trait M2 {}

struct S1;
struct S2;

impl M1 for S1 {}
impl M2 for S2 {}

struct X<T, U>(T, U);

impl<T: M1> X<T, ()> {
    fn foo() {}
}

impl<T: M2> X<T, usize> {
    fn foo() {}
}

reuse X::foo;
```

How to resolve `X::foo`? If we generate parent generics (`fn foo<T, U>() { X::<T, U>::foo() }`) which clauses should we inherit? It is impossible to determine which function to reuse, and despite the fact that there may be some cases where it is possible, I don't think that we should write heuristics for that. So always specifying parent generics seems to be a good option. Also I think we should ban infers in parent segment too.

One implementation aspect of how we map generic args for signature and predicates inheritance, as we inherit predicates not from the ADT declaration but from the impl block we need to take generic args from this impl, not from the declaration. So indices of generic args are taken from the impl block and then they are used in mapping and future instantiation:

```rust
struct S<'a, A, const C: usize> {
    xd: &'a [A; C],
}

// index of A = 3
// index of C = 4
impl<'a, 'b, 'c, A, const C: usize> S<A, C> {
    fn foo_self<'d: 'd, 'e, T, const B: bool>(self) {}
}

trait Trait<'a, AA, BB> where Self: Sized {
    reuse S::<(), ()>::foo_self;
    // Args: [Self/#0, 'a/#1, AA/#2, BB/#3, '{region error}, 'd/#4, (), {const error}, T/#5, B/#6]
    // Mapping: {0: 0, 7: 9, 5: 5, 3: 6, 6: 8, 4: 7}, A (index 3) is mapped into index 6 (`()`), C (index 4) mapped into index 7 (const error)
}
```

## Other concerns

### Glob and list delegations

List delegations are supported, glob delegations are not supported:

```rust
struct X;

impl X {
    fn foo(&self) {}
    fn foo2(&self) {}
}

struct Y;

impl Y {
    reuse X::{foo, foo2} { X }
}

impl Y {
    reuse X::*;
    //~^ ERROR: expected trait, found struct `X`
}
```

### Self type adjustments and target expression deletion

Adjustments for receiver are applied, adjustments for other parameters whose types contain `Self` are not applied as `Self` acts as a type alias to the struct, not a generic param which will can get replaced. The deletion of target expression should work as before.

```rust
enum X {
   ...
}

impl X {
    fn static_f() {}
    fn by_value(self) {}
    fn by_ref(&self) {}
    fn by_mut_ref(&mut self) {}
}

struct Y;

impl Y {
    fn get_x(&self) -> X { X }
    reuse X::{static_f, by_value, by_ref, by_mut_ref} { self.get_x() }
}

impl Y {
    fn get_x(&self) -> X { X }

    #[attr = Inline(Hint)]
    fn static_f() -> _ { X::static_f() }

    #[attr = Inline(Hint)]
    fn by_value(self: _) -> _ { X::by_value(self.get_x()) }

    #[attr = Inline(Hint)]
    fn by_ref(self: _) -> _ { X::by_ref(self.get_x()) }

    #[attr = Inline(Hint)]
    fn by_mut_ref(self: _) -> _ { X::by_mut_ref(self.get_x()) }
}

fn main() {
    let y = Y;
    y.by_ref();
    y.by_mut_ref();
    //~^ ERROR: cannot borrow `y` as mutable, as it is not declared as mutable
    y.by_value();

    let y = &Y;
    y.by_value();
    //~^ ERROR: cannot move out of `*y` which is behind a shared reference
    y.by_ref();
    y.by_mut_ref();
    //~^ ERROR: cannot borrow `*y` as mutable, as it is behind a `&` reference

    let y = &mut Y;
    y.by_value();
    //~^ ERROR: cannot move out of `*y` which is behind a mutable reference
    y.by_ref();
    y.by_mut_ref();
}
```

### Recursive delegations

Works as before, we just check the resolution chain and we do not care whether it came from resolution at resolve stage or from resolution of type relative delegations.

r? @petrochenkov
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants