In my understanding, the gradient still flows to the encoder’s weight because we are just passing the weight (self.encoder.weight.t()), as it is to the function in F. i.e, here the link to the parameter is still intact so that automatic differentiation happens (thanks to the integration of Variable into Tensor, I guess). Instead, if you decide to pass the raw data in encoder.weight (using  self.encoder.weight.data.t()), then we are detaching the differentiation path, hence automatic differentiation will not affect encoder.weight.
Maybe, @tom, @smth, @ptrblck would be able to give more appropriate answer on technicalities of this. For now, this is my understanding. I am not sure if it is 100% correct.